HTML5 视频:强制中止缓冲

Posted

技术标签:

【中文标题】HTML5 视频:强制中止缓冲【英文标题】:HTML5 Video: Force abort of buffering 【发布时间】:2011-05-03 13:55:55 【问题描述】:

如何在 html5 视频上强制中止事件?我有一个覆盖,当我关闭它时,视频应该暂停播放,然后停止缓冲。但是,我的互联网连接继续发疯。哦,我在 Mac OS X 10.6 上使用 Chrome 7.0.5。

我已经尝试了几件事——没有一个奏效:

(对于不熟悉XUI的人,x$就像jQuery的包装函数)

首先,调度一个 abort HTML 事件:

var videoEl = x$('#video_el')[0];
videoEl.pause();
var evObj = document.createEvent('HTMLEvents');
evObj.initEvent('abort', false, false);
videoEl.dispatchEvent(evObj);

接下来,更改 src,然后强制加载:

var videoEl = x$('#video_el')[0];
videoEl.pause();
videoEl.src = "";
videoEl.load(); //tried with and without this step

编辑:我的视频元素看起来像这样:

<video id="video_el" src="<video_url>" preload="none" controls="controls" />

同样,这些都不起作用。以前有人遇到过这个问题吗?有什么建议?

总之,我试图强制 HTML5 视频元素停止缓冲。

谢谢!

【问题讨论】:

【参考方案1】:

好的,所以在过去的几天里,我一直在努力解决这个问题。 这是我的分析和解决方案:

简而言之,我试图解决的问题: 我注意到,当播放器暂停时,HTML5 播放器并没有停止下载(完全没有,即使在合理的时间之后也没有)。使用 24/7 音频流并开发一个移动网站,我意识到这对于我的访问者来说远非最佳,考虑到如果他们让网站保持打开状态会导致高数据使用量 - 尽管我确实认为我会让一些电信公司非常高兴通过“俯瞰“这个问题... 澄清一下,我并不真正关心固定长度的文件。大多数情况下,下载完整文件是查看在线资源所需的功能(想想慢速连接),所以我没有试图阻止。

分析: HTML5 音频元素没有 stop() 函数,也没有可以设置允许缓冲的数据量的选项,或者说您希望元素停止缓冲的方式 - 不要将此与“预加载”功能混淆,这仅适用于单击播放按钮之前的元素。 我不知道为什么会这样以及为什么这个功能不可用。如果有人可以向我解释为什么这些关键功能没有在一个可以使手机的 Web 开发更好、更标准化的标准中实现,我很想知道。

解决方案: 我发现在您的音频元素中实现(某种)停止功能的唯一可行解决方案如下: 1.暂停当前播放器——你可以通过audio.addEventListener('pause', yourFunction);钩住播放器的暂停事件 2.设置源为空-audio.src = ""; 3.加载src - audio.load(); 4. 移除整个音频元素 5. 插入一个没有定义源的新 HTML5 音频元素 6. 设置源(最初存在的源) - audio.src = "old source url 7. 重新挂钩暂停事件 - audio.addEventListener('pause', current-function);

ios 需要完全注入新的 HTML5 音频播放器。在我的情况下,只需重置 src 然后加载它就会导致播放器“自动播放”...

对于懒人(包括 jQuery):

var audio = $("audio").get(0);
audio.pause(0);
var tmp = audio.src;
audio.src = "";
audio.load();
$("audio").remove();

$("#audio-player").html("<audio controls preload='none'></audio>");<br>
audio = $("audio").get(0);
audio.src = tmp;
audio.addEventListener('pause', current-function);

按下暂停键会导致您的访问者丢失音频/视频文件中的当前位置,并且会重新开始。我没有解决这个问题的办法。再说一次,如果您正在处理直播,这个解决方案应该没问题。

希望这会有所帮助。

【讨论】:

为什么不将当前时间存储在一个临时变量中,当用户点击播放按钮时,您将音频播放器设置为该值? 你确实可以这样做,但我开发这个是为了卸载直播。在您按下停止的位置拾取实时流有点毫无意义;)但对于非常大的文件,这绝对是我可以添加的一个非常好的点。 这是一个糟糕的解决方案,因为它会抛出“错误”事件以尝试加载当前网页(即127.0.0.1),从而产生额外的人为负载。我试过nullundefined 但这些只是添加到当前页面的路径。如果您不关心错误,使用src="about:blank" 更有意义。 @ArturBodera 这是唯一的解决方案。该错误是播放器不支持任何“停止”功能的不幸副作用。这就是需要卸载资源的原因。在 HTML5 音频元素支持此功能之前,我建议将此作为一种解决方法。不作为永久解决方案。您描述的问题可以通过在引发错误的行周围放置try catch 来解决。 @ArturBodera 你确实是对的。尝试捕获不起作用。我会将 about:blank 添加到原始帖子中。我快速浏览了一下,该错误仅发生在 FF 中,而不发生在 Chrome 中。据我所知,两种浏览器都“接受”不同的方法。如果您只是重新加载(使用相同的资源),FF 会很高兴。这将停止浏览器下载资源。 Chrome 不介意空资源。尚未测试其他浏览器,但我会添加这些注释。感谢您的评论。【参考方案2】:

使用 preload="none",这就是我在暂停视频后强制中止缓冲,然后使用 jQuery 在暂停位置恢复播放的方式。

<video id="video_el" src="<video_url>" preload="none" controls="controls" />    

<script>
jQuery(function() 

  var video = jQuery('video').get(0);

  video.addEventListener('pause',function()
     var tmp_src = video.src;
     var playtime = video.currentTime;
     video.src = '';
     video.load();
     video.src = tmp_src;
     video.currentTime = playtime;
  );

);
</script>

【讨论】:

【参考方案3】:

关键步骤似乎是在调用load() 之前将src 设置为空白值。我已经成功地这样做了:

var wasPlaying = !audioPlayer.paused;
audioPlayer.currentTime = 0.0; // Optional -- can be left out for pause
audioPlayer.pause();

if (wasPlaying)  // This prevents the browser from trying to load the entire source
    audioPlayer.load();

在 Win10 上的 Chrome 和 Firefox 中,这会触发一个中止事件。在我的特定情况下,这需要关闭本来会无限期保持打开的套接字,这导致在同一页面上使用多个播放器时达到每个服务器的六个连接限制。

【讨论】:

【参考方案4】:

实际上,您可以通过将 src 属性设置为带有一些参数的 php/aspx 文件来执行相同的操作,以读取文件内容并将数据检索为等效类型(例如,Content-Type: video/mp4)。但它在 IE 11 中不起作用(真是令人惊讶:D),那么您需要为这个华丽的浏览器执行上述技巧。

使用这个...

<video id="v1" preload="none">
  <source src="video.php?id=24" type="video/mp4">
</video>

而不是这个...

<video id="v2" preload="none">
  <source src="video-24.mp4" type="video/mp4">
</video>

一个缺点是您无法确定视频的完整长度,但要解决这个问题,这个问题并不大,您可以将这个值存储在您的数据库中,或者再做一个小技巧。

我已经使用 Chrome 32、Firefox 26、Opera 18 和 IE 11 测试了以下脚本

setInterval(function() 
    var r = [];

    try 
        r.push(v1.buffered.end(0));
     catch(e) 
        r.push('nahh');
    ;

    try 
        r.push(v2.buffered.end(0));
     catch(e) 
        r.push('second nahh');
    ;

    console.log(r.join(', '));
, 500);

在我的本地主机测试中...

Firefox 26 按下播放后,它总是缓冲整个文件。

IE 11(考虑到src="video-24.mp4",因为另一个不起作用)按下播放后,它总是逐块缓冲文件,即使它被暂停并完全忽略preload="none"属性。

Chrome 32 完美运行(Opera 18 也是如此)。

【讨论】:

【参考方案5】:

您还可以将 src 更改为包含一秒钟静音的 mp3。比用新的 src 调用 play 函数。 随着新 mp3 的加载,流的缓冲停止。

var audio = document.getElementById("audioradio");
audio.src = "/sound/pause.mp3";
audio.play();
&lt;audio style="display: none;" id="audioradio" src="/sound/pause.mp3" preload="none"&gt;&lt;/audio&gt;

仅在 Firefox 中测试!

【讨论】:

以上是关于HTML5 视频:强制中止缓冲的主要内容,如果未能解决你的问题,请参考以下文章

我们如何强制 html 播放 100% 缓冲音频或视频?

仅在缓冲完整视频后才开始播放 HTML5 视频

HTML5 视频缓冲,尽管等待 `canplaythrough` 事件到 `play()`

Youtube 的 HTML5 视频播放器如何控制缓冲?

有没有办法知道 HTML5 视频初始缓冲区百分比的 Javascript 百分比?

HTML5 视频卡顿/运行不流畅/缓冲和预加载