HTML5视频:强制中止缓冲

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视频元素的缓冲。

谢谢!

5个回答

64

好的,最近几天我一直在努力解决这个问题。
以下是我的分析和解决方案:

简而言之,我试图解决的问题:
我发现当播放器暂停时(完全不会,甚至在合理的时间后),HTML5播放器不会停止下载。由于我正在处理24/7音频流并开发移动网站,我意识到如果访问者离开网站打开,这远非最佳选择 - 尽管我认为我可能会“忽略”这个问题让一些电信公司非常高兴...
只是为了澄清,我真的不关心固定长度的文件。完成文件的下载大多数时间是浏览在线资源所必需的功能(考虑慢速连接),因此不是我要防止的东西。

分析:
HTML5音频元素没有stop()函数,也没有选项可以设置允许缓冲的数据量,或者一种说你想让元素停止缓冲的方法 - 不要将其与'preload'功能混淆,这仅适用于单击播放按钮之前的元素。
我不知道为什么如此,以及为什么这些关键功能在应该使移动电话网络开发更好和更标准化的标准中未实现。如果有人能向我解释为什么没有实施这些关键功能,我会很乐意了解。

解决方案:
我找到的唯一有效的解决方案是在音频元素中实现(类似)停止功能:
1. 暂停当前播放器 - 您可以通过audio.addEventListener('pause',yourFunction)挂钩播放器上的暂停事件;
2. 将来源设置为空 - audio.src =“”;
3. 加载src - audio.load();
4. 删除整个音频元素
5. 插入一个新的HTML5音频元素而不定义源
6. 设置源(最初存在的源)- audio.src ="旧源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);

按下暂停按钮会导致您的访问者失去音频/视频文件中当前的位置,并且文件将重新开始。我对此问题没有解决方案。但是,如果您正在处理实时流,则这个解决方案应该是可行的。

希望这可以帮到您。


6
为什么不在一个临时变量中存储当前时间,当用户单击播放按钮时,将音频播放器设置为该值? - franzlorenzon
3
确实可以这样做,但我开发这个是为了卸载直播流。在按下停止键的位置拾取直播流有点无意义;但对于非常大的文件来说,这确实是一个非常好的建议,我可以添加这个功能。 - Ruben
@ArturBodera 这是唯一的解决方案。错误是播放器不支持任何“停止”功能的不幸副作用。这就是为什么需要卸载资源的原因。在HTML5音频元素支持此功能之前,我建议采用此方法作为解决方法。并且你所描述的问题可以通过在抛出错误的行周围放置“try catch”来简单解决。 - Ruben
2
@ArturBodera,你说得没错。try catch不起作用。我会在原帖中添加about:blank。 我快速查看了一下,错误只发生在FF中,而不是Chrome中。据我所见,两个浏览器“接受”不同的方法。如果您只是重新加载(使用相同的资源),FF会很高兴。这将阻止浏览器下载资源。Chrome不介意空资源。还没有测试其他浏览器,但我会添加这些注释。感谢您的评论。 - Ruben
显示剩余3条评论

14

使用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>

“这应该被选择为正确答案 preload =“none””。 - Schnitter

1
关键步骤似乎是在调用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中,这会触发一个abort事件。在我的特定情况下,这是必需的,以关闭否则会无限期保持打开状态的套接字,这导致在同一页上使用多个播放器时达到每个服务器六个连接的限制。

0

实际上,您可以通过将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同样)。

0

你也可以将src更改为包含一秒静音的mp3文件。然后使用新的src调用play函数。 当新的mp3被加载时,流的缓冲停止。

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

仅在Firefox中测试!


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