HTML5 Video: Force abort of buffering
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.
I've tried a couple of things -- none of them have worked:
(For those unfamiliar with XUI, x$ is like the jQuery wrapping function)
First, dispatching an abort HTML Event:
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:
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.
Thanks!
Solution 1:
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.
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.
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);
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...
For the lazy people (includes 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.
Solution 2:
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.
<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>