Html HTML5 视频:强制中止缓冲
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4071872/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HTML5 Video: Force abort of buffering
提问by Brad Swerdfeger
How does one force an abort event on an HTML5 video? I have an overlay, where, when I close it, the video should pause playing and then stop buffering. However, my internet connection continues to go nuts. Oh, I'm using Chrome 7.0.5 on Mac OS X 10.6.
如何在 HTML5 视频上强制中止事件?我有一个叠加层,当我关闭它时,视频应该暂停播放然后停止缓冲。但是,我的互联网连接继续发疯。哦,我在 Mac OS X 10.6 上使用 Chrome 7.0.5。
I've tried a couple of things -- none of them have worked:
我已经尝试了几件事——它们都没有奏效:
(For those unfamiliar with XUI, x$ is like the jQuery wrapping function)
(对于不熟悉 XUI 的人,x$ 就像 jQuery 包装函数)
First, dispatching an abort HTML Event:
首先,调度 abort HTML 事件:
var videoEl = x$('#video_el')[0];
videoEl.pause();
var evObj = document.createEvent('HTMLEvents');
evObj.initEvent('abort', false, false);
videoEl.dispatchEvent(evObj);
Next, changing the src and then forcing a load:
接下来,更改 src 然后强制加载:
var videoEl = x$('#video_el')[0];
videoEl.pause();
videoEl.src = "";
videoEl.load(); //tried with and without this step
EDIT: My video element looks something like this:
编辑:我的视频元素如下所示:
<video id="video_el" src="<video_url>" preload="none" controls="controls" />
Again, none of these work. Anyone ran into this problem before? Any suggestions?
同样,这些都不起作用。以前有人遇到过这个问题吗?有什么建议?
In summary, I am trying to force an HTML5 video element to stop buffering.
总之,我试图强制 HTML5 视频元素停止缓冲。
Thanks!
谢谢!
回答by Ruben
Ok, so for the last few day's I've really been struggling with this issue.
Here is my analysis and solution:
好的,所以在过去的几天里,我真的一直在为这个问题而苦苦挣扎。
这是我的分析和解决方案:
In short the problem I tried to solve:
I noticed that the HTML5 player does not stop downloading when the player is paused (at all, not even after a reasonable amount of time). Working with a 24/7 audio stream and developing a mobile website I realized that this is far from optimal for my visitors considering the high data usage if they leave the site open - although I do think I would make some telco's very happy by "overlooking" this issue...
Just to clarify, I don't really care about files with a fixed length. Downloading the complete file is most of the time a functionality required for viewing online resources (think slow connection) so not something I tried to prevent.
简而言之,我试图解决的问题是:
我注意到 HTML5 播放器在播放器暂停时不会停止下载(根本没有,甚至在一段合理的时间后也不会)。使用 24/7 音频流并开发一个移动网站,我意识到这对于我的访问者来说远非最佳,因为如果他们让网站保持打开状态,那么考虑到高数据使用量 - 尽管我确实认为我会让一些电信公司非常高兴通过“忽略“这个问题......
只是为了澄清,我并不真正关心固定长度的文件。下载完整文件在大多数情况下是查看在线资源所需的功能(想想慢速连接),所以不是我试图阻止的。
Analysis:
The HTML5 audio element does not have a stop() function, nor does it have an option where you can set the amount of data that it is allowed to buffer, or a way of saying you want the element to stop buffering - Don't confuse this with the 'preload' function, this only applies to the element before the play button is clicked.
I have no clue why this is and why this functionality is not available. If anyone can explain to me why these crucial functions are not implemented in a standard that should make web development for mobile phones better and more standardized I would love to know.
分析:
HTML5 音频元素没有 stop() 函数,也没有可以设置允许缓冲的数据量的选项,或者说你希望元素停止缓冲的方式 - Don不要将此与“预加载”功能混淆,这仅适用于单击播放按钮之前的元素。
我不知道为什么会这样以及为什么此功能不可用。如果有人能向我解释为什么这些关键功能没有在一个标准中实现,该标准应该使手机的 Web 开发更好和更标准化,我很想知道。
Solution:
The only working solution I found to implement a (sort of) stop function in your audio element is as follows:
1. Pause the current player - you can hook the pause event on the player via audio.addEventListener('pause', yourFunction);
2. Set the source to empty - audio.src = "";
3. Load the src - audio.load();
4. Remove the whole audio element
5. Insert a new HTML5 audio element without the source defined
6. Set the source (the source that was there in the first place) - audio.src = "old source url
7. Rehook the pause event - audio.addEventListener('pause', current-function);
解决方案:
我发现在音频元素中实现(某种)停止功能的唯一可行解决方案如下:
1. 暂停当前播放器 - 您可以通过 audio.addEventListener('pause',你的函数);
2.设置源为空——audio.src = "";
3. 加载 src - audio.load();
4. 删除整个音频元素
5. 插入一个没有定义源的新 HTML5 音频元素
6. 设置源(首先存在的源) - audio.src = "old source url
7. 重新挂起暂停事件- audio.addEventListener('pause', current-function);
Completely injecting a new HTML5 audio player is necessary for iOS. Simply resetting the src and then loading it causes the player to 'autoplay' in my case...
iOS 需要完全注入新的 HTML5 音频播放器。简单地重置 src 然后加载它会导致播放器在我的情况下“自动播放”......
For the lazy people (includes jQuery):
对于懒惰的人(包括 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);
Pressing pause will cause your visitor to lose there current location in the audio/video file and it will start again. I have no solution for this issue. Then again, if you are dealing with a live stream this solution should be fine.
按暂停将导致您的访问者丢失音频/视频文件中的当前位置,并且它将重新开始。我对这个问题没有解决方案。再说一次,如果您正在处理实时流,则此解决方案应该没问题。
Hope this helps.
希望这可以帮助。
回答by Eric Leroy
With preload="none", This is how I force aborted the buffering after pausing the video, and then resumed playback at the paused location using jQuery.
使用 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>
回答by Dinfinity
The key step seems to be to notset src
to a blank value before calling load()
. I've had success doing it like this:
关键的一步似乎是没有设置src
之前调用为空值load()
。我已经成功地这样做了:
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();
}
In both Chrome and Firefox on Win10, this fires an abort event. In my specific case this was required to close the sockets that would otherwise remain open indefinitely, which led to hitting the six connections per server limit with multiple players being used on the same page.
在 Win10 上的 Chrome 和 Firefox 中,这会触发中止事件。在我的特定情况下,需要关闭套接字,否则这些套接字将无限期地保持打开状态,这导致在同一页面上使用多个播放器时,每个服务器的连接数达到 6 个限制。
回答by IchEben
You could also change the src to a mp3 that contains one second of silence. Than call the play function with the new src. As the new mp3 is loaded the buffering of the stream stops.
您还可以将 src 更改为包含一秒钟静音的 mp3。比用新的 src 调用播放函数。随着新 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>
Testet in Firefox only!
仅在 Firefox 中测试!
回答by thejh
See here: http://dev.w3.org/html5/spec/video.html#attr-media-preload
见这里:http: //dev.w3.org/html5/spec/video.html#attr-media-preload
Maybe you could set preload
to none
?
也许你可以设置preload
为none
?
In case that doesn't work: Could you fetch its attributes, remove it, insert a new video element and give that element the saved attributes?
如果这不起作用:您能否获取其属性,将其删除,插入一个新的视频元素并为该元素提供已保存的属性?
回答by Nevershowmyface
Actually you can do the same thing by setting the src attribute as a php/aspx file with some params to read the file content and retrieve the data as the equivalent type(e.g., Content-Type: video/mp4
). BUT it does't work in IE 11 (what a surprise :D), then you'll need to do the trick above just for this gorgeous browser.
实际上,您可以通过将 src 属性设置为带有一些参数的 php/aspx 文件来执行相同的操作,以读取文件内容并将数据检索为等效类型(例如,Content-Type: video/mp4
)。但是它在 IE 11 中不起作用(多么令人惊讶:D),那么您需要为这个华丽的浏览器执行上述技巧。
Use this...
用这个...
<video id="v1" preload="none">
<source src="video.php?id=24" type="video/mp4">
</video>
Instead of this...
而不是这个...
<video id="v2" preload="none">
<source src="video-24.mp4" type="video/mp4">
</video>
As a drawback you won't be able to determine the full length of the video, but to solve this problem, that's not soo big, you could store this value in your database or just make another little trick.
作为一个缺点,您将无法确定视频的全长,但要解决这个问题,这并不是很大,您可以将此值存储在您的数据库中,或者只是制作另一个小技巧。
I've tested using Chrome 32, Firefox 26, Opera 18 and IE 11 the following script
我已经使用 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);
In my localhosts tests...
在我的本地主机测试中...
Firefox 26 After you had pressed play, it ALWAYS buffered the full file.
Firefox 26 在您按下播放键后,它总是会缓冲整个文件。
IE 11 (considering src="video-24.mp4"
, cuz the other don't work) After you had pressed play, it ALWAYS buffered the file chunk by chunk even if it was paused and completly ignores the preload="none"
attribute.
IE 11(考虑src="video-24.mp4"
,因为另一个不起作用)按下播放后,它总是逐块缓冲文件,即使它被暂停并完全忽略该preload="none"
属性。
Chrome 32 Works perfectly (same for Opera 18).
Chrome 32 完美运行(Opera 18 相同)。