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

时间:2019-10-08 18:00:05

标签: 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的类似存储库中寻找脚本,但我无法这样做。太好了,如果有人可以帮助我,谢谢!

1 个答案:

答案 0 :(得分:1)

您可以尝试使用 ffmpeg.wasm 将 .m3u8 文件转换为 .mp4 文件。 ffmpeg.wasm 是 FFmpeg 的纯 WebAssembly / JavaScript 端口。他们甚至有一个example repository for a Chrome extension。不过我自己还没有测试过。

StackOverflow 上还有其他问题涉及如何使用 FFmpeg 转换 m3u8 文件,例如 this one