首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >碎片化的MP4不会出现在Chrome中

碎片化的MP4不会出现在Chrome中
EN

Stack Overflow用户
提问于 2017-11-13 15:36:22
回答 3查看 3K关注 0票数 3

但是在Firefox中运行得很好。

谷歌Chrome版本:61.0.3163.100(官方版本)(64位)

Mozilla Firefox版本: 56.0.2 (64位)

我的视频是通过MP4通过WebSocket流到一个客户端html页面上的,在那里它被导入到MSE中。视频编解码器是H264的主要配置文件。视频信息已经检查了FFPROBE和其他检查人员,以确保数据的完整性是安全的。在修改FMP4时使用以下标志:

代码语言:javascript
复制
 "empty_moov+default_base_moof+frag_keyframe"

我还双重检查了第一个碎片是所谓的“初始化段”,大小为24个字节。正如我所说的,Firefox播放很好。

下面是客户机代码(主要是从这里借用的):

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>MSE Demo</title>
</head>

<body>
   <h1>MSE Demo</h1>
   <div>
      <video id="video1" controls width="80%"   autoplay="true"> </video>
   </div>
 <script type="text/javascript">
    (function () {

        var mime = 'video/mp4; codecs="avc1.4D401E"';

        if (!MediaSource.isTypeSupported(mime)) {
            document.querySelector('h1').append(' - Unsuported mime type :(');
            return;
        }

        var buffer;
        var websocket;
        var buffer_size = 4 * 1024 * 1024;
        var buffer_index = 0;
        var frag_mp4_buffer = new Uint8Array(buffer_size);
        var video = document.querySelector('video');
        var mediaSource = new MediaSource();

        mediaSource.addEventListener('sourceended', function (e) { console.log('sourceended: ' + mediaSource.readyState); });
        mediaSource.addEventListener('sourceclose', function (e) { console.log('sourceclose: ' + mediaSource.readyState); });
        mediaSource.addEventListener('error', function (e) { console.log('error: ' + mediaSource.readyState); });

        video.src = window.URL.createObjectURL(mediaSource);
        video.crossOrigin = 'anonymous';

        mediaSource.addEventListener('sourceopen', function (e) {
            console.log('sourceopen: ' + mediaSource.readyState);
             //doesn't help:
            //  var playPromise =  video.play();
            // In browsers that don’t yet support this functionality,
            // playPromise won’t be defined.
            /*
            if (playPromise !== undefined) {
                playPromise.then(function () {
                    // Automatic playback started!
                }).catch(function (error) {
                    // Automatic playback failed.
                    // Show a UI element to let the user manually start playback.
                });
            }
            */

            buffer = mediaSource.addSourceBuffer(mime);

            buffer.addEventListener('updateend', function (e) {
                if (video.duration && !video.currentTime) {
                    video.currentTime = video.duration;
                }
            });

            var websocket = new WebSocket('ws://' + document.location.hostname + ':8080');
            websocket.binaryType = 'arraybuffer';

            websocket.addEventListener('message', function (e) {
                var data = new Uint8Array(e.data);
                console.log("got packet! size:" + data.length);
                if (data.length) {
                    if ((buffer_index + data.length) <= buffer_size) {
                        frag_mp4_buffer.set(data, buffer_index);
                        buffer_index = buffer_index + data.length;

                        if (!buffer.updating && mediaSource.readyState == 'open')
                         {
                            var appended = frag_mp4_buffer.slice(0, buffer_index);
                            buffer.appendBuffer(appended);
                            frag_mp4_buffer.fill(0);
                            buffer_index = 0;

                        }
                    }
                }
            }, false);
        }, false);
    })();
    </script>
 </body>

另一个重要的信息,您可以看到我注释掉了video.play()调用。这实际上是应用程序启动时抛出错误的唯一位置:

DOMException:未能加载,因为没有找到支持的源

我尝试了来自这里的以下解决方案:

