【问题标题】:Prepare mp4 videos for Media Source Extensions API using ffmpeg使用 ffmpeg 为 Media Source Extensions API 准备 mp4 视频
【发布时间】:2018-07-13 07:10:14
【问题描述】:

这个命令产生 init.mp4 + 一堆 m4s 文件,我正在尝试使用 MSE 播放它们:

ffmpeg -i <input file> -f hls -hls_segment_type fmp4 -c:v copy playlist.m3u8

这是我正在使用的客户端代码:

var socket = io();
var video = document.querySelector('video');
var mimeCodec = 'video/mp4; codecs="avc1.64000d,mp4a.40.2"'; 
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
    var mediaSource = new MediaSource;
    video.src = URL.createObjectURL(mediaSource);
    mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
    console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen (_) {
  var mediaSource = this;
  var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
  sourceBuffer.mode = 'sequence'; 
  socket.on('broadcast', function (newPiece) {
      // here i'm getting the buffer of the video  == buffer
      sourceBuffer.addEventListener('updateend', function (_) {
        video.play().then(function() { }).catch(function(error) { });
      });
      sourceBuffer.appendBuffer(buffer); // when the seconde video comes i append it's buffer
  })
};

当我发送init.mp4 文件后跟playlist0.m4s, playlist1.m4s, playlist2.m4s, .... 时,一切正常。 但是当我尝试播放init.mp4 文件时,紧接着是 6,7,8 而不是 0,1,2,意思是 playlist6.m4s, playlist7.m4s, playlist8.m4s, ....,它没有用。 我不知道为什么,这应该是直播视频,从一开始就看直播的观众得到init.mp4, playlist0.m4s, playlist1.m4s, playlist2.m4s, ....。 5 分钟后出现的人会得到类似 init.mp4, playlist32.m4s, playlist33.m4s, playlist34.m4s, .... 的东西,但到目前为止,它只适用于得到 init.mp4, playlist0.m4s, playlist1.m4s, playlist2.m4s, .... 的观众。该视频无法为其他人播放

【问题讨论】:

  • 是否需要 WebM?如果没有,你可以试试 mp4/h.264。
  • @heff WebM 不是必需的,如果它是 mp4,只要它与 Media Source Extensions API 配合良好,就没有问题,如果你有一个工作示例,如果你把它作为答案,我将不胜感激
  • 在这里查看我的答案stackoverflow.com/a/30643655/83169。您必须在客户端工作,以便您可以将 fMP4 分块到 moof+mdat 段中。
  • @PabloMontilla 我在搜索时看到了您的答案,但我不明白,我是 ffmpeg 和 mse 的初学者,您能否发布您的意思作为答案的代码,谢谢

标签: video ffmpeg


【解决方案1】:

如果您可以使用fMP4 而不是webm,则可以使用以下命令行生成合适的分段MP4(面向低延迟):

ffmpeg -i <input file> -c:v libx264 -profile:v main -level 3.2 -pix_fmt yuv420p -b:v <bitrate> -preset medium -tune zerolatency -flags +cgop+low_delay -movflags empty_moov+omit_tfhd_offset+frag_keyframe+default_base_moof+isml -c:a aac <output file.mp4>

请务必使用最新版本。

您仍然需要解析生成的 MP4 输出,以向 Web 客户端发送一个带有 moov 框的初始化段,以及成对的 moof+mdat 框作为 MSE 播放视频的段。

【讨论】:

  • 谢谢它需要做很多工作,我发现我可以使用这个命令ffmpeg -i &lt;input file&gt; -f hls -hls_segment_type fmp4 -c:v copy playlist.m3u8,然后发送到浏览器init.mp4,然后是playlist0.m4s, playlist1.m4s, playlist2.m4s, ...这个工作正常,但是当我尝试时出现问题就像这样init.mp4, playlist5.m4s, playlist6.m4s, ... 它不起作用,我不知道为什么。它应该像现场视频,这意味着有人可以在 10 分钟后从头开始观看,我的意思是你不能将 init.mp4, playlist0.m4s, playlist1.m4s, ... 发送给 10 分钟后的人
  • 您基本上有两个标准选项:HLS(iOS 设备唯一支持的一个)和 DASH。两者都可以使用 fMP4,并且都使用描述不同视频片段的文件(.m3u8 或 .xml 清单)。如果您想要让人们看到适合他们带宽的视频,那么您需要在客户端使用 HLS 或 DASH 以及合适的播放器(例如 Shaka [github.com/google/shaka-player])。如果您想流式传输实时事件,您可能可以根据您的需要调整 HLS 或 DASH 方式。否则,您必须按照我在答案中告诉您的内容编写自己的代码。
  • 您在回答中建议的内容需要更多代码 + 与playlist.m4s 相比,mp4 文件太大,如果有办法我可以像这样init.mp4, playlist8.m4s, playlist9.m4s, ... 播放视频,我的意思是不要以连续的方式很好,我会更新我的问题,让你明白我的意思
  • 您可以简单地将video.currentTime 更改为正确的时间。您的问题是您将来会添加片段,但播放器尝试从头开始。您可以通过查看video.buffered 来查看与加载的段对应的时间。
  • 我是初学者,这是我第一次使用 MSE 和视频,你能告诉我如何像你说的那样通过查看 video.bufferedvideo.currentTime 更改为正确的吗跨度>
猜你喜欢
  • 2013-08-08
  • 2015-07-02
  • 2010-12-22
  • 2018-02-14
  • 2012-11-27
  • 2012-05-22
  • 1970-01-01
  • 2018-05-29
  • 2022-12-25
相关资源
最近更新 更多