使用ffmpeg处理时流式传输mkv文件

时间:2019-04-01 17:12:25

标签: python node.js ffmpeg video-streaming mkv

我想做什么:

  • 我想在Firefox中播放mkv视频。
  • 但是Firefox不支持mkv格式。

因此,我进行了大量搜索后发现, 按照这些步骤,我可以流式播放而不是播放视频。

  • 可以使用FFmpeg将mkv转换为m3u8
  • m3u8指向ts段文件
  • 然后在浏览器端使用hls.js播放视频

但是要抓住的是我要以编程方式执行此操作。

我实际上想做什么:

步骤

  • 客户端将巨大(> 1 GB)的mkv文件上传到客户端的服务器(服务器是客户端的计算机本身)

  • 上传完成后,

  • 客户端请求播放视频。

  • 服务器开始转码并立即向客户端发送m3u8流,而不是让客户端等待转码完成。

  • 客户端应该可以搜索视频。 (最重要的部分)

EmbyPlex都已经实现了它。

我能够在chrome中使用它,因为它支持播放某些mkv文件。 我编写了一个节点js服务器,它接受Range标头和伪流视频。

A gist

但是正如我所提到的,Firefox对mkv说不。

因此,我尝试了hls的操作,但是我无法完全获得生成流并即时播放的命令。

我是从命令行开始的

ffmpeg -i ../stream.mkv -hls_list_size 0 -acodec copy -vcodec copy file.m3u8

和另一个外壳实例上的简单http-server

我的index.html文件

<html>
    <title>Welcome</title>
    <body>
        <script src="./hls.js"></script>
        <video id="video" width="400" controls></video>
        <script>
            var video = document.getElementById('video');
            if(Hls.isSupported()) {
                var hls = new Hls();
                hls.loadSource('file.m3u8');
                hls.attachMedia(video);
                hls.on(Hls.Events.MANIFEST_PARSED,function() {
                    video.play();
                });
            } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
                video.src = 'file.m3u8';
                video.addEventListener('loadedmetadata',function() {
                    video.play();
                });
            }
        </script>
    </body>
</html>

在运行时,我继续请求服务器。

我能够获得视频,但它仅查找已转换为ts文件的视频。

它是随机的,视频长度不断增加。有时无法播放,并且在FFmpeg转换为m3u8后,如果刷新网页,则会播放视频。

我认为这与m3u8文件的连续覆盖有关。 有没有办法预先确定m3u8的文件内容并将其填满?

我希望能够进一步寻找并以某种方式产生另一个FFmpeg进程 从视频的时间戳开始?我怎样才能找到寻求帮助的部分?

所以我想再次做

  • 我要请求服务器播放视频文件
  • 它产生一个子进程FFmpeg进行转码
  • 向客户端发送流
  • 客户应该能够找到目标,并且应该发挥作用。

1 个答案:

答案 0 :(得分:1)

这个问题实际上非常困难。 Plex可以作弊,因为文件是专门为每个用户打包的,并且在大多数情况下都由plex控制播放器。

Plex的基本工作方式:

对文件进行预分析,并生成完整的清单。转码从文件的开头开始,并在本地缓存段。如果发生寻道(请求了未在本地缓存的段),则转码被取消,并且在所请求段的偏移量处重新开始,并且播放器会使已缓存的任何段无效。

如果客户端缓存的段没有无效,或者使用了CDN,则不能保证第一个,后搜索段将与稍后生成的前一个段对齐。这将导致边界跳和弹出。

例如,在电影中搜索1个小时,而后退30秒。这两个片段的创建顺序不正确,无法流畅地回放

如果您需要支持现成的播放器和CDN,则问题将更加棘手,因为您必须能够即时生成帧精确的片段。帧准确的音频非常棘手,特别是在编解码器中使用启动样本。我建议您研究像mux.com这样的商业服务,基本上可以做到这一点。