javascript - 如何在浏览器中将 m3u8 URL 转换为 mp4 可下载文件?

标签 javascript google-chrome-extension mp4 converters m3u8

我正在编写一个扩展程序来从网站下载视频。该网站有 mp4文件和 m3u8文件。我已经实现了部分直接下载mp4文件。我坚持转换 m3u8文件到 mp4 .我尝试了很多 js 包,但有很多依赖项,即使使用 browserfy 也失败了.
当前 popup.js 文件

unction loadvideoList(callback){
    chrome.storage.sync.get(['courseID'], function(result) {
        if(result.courseID != 'undefined'){
            $.ajax({
                type: 'GET',
                url: "http://localhost:80/get_videos_list/"+result.courseID,
                crossDomain: true,
                success: function(response) {
                    document.getElementById("loading_icon").style.display='none';
                    document.getElementById("videos_list").style.display='block';
                    document.getElementById("videos_list").style.padding='10px';
                    for(var i = 0; i < response.video_list.length; i++){
                        if(response.video_list[i].type == 'mp4'){
                            handleDownloadButton(response.video_list[i]);
                        }else{
                            // ************ HERE ***************
                            handleDownloadButton-m3u8Tomp4(response.video_list[i].video_url)
                        }
                    }
                },
                error: function (err) {
                    alert("unexpected error occured: "+err.code);
                    console.log(err);
                }
             });
        }else{
            document.getElementById("videos_list").style.display='none';
            document.getElementById("videos_list").style.padding='0';
        }
    });
}

function handleDownloadButton(json_vid){
    var node = document.createElement("DIV"); 
    // node.style.marginBottom = "5px"
    var t = document.createElement('p');
    t.textContent = json_vid.file_name;
    t.style.width ="240px";
    node.appendChild(t);
    node.style.padding = "5px";
    var downloadBtn = document.createElement("BUTTON");
    downloadBtn.style.cssFloat = "right";
    downloadBtn.className = "btn btn-primary btn-sm download_btn";
    downloadBtn.innerHTML = "Download"; 
    // downloadBtn.value = json_vid.video_url;
    node.appendChild(downloadBtn);
    downloadBtn.id = json_vid.video_id;
    document.getElementById("videos_list").appendChild(node);

    var progress_bar = document.createElement("DIV");
    progress_bar.className = "progress_container";
    node.appendChild(progress_bar);
    var moving_bar = document.createElement("DIV");
    moving_bar.className = "progress_bar";
    progress_bar.appendChild(moving_bar);
    moving_bar.id = json_vid.video_id+"bar";

    $(function(){
        $(`#${json_vid.video_id}`).click(function(){
            $(`#${json_vid.video_id}`).attr("disabled", true);
            // alert(json_vid.video_url);
            var that = this;
            var page_url = json_vid.video_url;
        
            var req = new XMLHttpRequest();
            req.open("GET", page_url, true);
            // req.withCredentials = true;
            req.addEventListener("progress", function (evt) {
                if(evt.lengthComputable) {
                    var percentComplete = evt.loaded / evt.total;
                    // document.getElementById("download_stat").innerHTML = percentComplete;
                    // console.log(percentComplete);
                    document.getElementById(json_vid.video_id+"bar").style.width = `${percentComplete*100}%`;
                    document.getElementById(json_vid.video_id).textContent = `${(percentComplete*100).toFixed(2)}%`;
                }
            }, false);
            
            req.responseType = "blob";
            req.onreadystatechange = function () {
                if (req.readyState === 4 && req.status === 200) {
                    var filename = $(that).data('filename');
                    if (typeof window.chrome !== 'undefined') {
                        // Chrome version
                        $(`#${json_vid.video_id}`).attr("disabled", false);
                        $(`#${json_vid.video_id}`).attr("onclick", "").unbind("click");
                        document.getElementById(json_vid.video_id).textContent = 'Save';
                        $(function(){
                            $(`#${json_vid.video_id}`).click(function(){
                                // alert("download is ready");
                                var link = document.createElement('a');
                                // link.text = "download is ready";
                                // document.getElementById("videos_list").appendChild(link);
                                link.href = window.URL.createObjectURL(req.response);
                                link.download = json_vid.file_name;
                                link.click();
                            });
                        });
                        
                    } else if (typeof window.navigator.msSaveBlob !== 'undefined') {
                        // IE version
                        var blob = new Blob([req.response], { type: 'application/force-download' });
                        window.navigator.msSaveBlob(blob, filename);
                    } else {
                        // Firefox version
                        var file = new File([req.response], filename, { type: 'application/force-download' });
                        window.open(URL.createObjectURL(file));
                    }
                }
            };
            req.send();
        });

    });
}

handleDownloadButton功能创建按钮直接下载mp4文件。我需要实现一个名为 handleDownloadButton-m3u8Tomp4 的类似函数(参见代码示例)应该首先转换 http://...file.m3u8到 mp4 并使其也可下载。我在类似的存储库中寻找脚本,例如 https://github.com/puemos/hls-downloader-chrome-extension ,但我无法这样做。那就太好了,如果有人可以帮助我,在此先感谢!

最佳答案

您可以尝试使用 ffmpeg.wasm 将 .m3u8 文件转换为 .mp4 文件。 ffmpeg.wasm 是 FFmpeg 的纯 WebAssembly/JavaScript 端口。他们甚至还有一个 example repository for a Chrome extension .不过我自己还没有测试过。
StackOverflow 上还有其他关于如何使用 FFmpeg 转换 m3u8 文件的问题。 , 喜欢 this one例如。

关于javascript - 如何在浏览器中将 m3u8 URL 转换为 mp4 可下载文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58291748/

相关文章:

javascript - Electron JS : avoiding cross-origin issues

google-chrome - 如何访问谷歌浏览器本地资源

video - 为什么 MP4 mdat atom 不以 H.264 NALU 起始码开头?

video - ISO BMFF 和其他 mp4 格式有什么区别?

javascript - javascript MSE可以从中间播放分段的mp4吗?

javascript - 使用 SJCL 客户端加密文件

javascript - 如何在不使用 OnClientClick 的情况下在表单提交之前运行 jQuery 脚本

javascript - 使用 javascript 添加总数

angular - Chrome - 调试 Angular/Typescript - 如何导航到 ts 文件

javascript - 将标签输入保存在数组中并在重新打开时显示