MSE Dump Tools

Media Source Extensions API 数据 Dump 工具

Verze ze dne 17. 01. 2021. Zobrazit nejnovější verzi.

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==UserScript==
// @name         MSE Dump Tools
// @namespace    CloudMoeMediaSourceExtensionsAPIDataDumper
// @version      1.3.0
// @description  Media Source Extensions API 数据 Dump 工具
// @author       TGSAN
// @include      /.*/
// @run-at       document-start
// @grant        GM_registerMenuCommand
// @grant        unsafeWindow
// ==/UserScript==

(function () {
    'use strict';

    GM_registerMenuCommand(`视频 - 最快播放速度`, function () { document.getElementsByTagName("video")[0].playbackRate = 16 });
    GM_registerMenuCommand(`视频 - 恢复播放速度`, function () { document.getElementsByTagName("video")[0].playbackRate = 1 });
    GM_registerMenuCommand(`音频 - 最快播放速度`, function () { document.getElementsByTagName("audio")[0].playbackRate = 16 });
    GM_registerMenuCommand(`音频 - 恢复播放速度`, function () { document.getElementsByTagName("audio")[0].playbackRate = 1 });
    GM_registerMenuCommand(`结束Dump`, EndAllDumpTasks);

    var dumpEndTasks = [];

    function EndAllDumpTasks() {
        dumpEndTasks.forEach((endTask) => {
            endTask();
        })
    }

    unsafeWindow.SavedDataList = [];

    unsafeWindow.DownloadData = function (dataKey, fileName) {
        const link = document.createElement('a');
        link.href = URL.createObjectURL(new Blob([unsafeWindow.SavedDataList[dataKey]]));
        link.download = fileName;
        link.click();
        window.URL.revokeObjectURL(link.href);
    }

    function DownloadVideo() {
        DownloadData("video", "CloudMoe_Dumped_Video.mp4");
    }

    function DownloadAudio() {
        DownloadData("audio", "CloudMoe_Dumped_Audio.m4a");
    }

    function Uint8ArrayConcat(a, b) {
        var c = new Uint8Array(a.length + b.length);
        c.set(a);
        c.set(b, a.length);
        return c;
    }

    function BytesToSize(bytes) {
        if (bytes === 0) return '0 B';
        var k = 1024;
        var sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
        var i = Math.floor(Math.log(bytes) / Math.log(k));
        return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
    }

    var _addSourceBuffer = unsafeWindow.MediaSource.prototype.addSourceBuffer;
    unsafeWindow.MediaSource.prototype.addSourceBuffer = function (mime) {
        console.log("MediaSource addSourceBuffer Type: ", mime);
        var sourceBuffer = _addSourceBuffer.call(this, mime);
        var _append = sourceBuffer.appendBuffer;
        var endToSave = false;
        var sourceBufferData = new Uint8Array();
        var isVideo = (mime.startsWith("audio") ? false : true);
        dumpEndTasks.push(() => {
            endToSave = true;
            console.warn(`轨道: ${mime} 已结束保存。`);
            if (isVideo) {
                unsafeWindow.SavedDataList["video"] = sourceBufferData;
                GM_registerMenuCommand(`下载视频数据 (${BytesToSize(sourceBufferData.length)})`, DownloadVideo);
            } else {
                unsafeWindow.SavedDataList["audio"] = sourceBufferData;
                GM_registerMenuCommand(`下载音频数据 (${BytesToSize(sourceBufferData.length)})`, DownloadAudio);
            }
        });
        sourceBuffer.appendBuffer = function (buffer) {
            if (!endToSave) {
                sourceBufferData = Uint8ArrayConcat(sourceBufferData, new Uint8Array(buffer));
            }
            _append.call(this, buffer);
        }
        return sourceBuffer;
    }

})();