
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<img v-if="thumbnailUrl" :src="thumbnailUrl" alt="비디오 썸네일">
<div v-else-if="error" class="error">썸네일 생성 실패</div>
<div v-else class="loading">로딩 중...</div>
</template>
<script>
export default {
data() {
return {
thumbnailUrl: null,
error: false
}
},
props: {
filePath: String
},
methods: {
createThumbnail(videoBlob) {
return new Promise((resolve, reject) => {
// 동영상 요소 생성
const video = document.createElement('video');
video.style.display = 'none';
document.body.appendChild(video);
// 캔버스 요소 생성
const canvas = document.createElement('canvas');
canvas.width = 320;
canvas.height = 180;
// 동영상 파일로부터 URL 생성
const videoUrl = URL.createObjectURL(videoBlob);
video.src = videoUrl;
// 로드 시간 제한 설정 (10초)
const timeout = setTimeout(() => {
URL.revokeObjectURL(videoUrl);
document.body.removeChild(video);
reject(new Error('비디오 로드 시간 초과'));
}, 10000);
// 오류 처리
video.onerror = (e) => {
clearTimeout(timeout);
URL.revokeObjectURL(videoUrl);
document.body.removeChild(video);
reject(new Error('비디오 로드 실패: ' + e.message));
};
// 메타데이터 로드 후 처리
video.onloadedmetadata = () => {
// 첫 프레임이나 특정 시점으로 이동
video.currentTime = 0.5;
};
// 특정 시간으로 이동 완료 후 썸네일 생성
video.onseeked = () => {
try {
clearTimeout(timeout);
const ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
// 썸네일 URL 생성
const thumbnailUrl = canvas.toDataURL('image/jpeg', 0.7);
// 리소스 정리
URL.revokeObjectURL(videoUrl);
document.body.removeChild(video);
resolve(thumbnailUrl);
} catch (error) {
URL.revokeObjectURL(videoUrl);
document.body.removeChild(video);
reject(error);
}
};
});
}
},
async mounted() {
try {
console.log('비디오 파일 경로:', this.filePath);
// 백엔드에서 파일 가져오기
const response = await fetch(this.filePath, {
// credentials: 'include', // 필요한 경우 쿠키 포함
// mode: 'cors', // CORS 모드 설정
});
if (!response.ok) {
throw new Error(`HTTP 오류! 상태: ${response.status}`);
}
const blob = await response.blob();
console.log('비디오 Blob 크기:', blob.size);
// 썸네일 생성
this.thumbnailUrl = await this.createThumbnail(blob);
} catch (error) {
console.error('썸네일 생성 실패:', error);
this.error = true;
}
}
}
</script>
<style scoped>
.loading,
.error {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
min-height: 180px;
background-color: #f0f0f0;
border-radius: 30px;
}
.loading {
color: #666;
}
.error {
color: #e53935;
}
</style>