HTML5 MediaSource适用于某些mp4文件,而不适用于其他文件(相同的编解码器)

时间:2017-02-14 18:55:10

标签: html5 video media-source

我正在使用MediaSource API。该代码直接来自Mozilla的示例页面:https://developer.mozilla.org/en-US/docs/Web/API/MediaSource/endOfStream

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
  </head>
  <body>
    <video controls></video>
    <script>
      var video = document.querySelector('video');

      var assetURL = 'frag_bunny.mp4';
      // Need to be specific for Blink regarding codecs
      // ./mp4info frag_bunny.mp4 | grep Codec
      var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';

      if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
        var mediaSource = new MediaSource;
        //console.log(mediaSource.readyState); // closed
        video.src = URL.createObjectURL(mediaSource);
        mediaSource.addEventListener('sourceopen', sourceOpen);
      } else {
        console.error('Unsupported MIME type or codec: ', mimeCodec);
      }

      function sourceOpen (_) {
        //console.log(this.readyState); // open
        var mediaSource = this;
        var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
        fetchAB(assetURL, function (buf) {
          sourceBuffer.addEventListener('updateend', function (_) {
            mediaSource.endOfStream();
            video.play();
            //console.log(mediaSource.readyState); // ended
          });
          sourceBuffer.appendBuffer(buf);
        });
      };

      function fetchAB (url, cb) {
        console.log(url);
        var xhr = new XMLHttpRequest;
        xhr.open('get', url);
        xhr.responseType = 'arraybuffer';
        xhr.onload = function () {
          cb(xhr.response);
        };
        xhr.send();
      };
    </script>
  </body>
</html>

除非我使用其他视频,否则此工作正常。 我有一个简短的测试mp4 - 根据bento4的mp4info - 使用与frag_bunny.mp4相同的编解码器编码。由于

,它在mediaSource.endOfStream();崩溃
Uncaught DOMException: Failed to execute 'endOfStream' on 'MediaSource': The MediaSource's readyState is not 'open'.
    at SourceBuffer.<anonymous>

我认为视频文件必须符合某些特定标准才能使用,但我不了解它们。

有人能指出我正确的方向吗?

有关文件的更多详细信息

frag_bunny mp4info

File:
  major brand:      mp42
  minor version:    1
  compatible brand: mp42
  compatible brand: avc1
  compatible brand: iso5

Movie:
  duration:   60095 ms
  time scale: 1000
  fragments:  yes

Found 4 Tracks
Track 1:
  flags:        7 ENABLED IN-MOVIE IN-PREVIEW
  id:           1
  type:         Audio
  duration: 60095 ms
  language: eng
  media:
    sample count: 0
    timescale:    22050
    duration:     0 (media timescale units)
    duration:     0 (ms)
    bitrate (computed): 65.075 Kbps
  Sample Description 0
    Coding:      mp4a (MPEG-4 Audio)
    Stream Type: Audio
    Object Type: MPEG-4 Audio
    Max Bitrate: 0
    Avg Bitrate: 64000
    Buffer Size: 6144
    Codecs String: mp4a.40.2
    MPEG-4 Audio Object Type: 2 (AAC Low Complexity)
    MPEG-4 Audio Decoder Config:
      Sampling Frequency: 22050
      Channels: 2
    Sample Rate: 22050
    Sample Size: 16
    Channels:    2
Track 2:
  flags:        7 ENABLED IN-MOVIE IN-PREVIEW
  id:           2
  type:         Video
  duration: 60095 ms
  language: eng
  media:
    sample count: 0
    timescale:    600
    duration:     0 (media timescale units)
    duration:     0 (ms)
    bitrate (computed): 612.178 Kbps
  display width:  640.000000
  display height: 360.000000
  Sample Description 0
    Coding:      avc1 (H.264)
    Width:       640
    Height:      360
    Depth:       24
    AVC Profile:          66 (Baseline)
    AVC Profile Compat:   e0
    AVC Level:            30
    AVC NALU Length Size: 4
    AVC SPS: [2742e01ea9181405ff2e00d418041adb0ad7bdf010]
    AVC PPS: [28de09c8]
    Codecs String: avc1.42E01E
