Greasy Fork

HTML5视频截图保存工具

Shift+D保存HTML5视频截图,并生成带时间戳和文件名的图片+并复制到剪切板(可用于所有视频网站,百度网盘和哔哩哔哩亲测可用)

目前为 2023-10-03 提交的版本。查看 最新版本

// ==UserScript==
// @name         HTML5视频截图保存工具
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Shift+D保存HTML5视频截图,并生成带时间戳和文件名的图片+并复制到剪切板(可用于所有视频网站,百度网盘和哔哩哔哩亲测可用)
// @license      Yolanda Morgan
// @author       Yolanda Morgan
// @match        http://*/*
// @match        https://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 监听键盘按键事件
    document.addEventListener('keydown', function(e) {
        // 判断是否按下了Shift和S键
        if (e.shiftKey && e.key === 'D') {
            // 获取页面的video元素
            var v = document.querySelector('video');
            if (v) {
                // 获取当前时间作为文件名的一部分
                var currenttime = getCurrentTime();

                // 创建canvas元素并绘制video元素内容
                var c = document.createElement('canvas');
                c.width = v.videoWidth;
                c.height = v.videoHeight;
                c.getContext('2d').drawImage(v, 0, 0, c.width, c.height);

                // 绘制后,获取图片数据并下载
                c.toBlob(function(b) {
                    var u = URL.createObjectURL(b);
                    var filename = getFilename(currenttime, v);
                    download(u, filename);
                    URL.revokeObjectURL(u);
                });
            }
        }
    });

    // 获取视频文件名
    function getFilename(currenttime, videoElement) {
        var videoNameElement = document.querySelector('div.vp-video-page-card span.is-playing.vp-video-page-card__video-name');
        var originalFilename = videoNameElement ? videoNameElement.innerText.trim() : '';
        if (!originalFilename) {
            var titleElement = document.querySelector('head > title');
            originalFilename = titleElement ? titleElement.innerText.trim() : '';
        }
        if (videoNameElement || titleElement) {
            originalFilename = originalFilename.replace(/\.[^.]+$/, ""); // 去掉原始文件名的后缀
        }
        var currentTimeStr = formatTime(currenttime);
        var newFilename = "BR截图_" + getCurrentDate() + "_帧_" + currentTimeStr + "_" + originalFilename + ".png"; // 根据需求拼接文件名,帧就是时间戳,BR表示browser
        return newFilename || 'screenshot';
    }

    // 获取当前完整日期时间,格式为yyyyMMddHHmmss
    function getCurrentDate() {
        var date = new Date();
        var year = date.getFullYear();
        var month = ('0' + (date.getMonth() + 1)).slice(-2);
        var day = ('0' + date.getDate()).slice(-2);
        var hours = ('0' + date.getHours()).slice(-2);
        var minutes = ('0' + date.getMinutes()).slice(-2);
        var seconds = ('0' + date.getSeconds()).slice(-2);
        return year + month + day + hours + minutes + seconds;
    }

    // 格式化时间为hh:mm:ss的格式
    function formatTime(time) {
        var hours = Math.floor(time / 3600);
        var minutes = Math.floor((time % 3600) / 60);
        var seconds = Math.floor(time % 60);
        return ('0' + hours).slice(-2) + ':' + ('0' + minutes).slice(-2) + ':' + ('0' + seconds).slice(-2);
    }

    // 获取视频当前时间-可自行添加,优先级从前到后
    function getCurrentTime() {
        var timeElements = [
            //用于百度网盘<div class="vjs-time-tooltip" aria-hidden="true" style="right: 0px;">0:12:09
            //document.querySelector(".vjs-time-tooltip"),
            //用于百度网盘<span class="vjs-current-time-display" aria-live="off" role="presentation">12:09</span>
            document.querySelector(".vjs-current-time-display"),
            //用于百度网盘<div class="vp-video__control-bar--play-time-current"><div class="vp-video__control-bar--play-time">00:04:17</div>
            document.querySelector(".vp-video__control-bar--play-time-current .vp-video__control-bar--play-time"),
            //用于bilibili的<span class="bpx-player-ctrl-time-current">2:27:34</span>
            document.querySelector(".bpx-player-ctrl-time-current")
        ];
        var currentTime = null;
        for (var i = 0; i < timeElements.length; i++) {
            if (timeElements[i]) {
                var timeStr = timeElements[i].textContent.trim();
                // 将当前时间格式化为秒数
                if (/^\d+:\d+$/.test(timeStr)) { // 格式为"mm:ss"
                    var minutes = parseInt(timeStr.split(":")[0], 10);
                    var seconds = parseInt(timeStr.split(":")[1], 10);
                    currentTime = minutes * 60 + seconds;
                } else if (/^\d+:\d+:\d+$/.test(timeStr)) { // 格式为"hh:mm:ss"
                    var hours = parseInt(timeStr.split(":")[0], 10);
                    minutes = parseInt(timeStr.split(":")[1], 10);
                    seconds = parseInt(timeStr.split(":")[2], 10);
                    currentTime = hours * 3600 + minutes * 60 + seconds;
                }
                break;
            }
        }
        return currentTime;
    }

    // 保存图片的函数。它模拟点击链接,打开保存窗口
    function download(href, name) {
        var save_link = document.createElement('a');
        save_link.href = href;
        save_link.download = name;
        var event = document.createEvent('MouseEvents');
        event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        save_link.dispatchEvent(event);
    }
})();