【问题标题】:Can I download all segments of a m3u8 file as one mp4 file using web ( no ffmpeg )我可以使用网络(没有 ffmpeg)将 m3u8 文件的所有片段下载为一个 mp4 文件吗?
【发布时间】:2015-02-20 13:56:51
【问题描述】:

是否可以使用 javascript 或 php 将所有 m3u8 段下载到一个文件中

我搜索了这个,但找不到任何东西;

【问题讨论】:

  • 下载所有片段很容易,但您需要使用视频转换工具来重建 mp4。这通常在下载片段时由 javascript 即时完成
  • @andrew 没有视频转换工具可以保存为ts
  • 您问的是 HLS 吗? m3u8 可以在多种情况下使用。在 HLS 的情况下,容器格式确实是与 MP4 不同的 TS(MPEG 传输流)。生成的文件需要从 TS 重新混合到 MP4 中。
  • 可能是 ffmpeg,mp4Box 对于分段视频来说可能是一个不错的选择
  • 如果您的托管公司允许,您可以在运行 php 的同一台服务器上运行 ffmpeg。

标签: javascript php m3u8


【解决方案1】:

TL/DR: 我使用以下代码从 m3u8 链接下载所有 mpeg-ts 块文件,然后以编程方式将它们中的每一个转换为 .mp4。

我最终得到了许多可以添加到 vlc 播放列表并播放的小 .mp4 文件,但我无法使用 javascript 以编程方式将所有这些 mp4 文件连接到一个 mp4 文件中。

我听说将所有这些 ts 文件合并为一个 mp4 文件的最后一部分可以使用 mux.js 完成,但我自己没有这样做。

加长版:

我最终做的是使用m3u8_to_mpegts 将 m3u8 文件指向的每个 MPEG_TS 文件下载到一个目录中。

var TsFetcher = require('m3u8_to_mpegts');

TsFetcher({
    uri: "http://api.new.livestream.com/accounts/15210385/events/4353996/videos/113444715.m3u8",
       cwd: "destinationDirectory",
       preferLowQuality: true,
   }, 
   function(){
        console.log("Download of chunk files complete");
        convertTSFilesToMp4();
   }
);

然后我使用mpegts_to_mp4将这些 .ts 文件转换为 .mp4 文件

var concat = require('concatenate-files');


// Read all files and run 
function getFiles(currentDirPath, callback) {
    var fs = require('fs'),
        path = require('path');
    fs.readdir(currentDirPath, function (err, files) {
        if (err) {
            throw new Error(err);
        }

        var fileIt = files.length;
        files.forEach(function (name) {
            fileIt--;
            // console.log(fileIt+" files remaining");
            var filePath = path.join(currentDirPath, name);
            var stat = fs.statSync(filePath);
            if (stat.isFile()) {
                callback(filePath, (fileIt==0));
            }
        });
    });
}




var mpegts_to_mp4 = require('mpegts_to_mp4');
var toConvertIt=0, doneConvertingIt = 0;

function convertTSFilesToMp4(){ 
    getFiles("destinationDirectory/bandwidth-198000", 
        function onFileDiscovered(filePath, noMoreFiles){   //onFileDiscovered runs for each file we discover in the destination directory
            var filenameParts = filePath.split("/"); // if on Windows execute .split("\\");, thanks Chayemor!
            var filename = filenameParts[2];
            if(filename.split(".")[1]=="ts"){   //if its a ts file
                console.log(filename);  

                mpegts_to_mp4(filePath, toConvertIt+'dest.mp4', function (err) {
                    // ... handle success/error ...
                    if(err){
                        console.log("Error: "+err);
                    }
                    doneConvertingIt++
                    console.log("Finished converting file "+toConvertIt);
                    if(doneConvertingIt==toConvertIt){
                        console.log("Done converting vids.");
                    }
                });
                toConvertIt++;
            }
        });
}

注意:如果你想使用给定的代码,需要改变什么:

  • uri 明显
  • 您希望保存 ts 文件的 (cwd) 位置(我的是destinationDirectory)
  • preferLowQuality 如果您更喜欢它能找到的最高质量,请将其设置为 false
  • 下载后读取 ts 文件的位置(我的是destinationDirectory/bandwidth-198000)

我希望这段代码将来能对某人有所帮助。 特别感谢 Tenacex 在这方面的帮助。

【讨论】:

  • 如果在windows上执行:var filenameParts = filePath.split("\\");
  • 非常感谢您提供的精彩信息。我有一个疑问,想知道你是否可以帮我解决它。查询:我想让我的 HLS 视频对用户离线可用。是否可以将 HLS 视频存储在用户浏览器中(在索引数据库等中),然后直接从那里播放。有什么方法可以让视频离线观看?
猜你喜欢
  • 1970-01-01
  • 2021-02-26
  • 1970-01-01
  • 2016-05-14
  • 2018-10-08
  • 2020-12-14
  • 1970-01-01
  • 2018-11-18
  • 1970-01-01
相关资源
最近更新 更多