代码语言:javascript
复制
      var playPromise =  video.play();

      if (playPromise !== undefined) {
                playPromise.then(function () {
                    // Automatic playback started!
                }).catch(function (error) {
                    // Automatic playback failed.
                    $(document).on('click', '#video1', function (e) {
                        var video = $(this).get(0);
                        if (video.paused === false) {
                            video.pause();
                        } else {
                            video.play();
                        }

                        return false;
                    });
                });
       }

但没什么改变。视频区域总是白色的。

EN

回答 3

Stack Overflow用户

发布于 2017-11-19 08:52:25

我只是遇到了一个类似的问题,我只能让我的零碎mp4在火狐上播放,但不能在chrome上使用这个mse实例。我试图首先交付一个完整的文件,而不是通过websocket发送它,因为我想确保我的碎片mp4被正确格式化。我发现的问题是,在我的ffmpeg命令中,如果我输入-an删除音频,那么我的文件将不会在chrome中播放,但在firefox中仍然有效。使用没有音频标志或特别使用-c:a libfdk_aac允许我的mp4在chrome和火狐上播放。另外,您应该只需要-movflags +dash,而不是所有其他的移动标志。为了在下面的代码片段中提供参考,我使用了一个来自ip摄像机的rtsp提要,它是用h264视频编码的,因此使用了-c:v copy

在mac上进行了测试,在firefox和safari上进行了测试,但没有使用chrome:

ffmpeg -i input_source -an -c:v copy -f mp4 -movflags +dash dash.mp4

在mac上进行测试,在firefox、safari和chrome上工作

ffmpeg -i input_source -c:v copy -f mp4 -movflags +dash dash.mp4

ffmpeg -i input_source -c:a libfdk_aac -c:v copy -f mp4 -movflags +dash dash.mp4

*编辑我刚刚发现了更多关于为什么音频编码与在铬上回放相关的信息。我的mimetype/codec出错了,chrome也没有火狐和safari那么宽容。 var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';我把它改成了var mimeCodec = 'video/mp4; codecs="avc1.42E01E"';和mp4,在没有播放音频的情况下,它和其他浏览器一样被编码成了。也许你有音频,但没有包括音频部分的编解码器?或者你的视频编解码器不适合你的视频?很难不看到用于创建文件的完整ffmpeg命令。 *第二版编辑。我制作了一个 小工程 ,使用ffmpeg、nodejs、express和socket.io在媒体源扩展上测试实时流mp4。它的边缘有点粗糙,但它主要起作用。

票数 4
EN

Stack Overflow用户

发布于 2020-11-15 10:41:46

这在Firefox和Chrome上适用于我:

代码语言:javascript
复制
ffmpeg -i input.any \
  -f mp4 \
  -movflags faststart+separate_moof+empty_moov+default_base_moof \
  -acodec aac -b:a 256000 \
  -frag_duration 500K \
   output.mp4

它还应该与来自的SourceBuffer一起工作。你在这里寻找的米姆类型是audio/mp4; codecs="mp4a.40.2"

但是,在这一点上,我不知道如何在这个文件中查找(如果这是可能的话),例如,如果您不想将整个文件发送到客户端,而是从特定的时间戳开始,然后直接跳转到[moof][mdata]-pair开始加载。

票数 3
EN

Stack Overflow用户

发布于 2021-07-08 20:37:35

Chrome不喜欢视频没有音频的时候。

如果您使用一个m4s片段生成一个HLS播放列表(这些片段本质上是一个片段的mp4),那么您还需要确保有音频,或者它根本不会播放。

这个应该适用于所有浏览器:

代码语言:javascript
复制
ffmpeg -y -i SOURCE.mp4 -f lavfi -i aevalsrc=0 -af apad -shortest -c:v copy -movflags empty_moov+default_base_moof+frag_keyframe+omit_tfhd_offset -write_tmcd off FRAGMENTED_WITH_PADDED.mp4
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47268020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档