오픈 소스 썸네일 라이브러리인 ReactJS에서 비디오 썸네일을 생성합니다.
31003 단어 tutorialjavascriptproductivityreact
최근에 저는 사용자가 비디오를 업로드하고 해당 비디오의 썸네일을 선택할 수 있는 내 프로젝트 중 하나에서 서비스를 생성해야 했으며 비디오의 다양한 시간대에서 여러 썸네일을 생성해야 했습니다. 따라서 사용자는 주어진 썸네일 중 하나를 선택할 수 있습니다.
이런 식으로 [원본 화면을 업로드할 수 없습니다]
나는 나를 위해 이것을 할 수 있지만 결국 내 자신의
NPM
패키지를 만드는 JS 라이브러리를 검색합니다.video-thumbnails-generator
기여를 환영합니다. 저는 이미
Readme.md
에 로드맵을 추가했습니다.그러나 먼저 장면 뒤에서 어떻게 작동하는지 살펴보겠습니다.
🔵
Index.js
드라이버// convert image to object part instead of base64 for better performance
// https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
export const importFileandPreview = (file, revoke) => {
return new Promise((resolve, reject) => {
window.URL = window.URL || window.webkitURL;
let preview = window.URL.createObjectURL(file);
// remove reference
if (revoke) {
window.URL.revokeObjectURL(preview);
}
setTimeout(() => {
resolve(preview);
}, 100);
});
}
/**
*
* @param videoFile {FIle} // the video file
* @param numberOfThumbnails {number} //number of thumbnails you want to generate
* @returns {string[]} // an array of base64 thumbnails images
*
* @abstract
* Idea taken from - https://codepen.io/aertmann/pen/mrVaPx
* The original functionality of getVideoThumbnail() function is customized as per working code
* If it didn't work in future then replace it with about links working example
*/
export const generateVideoThumbnails = async (videoFile, numberOfThumbnails) => {
let thumbnail = [];
let fractions = [];
return new Promise(async (resolve, reject) => {
if (!videoFile.type?.includes("video")) reject("not a valid video file");
await getVideoDuration(videoFile).then(async (duration) => {
// divide the video timing into particular timestamps in respective to number of thumbnails
// ex if time is 10 and numOfthumbnails is 4 then result will be -> 0, 2.5, 5, 7.5 ,10
// we will use this timestamp to take snapshots
for (let i = 0; i <= duration; i += duration / numberOfThumbnails) {
fractions.push(Math.floor(i));
}
// the array of promises
let promiseArray = fractions.map((time) => {
return getVideoThumbnail(videoFile, time)
})
// console.log('promiseArray', promiseArray)
// console.log('duration', duration)
// console.log('fractions', fractions)
await Promise.all(promiseArray).then((res) => {
res.forEach((res) => {
// console.log('res', res.slice(0,8))
thumbnail.push(res);
});
// console.log('thumbnail', thumbnail)
resolve(thumbnail);
}).catch((err) => {
console.error(err)
}).finally((res) => {
console.log(res);
resolve(thumbnail);
})
});
reject("something went wront");
});
};
const getVideoThumbnail = (file, videoTimeInSeconds) => {
return new Promise((resolve, reject) => {
if (file.type.match("video")) {
importFileandPreview(file).then((urlOfFIle) => {
var video = document.createElement("video");
var timeupdate = function () {
if (snapImage()) {
video.removeEventListener("timeupdate", timeupdate);
video.pause();
}
};
video.addEventListener("loadeddata", function () {
if (snapImage()) {
video.removeEventListener("timeupdate", timeupdate);
}
});
var snapImage = function () {
var canvas = document.createElement("canvas");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext("2d").drawImage(video, 0, 0, canvas.width, canvas.height);
var image = canvas.toDataURL();
var success = image.length > 100000;
if (success) {
URL.revokeObjectURL(urlOfFIle);
resolve(image);
}
return success;
};
video.addEventListener("timeupdate", timeupdate);
video.preload = "metadata";
video.src = urlOfFIle;
// Load video in Safari / IE11
video.muted = true;
video.playsInline = true;
video.currentTime = videoTimeInSeconds;
video.play();
});
} else {
reject("file not valid");
}
});
};
/**
*
* @param videoFile {File}
* @returns {number} the duration of video in seconds
*/
export const getVideoDuration = (videoFile)=> {
return new Promise((resolve, reject) => {
if (videoFile) {
if (videoFile.type.match("video")) {
importFileandPreview(videoFile).then((url) => {
let video = document.createElement("video");
video.addEventListener("loadeddata", function () {
resolve(video.duration);
});
video.preload = "metadata";
video.src = url;
// Load video in Safari / IE11
video.muted = true;
video.playsInline = true;
video.play();
// window.URL.revokeObjectURL(url);
});
}
} else {
reject(0);
}
});
};
🔵 설명
importFileandPreview()
/**
* This function will take an File object and will convert it
* into windowObjectURI which look something like this -
* blob:http://localhost/2d7b2c97-02f3-4e7d-a6c1-d04746c27730
*/
export const importFileandPreview = (file, revoke) => {
return new Promise((resolve, reject) => {
//@todo - your logic here
});
}
getVideoDuration()
/**
* @abbrivation This function takes a video File object as an
* input and returns the duration of that video.
*
* @param videoFile {File}
* @returns {number} the duration of video in seconds
*/
export const getVideoDuration = (videoFile)=> {
return new Promise((resolve, reject) => {
if (videoFile) {
resolve(duration);
} else {
reject(0);
}
});
};
getVideoThumbnail()
/**
* @abbrivation
* This function takes a video File Object and the time where we
* need a snapshot of video screen.
* It will return a snapshot of the video at the given time
* in `base64` format.
*
* @param {File} file
* @param {number} videoTimeInSeconds
* @returns string // base64Image
*/
const getVideoThumbnail = (file, videoTimeInSeconds) => {
return new Promise((resolve, reject) => {
if (file.type.match("video")) {
resolve(thumbnail); //base64 image
} else {
reject("file not valid");
}
});
};
generateVideoThumbnails()
/**
* This functin will take two input video File and Number
* And It will generate that many thumbnails.
*
* @param videoFile {FIle} // the video file
* @param numberOfThumbnails {number} //number of thumbnails you want to generate
* @returns {string[]} // an array of base64 thumbnails images
*
* @abstract
* Idea taken from - https://codepen.io/aertmann/pen/mrVaPx
* The original functionality of getVideoThumbnail() function is customized as per working code
* If it didn't work in future then replace it with about links working example
*/
export const generateVideoThumbnails = async (videoFile, numberOfThumbnails) => {
let thumbnail = [];
let fractions = [];
return new Promise(async (resolve, reject) => {
if (!videoFile.type?.includes("video")) reject("not a valid video file");
// first we get video duration
// then we calculate how many thumbnails to generate
// we cann generateThumbnail() function that many times
// then we resolve all those promises and return result.
await Promise.all(promiseArray).then((res) => {
res.forEach((res) => {
thumbnail.push(res);
});
resolve(thumbnail);
}).catch((err) => {
console.error(err)
}).finally((res) => {
resolve(thumbnail);
})
});
reject("something went wrong");
});
};
실제 작동 확인 - Live Demo .
즐겁게 읽으셨기를 바랍니다. 히트 댓 하트 아이콘 잊지마세요😀 새로운 소재👋로 곧 만나요.
Reference
이 문제에 관하여(오픈 소스 썸네일 라이브러리인 ReactJS에서 비디오 썸네일을 생성합니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rajeshroyal/video-thumbnails-generate-with-vanilla-js-reactjs-like-youtube-3ok8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)