티스토리 뷰
저번 시간에 ffmpeg 라이브러리 설치하기 전에 윈도는 설정해야 할 것이 있었다.
이제 본격적으로 코드 스터디를 진행해보겠다.
1. 라이브러리 설치
yarn add fluent-ffmpeg
npm i fluent-ffmpeg
먼저 ffmpeg 라이브러리를 설치한다.
2. 서버에 저장된 섬네일을 생성
다음은 서버에 저장된 영상을 이용하여 썸네일을 생성하는 코드를 제작해보려고 한다.
// client > src > components > views > VideoUploadPage > VideoUploadPage.js
// 중략
axios.post('/api/video/uploadfiles', formData, config)
.then(response => {
if(response.data.success) {
axios.post('/api/video/thumbnail', variable).then(response => {
if(response.data.success) {
console.log(response.data);
} else {
alert('썸네일 생성에 실패하였습니다.')
}
})
} else {
alert('비디오 업로드를 실패했습니다.');
}
})
// 중략
uploadfiles에 성공적으로 영상이 올랐다면 variable에는 url, fileName의 데이터를 가져온다. 아래 서버에서 thumbnail에 대한 데이터 값이 성공적일 때, 데이터 값을 가져온다.
3. 생성된 썸네일을 서버에 저장
여기에서는 위에서 만든 api/video/thumbnail의 라우터를 만들어준다.
// server > routes > video.js
//중략
var ffmpeg = require('fluent-ffmpeg');
// 중략
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) // uploads 저장경로를 가져온다.
.on('filenames', function (filenames) { // 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' // thumbnail-파일원래이름(확장자를 제거한)상태로 저장이 된다.
})
})
// 중략
여기에서는 비디오의 정보를 가져오는 ffprobe를 사용하고, 썸네일 생성을 진행한다. 성공 시 2번의 response.data.success로 가게 된다.
4. 화면에 보여주기
// client > src > components > views > VideoUploadPage > VideoUploadPage.js
// 중략
const [FilePath, setFilePath] = useState("");
const [Duration, setDuration] = useState("");
const [ThumbnailPath, setThumbnailPath] = useState("");
// 중략
axios.post('/api/video/uploadfiles', formData, config)
.then(response => {
if(response.data.success) {
let variable = {
url: response.data.url,
fileName: response.data.fileName
};
setFilePath(response.data.url);
axios.post('/api/video/thumbnail', variable).then(response => {
// 서버에서 썸네일 생성 성공시 url: filePath, fileDuration: fileDuration 데이터가 넘어온다.
if(response.data.success) {
setDuration(response.data.fileDuration);
setThumbnailPath(response.data.url);
console.log(response.data);
} else {
alert('썸네일 생성에 실패하였습니다.')
}
})
} else {
alert('비디오 업로드를 실패했습니다.');
}
})
return (
...
{ThumbnailPath &&
<div>
<img src={`http://localhost:5000/${ThumbnailPath}`} alt="thumbnail" />
</div>
}
...
)
}
export default VideoUploadPage;
FilePath, Duration, ThumbnailPath를 useState로 관리해준다. 썸네일 성공시 setState에 저장들을 해준다. 단, 화면에 썸네일이 안 올라갔을 때 문제가 생기지 않도록 썸네일이 들어갔을 때만 이미지가 성공적으로 보여주는 것을 확인할 수 있다.
다음과 같이 영상을 올리면 썸네일을 저장하고 저장된 썸네일을 화면과 같이 보여준다.
이번엔 클라이언트와 서버를 왔다 갔다 하느라 이해하는데 생각보다 시간이 걸렸다.
최대한 설명해주시는 내용을 토대로 머릿속에 알고리즘 같은 그림을 그리려고 노력하였다.
그리고 최대한 그 언어에 대한 이해를 높이려고 노력을 해보았다.
흠 노력도 좋지만 빨리 실무로 많은 난관을 부딪혀보고 싶다.
'Front-End > React' 카테고리의 다른 글
React-Youtube : 디테일 비디오 페이지에서 우측 비디오 리스트 생성 (0) | 2021.04.16 |
---|---|
리액트 라우터에 대하여 (0) | 2021.04.11 |
React-Youtube : 비디오를 저장하는 함수 만들기 (0) | 2021.04.07 |
boiler-plate : 회원가입 페이지 만들기 (0) | 2021.04.04 |
boiler-plate : redux로 로그인 화면 구현하기 (0) | 2021.04.03 |
- Total
- Today
- Yesterday
- programmers
- mongodb
- Git
- 리액트
- 자바스크립트
- 재공부
- 노드
- 함수
- 파이썬
- 코딩테스트
- Switch
- Coding Test
- react
- node
- 리액트 유튜브
- 배열
- redux
- 프로그래머스
- node-sass
- 자바
- github
- Visual Studio Code
- array
- 리덕스
- javascript
- 리액트 썸네일
- 뷰
- CSS
- java
- node.js
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |