使用HTML <video> 无缝播放视频文件序列

3
我尝试了几种方法:
  1. 我试图创建隐藏的视频标签并显示/隐藏它们,但这会导致闪烁。

  2. 我试图更改视频的src属性,但必须在播放()之前调用load()方法,而load()将加载新视频。

    这也不是我想要的,因为这会导致新视频停止一段时间(因为需要时间来加载)。

  3. 我试图通过使用ajax在前一个视频完成之前在后台加载新视频来缓存新视频。 新视频可以完全下载(300Kbytes),然后才结束旧视频。

    但是,当我在新视频上调用.load()函数时,它会再次下载。

我的问题是:对于第三种方法,视频对象是否有一种方法可以利用缓存中已下载的文件?

阅读了一些资料后,我认为以上三种可能是实现我的目标的唯一方法。第三种方法确实是我想要的,但是视频文件只被下载了两次(一次是Ajax下载,另一次是调用load())。请注意,如果不调用load(),仅仅更改src属性并调用play()是行不通的。


为什么不将src属性设置为缓存视频(可能是data:video / mp4格式之类的),然后调用load()? - Palash
嗨,我不知道如何使用JavaScript访问缓存文件?例如,我使用$.get(“http://myvideo”),但我不知道它保存在哪里?有什么提示吗?非常感谢。 - user534498
你可以使用 var data; $.get("myvideo").done(function(dat){data = dat;}); 你明白了吗? - Palash
我尝试将数据保存到Blob中,并从该Blob创建对象URL,然后从Blob加载URL。问题在于.load函数需要非常长的时间,并且会导致比替换<video>标签更多的闪烁。似乎不可能在视频之间实现无缝交易(实际上我正在尝试通过将实时视频分成小视频间隔并按顺序实时播放它们来实现实时视频)。 - user534498
更具体地说,对于替换视频标签的方法,隐藏的视频标签可以在旧标签仍在播放时调用加载,因此当调用播放并替换旧标签时,它会更加流畅(尽管会闪烁)。然而,如果只是替换src并在缓冲对象上调用load,则会有显着的延迟。 - user534498
你可以根据获取的延迟,在第一个视频结束前开始播放第二个视频,并在第一个视频结束时将其隐藏,从而使第二个视频无缝播放? - Palash
1个回答

6
媒体源扩展是您需要的。目前(撰写时),有关它们的良好文档很难找到(MDN 的文档大部分只是纸面文件),但如果你敢尝试,你可以深入规范学习。

简而言之,使用媒体源扩展,您可以创建一个MediaSource对象并将其设置为<video>元素的源,而不是将<video>指向完整视频的 URL。然后,您可以使用 JavaScript 明确下载代表直播流的更多段视频,并将它们添加到您的MediaSource对象中,这些部分将无缝播放。

此外,虽然它略微超出了您所问的范围,但MPEG-DASH是一种通过对短片段进行编码作为单独的文件(例如,短的独立 mp4),并将这些片段逐个提供给浏览器来实现您感兴趣的操作(即通过流式传输实时视频)的技术。没有媒体源扩展,无法在浏览器中实现 MPEG-DASH,因此它们经常一起讨论。有关使用 HTML 和 JavaScript 使用媒体源扩展构建 DASH 播放器的文档(在不同细节级别上)可以在BBC 的技术博客MSDN上找到。

不幸的是,媒体源扩展尚未在所有主要浏览器中提供。例如,我的 Mac 上最新版的 Firefox 没有 window.MediaSource。这意味着您不能仅使用 HTML5<video>元素在所有主要浏览器上进行分段直播流传输yet。不幸的是,如果需要跨浏览器兼容性,则仍需退回到 Flash。

与你一样,我试图在不使用媒体源扩展的情况下实现这种行为。我尝试了许多技术(并将它们结合起来),包括在<video>元素上切换URL,取消隐藏并播放<video>元素,预先下载片段并将它们存储在Blobs中,然后将其用作<video>元素的src,以及将preload属性设置为auto,预先将片段加载到内存中……但是没有任何效果。在Google Chrome中,使用任何这些技术都会导致明显的卡顿,当你从第一个视频的ended事件中使用play()播放第二个视频时,即使你预先完全加载了第二个视频。在不支持媒体源扩展的浏览器中,使用<video>元素无法实现连续无缝的视频播放,除非有一些卡顿。


1
谢谢。我没有看这个。我已经自己找到了一个解决方案(不完美)。解决方案是:使用video.js,并动态创建视频标签并交换它们。此外,不要使用play_ended或类似的事件,使用计时器。例如,如果您下载了视频,请获取视频长度(对我来说很简单,因为每个视频都是0.8秒),并使用0.8秒的计时器进行交换。闪烁消失了。为了同步,我使用播放速率,使视频动态地播放更快或更慢(也相应地设置计时器)。 - user534498
@user534498 感谢您的接受,但如果您不再对这个问题感兴趣并且还没有阅读答案,最好不要接受它。这样,如果其他人回答了这个问题(也许提供了一个关于如何在几年后使用媒体源扩展来完成此操作的指南,到那时它们将无处不在),哪个答案排在顶部可以由社区投票决定,而不是我的答案被困在那里。 - Mark Amery
@user534498 你好,能否在这里分享一个例子?非常感谢。 - SuperBerry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接