WishMeLz

生活其实很有趣

获取视频某一秒的截图

        
        const handleGetVideoThumb = async function (url, options = {}) {
            if (typeof url !== "string") {
                console.error("URL must be a string");
                return;
            }

            // 默认参数
            const defaults = {
                seekTime: 1,
                onLoading: () => {},
                onLoaded: () => {},
                onFinish: (thumbData) => {},
                onError: (error) => console.error(error),
            };
            const params = { ...defaults, ...options };

            // 基于视频元素绘制缩略图,而非解码视频
            const video = document.createElement("video");
            // 静音
            video.muted = true;

            // 绘制缩略图的 canvas 画布元素
            const canvas = document.createElement("canvas");
            const context = canvas.getContext("2d", {
                willReadFrequently: true,
            });

            // 绘制缩略图的标志量
            let isTimeUpdated = false;

            // 设置视频源并返回 blob URL
            const setVideoSource = async (url) => {
                if (/^blob:|base64,/i.test(url)) {
                    return url;
                } else {
                    try {
                        const response = await fetch(url);
                        const blob = await response.blob();
                        params.onLoaded();
                        return URL.createObjectURL(blob);
                    } catch (error) {
                        params.onError(error);
                    }
                }
            };

            // 获取视频尺寸并开始绘制
            const onLoadedMetadata = () => {
                canvas.width = video.videoWidth;
                canvas.height = video.videoHeight;
                draw();
            };

            // 触发绘制监控
            const onTimeUpdate = () => {
                isTimeUpdated = true;
            };

            // 绘制方法
            const draw = () => {
                const thumbData = [];
                video.currentTime = params.seekTime;

                const onSeeked = () => {
                    if (isTimeUpdated) {
                        context.clearRect(0, 0, canvas.width, canvas.height);
                        context.drawImage(video, 0, 0, canvas.width, canvas.height);
                        canvas.toBlob((blob) => {
                            thumbData.push(URL.createObjectURL(blob));
                            params.onFinish(thumbData);
                        }, "image/jpeg");
                        video.removeEventListener("seeked", onSeeked);
                    }
                };

                video.addEventListener("seeked", onSeeked);
            };

            // 设置事件监听
            video.addEventListener("loadedmetadata", onLoadedMetadata);
            video.addEventListener("timeupdate", onTimeUpdate);

            // 获取视频数据
            params.onLoading();
            video.src = await setVideoSource(url);
        };

        // 示例调用
        handleGetVideoThumb(
            "https://xxxxx.mp4",
            {
                seekTime: 7, // 截取第7s视频
                onFinish: (data) => {
                    console.log(data); // 图片数据
                },
                onError: (error) => {
                    console.error("Error occurred:", error);
                },
            }
        );