Track 3:
  flags:        7 ENABLED IN-MOVIE IN-PREVIEW
  id:           3
  type:         Hint
  duration: 60095 ms
  language: eng
  media:
    sample count: 0
    timescale:    90000
    duration:     0 (media timescale units)
    duration:     0 (ms)
    bitrate (computed): 45.859 Kbps
  Sample Description 0
    Coding:      rtp  (RTP Hints)
Track 4:
  flags:        7 ENABLED IN-MOVIE IN-PREVIEW
  id:           4
  type:         Hint
  duration: 60095 ms
  language: eng
  media:
    sample count: 0
    timescale:    22050
    duration:     0 (media timescale units)
    duration:     0 (ms)
    bitrate (computed): 5.510 Kbps
  Sample Description 0
    Coding:      rtp  (RTP Hints)

我的视频的mp4info

File:
  major brand:      mp42
  minor version:    0
  compatible brand: mp42
  compatible brand: isom
  compatible brand: avc1

Movie:
  duration:   5568 ms
  time scale: 90000
  fragments:  no

Found 2 Tracks
Track 1:
  flags:        1 ENABLED
  id:           1
  type:         Video
  duration: 5533 ms
  language: und
  media:
    sample count: 166
    timescale:    90000
    duration:     498000 (media timescale units)
    duration:     5533 (ms)
    bitrate (computed): 465.670 Kbps
  display width:  560.000000
  display height: 320.000000
  frame rate (computed): 30.000
  Sample Description 0
    Coding:      avc1 (H.264)
    Width:       560
    Height:      320
    Depth:       24
    AVC Profile:          66 (Baseline)
    AVC Profile Compat:   c0
    AVC Level:            30
    AVC NALU Length Size: 4
    AVC SPS: [6742c01e9e218118534d40404050000003001000000303c8f162ee]
    AVC PPS: [68ce06cb20]
    Codecs String: avc1.42C01E
Track 2:
  flags:        3 ENABLED IN-MOVIE
  id:           2
  type:         Audio
  duration: 5568 ms
  language: eng
  media:
    sample count: 261
    timescale:    48000
    duration:     267264 (media timescale units)
    duration:     5568 (ms)
    bitrate (computed): 83.050 Kbps
  Sample Description 0
    Coding:      mp4a (MPEG-4 Audio)
    Stream Type: Audio
    Object Type: MPEG-4 Audio
    Max Bitrate: 91632
    Avg Bitrate: 83051
    Buffer Size: 280
    Codecs String: mp4a.40.2
    MPEG-4 Audio Object Type: 2 (AAC Low Complexity)
    MPEG-4 Audio Decoder Config:
      Sampling Frequency: 48000
      Channels: 1
    Sample Rate: 48000
    Sample Size: 16
    Channels:    1

Chrome版本:55.0.2883.95(64位)

2 个答案:

答案 0 :(得分:1)

如果mp4碎片,

t工作正常。你可以使用bento4的 mp4fragment 工具来做到这一点,你可以在这里找到: https://www.bento4.com/documentation/mp4fragment/

答案 1 :(得分:1)

基于Xander的答案,了解视频打包和流式传输的方式非常有用:

  • 相机刻录'原始'图像 - 通常是像素的大位图
  • 编码器将每个帧编码为更有效的存储和传输格式 - 示例编码器是h.264,h.265,vp9等。值得一提的是每个帧中都有变体和不同的配置文件(所以一个h) .264编码视频可能在特定设备/客户端上播放而另一个可能不在。)
  • 将视频流打包到容器中,例如MP4。此容器通常包含视频,音频,元数据,字幕(如果存在)等的流。
  • 如果要使用自适应比特率流协议(例如HLS或DASH)对视频进行流式传输,则视频容器将被分解为相等长度的段,例如, 10秒段,客户端可以一次请求一个。如果视频在多个比特率视频流中可用,则允许客户端从与当前网络条件最匹配的比特率中选择下一个段。

正如Xander所说,上面的代码旨在处理以这种方式分段或分段的MP4文件,而不是非碎片的mp4视频文件。