관리 메뉴

웹개발자의 기지개

[PHP,Javascript] 동영상 미리보기, 동영상 업로드시 자동 썸네일 이미지생성하기 본문

PHP

[PHP,Javascript] 동영상 미리보기, 동영상 업로드시 자동 썸네일 이미지생성하기

http://portfolio.wonpaper.net 2024. 12. 1. 01:48

 

 

구현해야하는 사항은 다음 2가지이다.

 

(1) 동영상파일 선택시 자동 미리보기 이미지가 바로 생성되어 화면에 나타날것 (Javascript 로 구현)

(2) 해당 동영상 파일 업로드시 영상 업로드 됨과 동시에 자동으로 jpg 썸네일 이미지 생성시키기 (PHP 백엔드로 구현)

 

* jquery 라이브러리는 당연히 상단부에 미리 배치시킨다.

 

[test.php]

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
 
[test.php]
 
<form id="f1" name="f1" method="post" enctype="multipart/form-data">
 
    <div class="audi_filed_tit01">Required Fields</div>
    <ul class="audi_form">
        <li>
            <div class="audi_form_tit01">Introduction *</div>
            <div class="audi_form_con01">
                <textarea name="intro" class="form_st01" style="height:200px;"></textarea>
            </div>
        </li>
        <li>
            <div class="audi_form_tit01">Movie File *</div>
            <div class="audi_form_con01">
                <div class="filebox">
                    <input class="upload-name1" value="Choose file" placeholder="Choose file">
                    <label for="file1">Choose file</label> 
 
                    <input type="file" id="file1" name="userfile1" accept="video/*">
 
                    <div style="margin-top:10px;"><canvas id='videoThumbnail' style="width: 320px; height: 180px;border:solid 1px #dddddd;background:no-repeat center center / 30%;background-image:url('../img/add-round-gray.svg');"></canvas></div>
 
                    <input type="hidden" id="imageData" name="imageData" value="">
 
                    <p style="color:#ff6600;">* Please upload video files under 100 MBytes. (mp4)</p>
                </div>
            </div>
        </li>
    </ul>
    <div class="btn_box">
        <input value="submit" type="button" onClick="uploadChk()">
        <input value="cancel" type="button" onClick="location.href='/'">
    </div>
 
    <div id="uploading_txt_message" style="color:#ff6633;text-align:center;margin:14px;display:none;">
    * It may take some time as we upload video files. 
    <br>* When you click the submit button, please wait a moment until the video file upload is complete.
    </div>
 
    <div id="write_waiting" style="display: none;" >
        <div style="padding:10px"><img src="/img/loading_img.gif" border=0></div>
    </div>
</form>
 
 
<script>
$('#file1').on('change'function(event) {
    var fileName11 = $("#file1").val();
    $(".upload-name1").val(fileName11);
 
    var file = event.target.files[0];
    const cover = getVideoCover(file, seekTo = 1.5);
});
 
function getVideoCover(file, seekTo = 0.0) {
 
    return new Promise((resolve, reject) => {
        const videoPlayer = document.createElement('video');
        videoPlayer.setAttribute('src', URL.createObjectURL(file));
        videoPlayer.load();
        videoPlayer.addEventListener('error', (ex) => {
            reject("error when loading video file", ex);
        });
        videoPlayer.addEventListener('loadedmetadata', () => {
            //alert(videoPlayer.duration);
 
            if (videoPlayer.duration < seekTo) {
                reject("video is too short.");
                return;
            }
            setTimeout(() => {
                videoPlayer.currentTime = seekTo;
            }, 200);
            videoPlayer.addEventListener('seeked', () => {
 
                const canvas = document.createElement("canvas");
//                canvas.width = videoPlayer.videoWidth;
//                canvas.height = videoPlayer.videoHeight;
                canvas.width = 320;
                canvas.height = 180;
 
                const ctx = canvas.getContext("2d");
                ctx.drawImage(videoPlayer, 00, canvas.width, canvas.height);
                ctx.canvas.toBlob(function(blob){
                    var url = URL.createObjectURL(blob);
                    $('#videoThumbnail').css({"background-image":"url("+url+")"});
                    $('#videoThumbnail').css({"background-size":"100%"});
                    $('#imageData').val(ctx.canvas.toDataURL('image/jpeg'0.5));
 
//                    const formData = new FormData(document.getElementById('f1'));
//                    formData.append('thumbnail', blob, 'thumbnail.png'); // 썸네일 이미지 추가
                });
            });
        });
    });
}
 
 
// $('#file1')[0].files[0]
// $('#videoThumbnail')[0].files[0]
 
function uploadChk() {
 
    var form = document.f1;
    if (form.intro.value=="")
    {
        alert("Please enter a brief description of the video in the introduction field.");
        form.intro.focus();
        return;
    }
 
    if ($('#file1').val() == "")
    {
        alert("Please select the video file correctly.");
        $('#file1').focus();
        return;
    }
 
    if (confirm("Would you like to upload related video files along with the items you entered?"))
    {
        show_waiting();
 
        form.action = "test_ok.php";
        form.submit();
    }
}
 
function show_waiting() {
//  var _x = document.body.clientWidth/2 + document.body.scrollLeft - 145;
//  var _y = document.body.clientHeight/2 + document.body.scrollTop - 44;
  var _x = document.body.clientWidth/2;
  var _y = document.body.clientHeight/2;
  document.getElementById("write_waiting").style.posLeft=_x;
  document.getElementById("write_waiting").style.posTop=_y;
  document.getElementById("write_waiting").style.visibility='visible';
}
 
</script>
cs

 

canvas 에 동영상의 미리보기 이미지를 그리는 소스이다.

$('#imageData').val(ctx.canvas.toDataURL('image/jpeg', 0.5)); 는 jpg파일

$('#imageData').val(ctx.canvas.toDataURL('image/png', 0.5)); 는 png파일

 

canvas 의 이미지 코드를 imageData hidden 태그로 폼값으로 넘겨서 백엔드 처리할때, 이미지로 업로드 시키는 방식이다.

 

[test_ok.php]

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?
session_start();
include "../inc/config.php"
 
    $intro            = trim($_POST['intro']);
 
    $intro      = addslashes($intro);
 
    $filesize1 = $_FILES['userfile1']['size'];
    if (!$filesize1$filesize1 = 0;
    if ($filesize1 > (1024 * 1024 * 100)) {    // 1024 * 1024 * 10
?>
    <script>
    alert("Video upload files can only be 100 MB or less.\nReturns to the previous page.");
    location.href="test.php";
    </script>
<?
    }
 
    $save_dir = '../pds/uploads';
 
    $thumbnail = "";
    if (isset($_POST['imageData'])) {
        // Extract base64 image data
        $imageData = $_POST['imageData'];
 
        // Remove the "data:image/png;base64," prefix
//        $imageData = preg_replace('/^data:image\/png;base64,/', '', $imageData);
//        $imageData = preg_replace('/\s+/', '+', $imageData);
        $imageData = str_replace('data:image/jpeg;base64,'''$imageData);
        $imageData = str_replace(' ''+'$imageData);
 
 
        // Decode the base64 data
        $decodedImage = base64_decode($imageData);
 
 
        // 썸네일이미지파일(jpg)
        $thumbnail = 'thumb_' . uniqid() . '.jpg';
 
        if (file_put_contents($save_dir."/".$thumbnail$decodedImage)) {
            //echo "Image successfully saved as: $filename";
        } 
 
 
    // 업로드된 영상파일
    $filename1 = uploadFile_each2($save_dir,$_FILES['userfile1']);
 
 
?>
cs

 

 

넘어온 imageData 의 코드화된 이미지소스를 Decoding 하여 해당 원하는 폴더와 이미지 파일명으로 바꾸어 이미지 파일을 만든다. (썸네일이미지) 

 

 

Comments