NODE.JS
Youtube 만들기 - 4) 비디오 업로드 Form 만들기 3(썸네일 만들기)
dodop
2021. 5. 14. 10:10
파일을 업로드 하면 옆에 썸네일이 생성되도록 지정할 것이다.
썸네일을 생성하기 위해서는 ffmpeg를 사용한다.
brew install ffmpeg를 해주고,
그 후 npm install fluent-ffmpeg --save를 해준다.
썸네일 생성을 위해 저번시간에 생성한 onDrop함수에 다음과 같은 axios구문을 추가해준다.
const onDrop = (files) =>{
//axios를 통해서 데이터 보낼때 파일이 오류생기지 않도록 전환하는 head 사용한다.
let formData = new FormData;
const config = {
header: {'content-type': 'multipart/form-data'}
}
formData.append("file", files[0])//첫번째 파일을 가져오기 위해서 배열을 사용한다.
//서버에 보낸다.
Axios.post('/api/video/uploadfiles', formData, config)
.then(response=>{
if(response.data.success){
console.log(response.data)
let variable = {
url:response.data.url,
fileName : response.data.fileName
}
setFilePath(response.data.url)
Axios.post('/api/video/thumbnail', variable)
.then(response =>{
if (response.data.success){
}else{
alert('썸네일 실행에 실패했습니다. ')
}
})
}else{
alert('비디오 업로드를 실패했습니다.')
}
})
}
axios를 작성했으니 다시 video.js 파일로 가서 라우트를 작성해주자.
const ffmpeg = require("fluent-ffmpeg");//썸네일 가져오기 위해서 ffmpeg사용한다
//thumbnail 만들기
router.post('/thumbnail', (req, res)=>{
let filePath = ""
let fileDuration = ""
//비디오 러닝타임 가져오기(비디오정보)
ffmpeg.ffprobe(req.body.url, function(err, metadata){
console.dir(metadata);
console.log(metadata.format.duration)
fileDuration = metadata.format.duration
});
//썸네일 생성(비디오 저장경로를 넣으면 이 파일의 파일이름을 생성하고 그 다음에 무엇을 할 지 설정해준다.)
ffmpeg(req.body.url)//클라이언트 한테서 온 비디오 url
.on('filenames', function(filenames){//썸네일 파일 이름 생성
console.log('Will generate ' + filenames.join(', '))
console.log(filenames)
filePath = "uploads/thumbnails/"+ filenames[0]
})
.on('end',function(){
console.log('Screenshots taken');//썸네일 생성되면 뭐 할건지
return res.json({success: true, url:filePath, fileDuration:fileDuration});//러닝타임도 준다.
})
.on('error', function (err) {
console.error(err);
return res.json({success:false, err});
})
.screenshots({
count:3,//3개의 샷 찍기 가능
folder: 'uploads/thumbnails',//업로드 폴더안에 썸네일 저장될 것이다.
size: '320x240',//썸네일 사이즈
filename:'thumbnail-%b.png'
})
})
module.exports = router;
업로드 폴더안의 썸네일이라는 폴더에 스크린샷이 생성되므로 폴더를 생성해준다.
다시 client로 돌아와서 다음 부분을 작성해준다.
우리는 5000번 포트를 가지고 있기 때문에 다음과 같이 포트를 추가해준다.
const [FilePath, setFilePath] = useState("")
const [Duration, setDuration] = useState("")
const [ThumbnailePath, setThumbnailePath] = useState("")
const onDrop = (files) =>{
//axios를 통해서 데이터 보낼때 파일이 오류생기지 않도록 전환하는 head 사용한다.
let formData = new FormData;
const config = {
header: {'content-type': 'multipart/form-data'}
}
formData.append("file", files[0])//첫번째 파일을 가져오기 위해서 배열을 사용한다.
//서버에 보낸다.
Axios.post('/api/video/uploadfiles', formData, config)
.then(response=>{
if(response.data.success){
console.log(response.data)
let variable = {
url:response.data.url,
fileName : response.data.fileName
}
setFilePath(response.data.url)
Axios.post('/api/video/thumbnail', variable)
.then(response =>{
if (response.data.success){
setDuration(response.data.fileduration)
setThumbnailePath(response.data.url)
}else{
alert('썸네일 실행에 실패했습니다. ')
}
})
}else{
alert('비디오 업로드를 실패했습니다.')
}
})
}
{/* Thumbnail (thumbnailPath가 있을 때에만 작동 */}
{ThumbnailePath &&
<div>
<img src={`http://localhost:5000/${ThumbnailePath}`} alt="thumbnail"/>
</div>
}