들어가기 전..
하.. 이번에 동영상 썸네일 만들라고 하셔서 작업하는데.. 자꾸 canvas에 안그려져서 무척이나 당황스러웠다.아무튼 좌충우돌 해결해서 나중에 이런 작업이 또 생기면 보려고 기록차 글을 남깁니다.아직 하자가 있습니다. 비율이 깨진다는 하자요. 다음에 수정해야겠어요.
html (template)
<div>
<video
ref="videoOriginElement"
:src="setVideo"
controls
:width="canvas.width"
:height="canvas.height"
muted
hidden
/>
<canvas ref="videoThumbnailElement" :width="canvas.width" :height="canvas.height" />
</div>
javascript (vue - typescript)
// ...중략
props: {
file: {
type: Object,
required: true,
},
originFileList: {
type: Array as PropType<File[]>,
},
},
setup(props, {emit}) {
const videoOriginElement = ref<HTMLVideoElement>();
const videoThumbnailElement = ref<HTMLCanvasElement>();
const state = reactive({
canvas : {
width: 80,
height: 80,
},
canvasCtx: null as CanvasRenderingContext2D | null | undefined,
});
// video src 만들기
const setVideo = computed(() => {
// props에서 받은 file(필수!! required) 에서 url 꺼내기.
let src = props.file.url ?? props.file.URL ?? '';
// or 이 방식은 input file 에서 받을 경우
// originFileList = 저흰 multiple 이여서 파일 list 였음
if (props.state === 'form' && props.originFileList) {
let currentFile;
props.originFileList.map((object: File) => {
if (object.name === props.file.fileName) {
currentFile = object;
}
});
src = URL.createObjectURL(currentFile);
}
return src;
});
onMounted(async () => {
// fileType이 video인지 체크.
// 저흰 video 말고도 이미지 등등 여러 포맷들을 다 받는데 동영상 일 경우 썸네일을 만드는거라 이럼;
if (isVideo(props.file.url ?? props.file.FileName)) {
await nextTick();
// 이게 중요함 alpha option 없으니까 안만들어져서 대환장 파티였음. ㅂㄷ 이거땜에 하루 헤딩함 왜 안되나하고
state.canvasCtx = videoThumbnailElement.value?.getContext('2d', {
alpha: false,
});
setVideoImage();
}
});
// 동영상 로드 되면 이래저래 만져주는 공간
// 사실 template video tag에 @loadedmetadata="함수"해서 작업했어도 될 것 같음
function setVideoImage() {
const video = videoOriginElement.value;
const canvas = videoThumbnailElement.value;
if (video && canvas) {
video.addEventListener('loadedmetadata', async function () {
//비디오의 영상길이 중 랜덤 타임을 뽑음
// video.currentTime = Math.random() * video.duration; //해당 시간으로 이동
video.currentTime = 1; //해당 시간으로 이동
await video?.play();
drawVideoThumbnail();
requestAnimationFrame(drawVideoThumbnail);
await video?.pause();
});
}
}
// canvas 에 그리는 것
async function drawVideoThumbnail() {
const video = videoOriginElement.value;
const canvas = videoThumbnailElement.value;
if (canvas && state.canvasCtx && video) {
state.canvasCtx.drawImage(video, 0, 0, video.width, video.height);
}
}
function isVideo(fileUrl) {
const fileName = getExtension(fileUrl);
switch (fileName.toLowerCase()) {
case 'mp4':
case 'mov':
return true;
}
return false;
}
return {
...toRefs(state),
videoOriginElement,
videoThumbnailElement,
}
}
예예.. 이리 해결은 했습니다.
다들 먼 유투브에서 따오거나 그래서..
저도 한 번 적어봤습니다
프론트 개발자 여러분 화이팅~!
다음에는 사용방법에 대하여 작성하겠습니다.
참고
https://stackoverflow.com/questions/40143958/javascript-generate-video-thumbnail-from-video-url
...등등
'FRONT > Vue.js' 카테고리의 다른 글
Vuex : Vue.js 상태관리 패턴 라이브러리 이해하기 (0) | 2020.05.26 |
---|