Created
December 8, 2015 01:30
-
-
Save anonymous/ded5b96230ad0e886dab to your computer and use it in GitHub Desktop.
Buffering // source http://jsbin.com/wokoraz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Buffering</title> | |
<style> | |
.ranges { | |
height: 20px; | |
position: relative; | |
width: 400px; | |
} | |
.buffered { | |
background-color: #999; | |
} | |
.seekable { | |
background-color: #777; | |
} | |
.played { | |
background-color: #555; | |
} | |
.range { | |
position: absolute; | |
display: block; | |
top: 0; | |
bottom: 0; | |
} | |
.buffered .range { | |
background-color: #595; | |
} | |
.seekable .range { | |
background: #995; | |
} | |
.played .range { | |
background: #955; | |
} | |
.track { | |
display: block; | |
cursor: pointer; | |
background-color: white; | |
padding-left: 1em; | |
} | |
</style> | |
</head> | |
<body> | |
<p>In Safari you will see a video of animals that contains 2 metadata cue points. Browsers that do not support HLS playback will fallback to an mp4 that starts with an animated title "global timoto". There are no cues there. Open in Safari.</p> | |
<video id="media" preload autoplay controls> | |
<!-- This source contains valid HLS MPEG-2 Transport ID3 --> | |
<source src="http://playertest.longtailvideo.com/adaptive/wowzaid3/playlist.m3u8" type="application/x-mpegURL"> | |
!-- This source DOES NOT cotain valid HLS MPEG-2 Transport ID3 --> | |
<!-- | |
source src="http://playertest.longtailvideo.com/adaptive/redbull/playlist.m3u8" type="application/x-mpegURL" | |
--> | |
<source src="http://content.bitsontherun.com/videos/w5VkaqJ1-393434.mp4 " type="video/mp4"> | |
</video> | |
<div> | |
<span>buffered: </span> | |
<span id="buffered-start"></span>-<span id="buffered-end"></span> | |
<span>of: </span> | |
<span id="buffered-count"></span> | |
</div> | |
<div class="buffered ranges"> | |
<span id="buffered-range-0" class="range"></span> | |
</div> | |
<div> | |
<span>seekable: </span> | |
<span id="seekable-start"></span>-<span id="seekable-end"></span> | |
<span>of: </span> | |
<span id="seekable-count"></span> | |
</div> | |
<div class="seekable ranges"> | |
<span id="seekable-range-0" class="range"></span> | |
</div> | |
<div> | |
<span>played: </span> | |
<span id="played-start"></span>-<span id="played-end"></span> | |
<span>of: </span> | |
<span id="played-count"></span> | |
</div> | |
<div class="played ranges"> | |
<span id="played-range-0" class="range"></span> | |
</div> | |
<div> | |
<span>currentTime: </span><span id="current-time"></span> | |
</div> | |
<div> | |
<span>duration: </span><span id="duration"></span> | |
</div> | |
<div> | |
<div> | |
<span>seekable duration: </span><span id="seekable-duration"></span> | |
</div> | |
<span>ranges start to end: </span><span id="ranges-start"></span>-<span id="ranges-end"></span> | |
</div> | |
<button id="seek-button">seek</button> to <input id="seek-time"></input> | |
<div> | |
<span>video tracks: </span><span id="video-track-count"></span> | |
</div> | |
<div> | |
<span>audio tracks: </span><span id="audio-track-count"></span> | |
</div> | |
<div> | |
<span>text tracks: </span><span id="text-track-count"></span> | |
</div> | |
</html> | |
<script id="jsbin-javascript"> | |
window.onload = function(){ | |
var el = document.getElementById.bind(document); | |
var create = function(name, id, classes) { | |
var element = document.createElement(name); | |
element.id = id; | |
element.className = classes || ''; | |
return element; | |
}; | |
var media = el('media'); | |
media.addEventListener('progress', update); | |
media.addEventListener('loadeddata', update); | |
//media.addEventListener('canplay', update); | |
//media.addEventListener('canplaythrough', update); | |
//media.addEventListener('playing', update); | |
media.addEventListener('timeupdate', update); | |
media.addEventListener('seeked', update); | |
el('seek-button').addEventListener('click', function() { | |
media.currentTime = parseFloat(el('seek-time').value) || 0; | |
}); | |
function update(e) { | |
var start = Infinity; | |
var end = 0; | |
if (media.buffered.length) { | |
start = Math.min(start, media.buffered.start(0)); | |
end = Math.max(end, media.buffered.end(media.buffered.length - 1)); | |
} | |
if (media.seekable.length) { | |
start = Math.min(start, media.seekable.start(0)); | |
end = Math.max(end, media.seekable.end(media.seekable.length - 1)); | |
el('seekable-duration').textContent = media.seekable.end(media.seekable.length - 1) - media.seekable.start(0); | |
} | |
if (media.played.length) { | |
start = Math.min(start, media.played.start(0)); | |
end = Math.max(end, media.played.end(media.played.length - 1)); | |
} | |
describeRange('buffered'); | |
describeRange('seekable'); | |
describeRange('played'); | |
drawRange('buffered', start, end); | |
drawRange('seekable', start, end); | |
drawRange('played', start, end); | |
el('current-time').textContent = media.currentTime; | |
el('duration').textContent = media.duration; | |
el('ranges-start').textContent = start; | |
el('ranges-end').textContent = end; | |
listTracks('video'); | |
listTracks('audio'); | |
listTracks('text'); | |
} | |
function listTracks(trackType) { | |
var tracksName = trackType + 'Tracks'; | |
var tracks = media[tracksName]; | |
if (tracks) { | |
var len = tracks.length; | |
el(trackType+'-track-count').textContent = len; | |
//tracks.onchange | |
//tracks.onaddtrack | |
//tracks.onremovetrack | |
for (var i=0; i<len; i++) { | |
var track = tracks.item(i); | |
var element = el(trackType+'-track-'+i); | |
if (!element) { | |
element = create('span', trackType+'-track-'+i, 'track'); | |
el(trackType+'-track-count').appendChild(element); | |
element.onclick = element.ontouchstart = (function(tr) { | |
return function() { | |
console.log(tr); | |
if (tr.enabled !== undefined) { | |
tr.enabled = true; | |
} else if (tr.selected !== undefined) { | |
tr.selected = true; | |
} else if (tr.mode) { | |
tr.mode = (tr.mode === 'showing') ? | |
'hidden' : (tr.mode === 'hidden' ? 'disabled': 'showing'); | |
} | |
}; | |
})(track); | |
// enable metadata tracks | |
if (track.kind === 'metadata') { | |
track.mode = 'showing'; | |
} | |
} | |
element.textContent = JSON.stringify({ | |
id: track.id || undefined, | |
kind: track.kind, | |
language: track.language || undefined, | |
label: track.label || undefined, | |
mode: track.mode, | |
enabled: track.enabled, | |
selected: track.selected, | |
cues: track.cues ? ([track.cues.length, track.cues]) : undefined | |
}, null, 1).replace(/"|}|{/g, ''); | |
} | |
} else { | |
el(trackType+'-track-count').textContent = 'unknown'; | |
} | |
} | |
function describeRange(rangesName) { | |
el(rangesName+'-count').textContent = media[rangesName].length; | |
if (media[rangesName].length) { | |
el(rangesName+'-start').textContent = media[rangesName].start(media[rangesName].length - 1); | |
el(rangesName+'-end').textContent = media[rangesName].end(media[rangesName].length - 1); | |
} | |
} | |
function drawRange(rangesName, start, end) { | |
var len = media[rangesName].length; | |
if (len) { | |
var rangeSize = end - start; | |
for (var i=0; i<len; i++) { | |
var a = media[rangesName].start(i) - start; | |
var b = media[rangesName].end(i) - start; | |
var element = el(rangesName+'-range-'+i); | |
if (!element) { | |
element = create('span', rangesName+'-range-'+i, 'range'); | |
el(rangesName+'-range-0').parentNode.appendChild(element); | |
} | |
element.style.left = ''+(a*100/rangeSize)+'%'; | |
element.style.right = ''+(100-(b*100/rangeSize))+'%'; | |
} | |
} | |
} | |
}; | |
</script> | |
<script id="jsbin-source-javascript" type="text/javascript">window.onload = function(){ | |
var el = document.getElementById.bind(document); | |
var create = function(name, id, classes) { | |
var element = document.createElement(name); | |
element.id = id; | |
element.className = classes || ''; | |
return element; | |
}; | |
var media = el('media'); | |
media.addEventListener('progress', update); | |
media.addEventListener('loadeddata', update); | |
//media.addEventListener('canplay', update); | |
//media.addEventListener('canplaythrough', update); | |
//media.addEventListener('playing', update); | |
media.addEventListener('timeupdate', update); | |
media.addEventListener('seeked', update); | |
el('seek-button').addEventListener('click', function() { | |
media.currentTime = parseFloat(el('seek-time').value) || 0; | |
}); | |
function update(e) { | |
var start = Infinity; | |
var end = 0; | |
if (media.buffered.length) { | |
start = Math.min(start, media.buffered.start(0)); | |
end = Math.max(end, media.buffered.end(media.buffered.length - 1)); | |
} | |
if (media.seekable.length) { | |
start = Math.min(start, media.seekable.start(0)); | |
end = Math.max(end, media.seekable.end(media.seekable.length - 1)); | |
el('seekable-duration').textContent = media.seekable.end(media.seekable.length - 1) - media.seekable.start(0); | |
} | |
if (media.played.length) { | |
start = Math.min(start, media.played.start(0)); | |
end = Math.max(end, media.played.end(media.played.length - 1)); | |
} | |
describeRange('buffered'); | |
describeRange('seekable'); | |
describeRange('played'); | |
drawRange('buffered', start, end); | |
drawRange('seekable', start, end); | |
drawRange('played', start, end); | |
el('current-time').textContent = media.currentTime; | |
el('duration').textContent = media.duration; | |
el('ranges-start').textContent = start; | |
el('ranges-end').textContent = end; | |
listTracks('video'); | |
listTracks('audio'); | |
listTracks('text'); | |
} | |
function listTracks(trackType) { | |
var tracksName = trackType + 'Tracks'; | |
var tracks = media[tracksName]; | |
if (tracks) { | |
var len = tracks.length; | |
el(trackType+'-track-count').textContent = len; | |
//tracks.onchange | |
//tracks.onaddtrack | |
//tracks.onremovetrack | |
for (var i=0; i<len; i++) { | |
var track = tracks.item(i); | |
var element = el(trackType+'-track-'+i); | |
if (!element) { | |
element = create('span', trackType+'-track-'+i, 'track'); | |
el(trackType+'-track-count').appendChild(element); | |
element.onclick = element.ontouchstart = (function(tr) { | |
return function() { | |
console.log(tr); | |
if (tr.enabled !== undefined) { | |
tr.enabled = true; | |
} else if (tr.selected !== undefined) { | |
tr.selected = true; | |
} else if (tr.mode) { | |
tr.mode = (tr.mode === 'showing') ? | |
'hidden' : (tr.mode === 'hidden' ? 'disabled': 'showing'); | |
} | |
}; | |
})(track); | |
// enable metadata tracks | |
if (track.kind === 'metadata') { | |
track.mode = 'showing'; | |
} | |
} | |
element.textContent = JSON.stringify({ | |
id: track.id || undefined, | |
kind: track.kind, | |
language: track.language || undefined, | |
label: track.label || undefined, | |
mode: track.mode, | |
enabled: track.enabled, | |
selected: track.selected, | |
cues: track.cues ? ([track.cues.length, track.cues]) : undefined | |
}, null, 1).replace(/"|}|{/g, ''); | |
} | |
} else { | |
el(trackType+'-track-count').textContent = 'unknown'; | |
} | |
} | |
function describeRange(rangesName) { | |
el(rangesName+'-count').textContent = media[rangesName].length; | |
if (media[rangesName].length) { | |
el(rangesName+'-start').textContent = media[rangesName].start(media[rangesName].length - 1); | |
el(rangesName+'-end').textContent = media[rangesName].end(media[rangesName].length - 1); | |
} | |
} | |
function drawRange(rangesName, start, end) { | |
var len = media[rangesName].length; | |
if (len) { | |
var rangeSize = end - start; | |
for (var i=0; i<len; i++) { | |
var a = media[rangesName].start(i) - start; | |
var b = media[rangesName].end(i) - start; | |
var element = el(rangesName+'-range-'+i); | |
if (!element) { | |
element = create('span', rangesName+'-range-'+i, 'range'); | |
el(rangesName+'-range-0').parentNode.appendChild(element); | |
} | |
element.style.left = ''+(a*100/rangeSize)+'%'; | |
element.style.right = ''+(100-(b*100/rangeSize))+'%'; | |
} | |
} | |
} | |
};</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
window.onload = function(){ | |
var el = document.getElementById.bind(document); | |
var create = function(name, id, classes) { | |
var element = document.createElement(name); | |
element.id = id; | |
element.className = classes || ''; | |
return element; | |
}; | |
var media = el('media'); | |
media.addEventListener('progress', update); | |
media.addEventListener('loadeddata', update); | |
//media.addEventListener('canplay', update); | |
//media.addEventListener('canplaythrough', update); | |
//media.addEventListener('playing', update); | |
media.addEventListener('timeupdate', update); | |
media.addEventListener('seeked', update); | |
el('seek-button').addEventListener('click', function() { | |
media.currentTime = parseFloat(el('seek-time').value) || 0; | |
}); | |
function update(e) { | |
var start = Infinity; | |
var end = 0; | |
if (media.buffered.length) { | |
start = Math.min(start, media.buffered.start(0)); | |
end = Math.max(end, media.buffered.end(media.buffered.length - 1)); | |
} | |
if (media.seekable.length) { | |
start = Math.min(start, media.seekable.start(0)); | |
end = Math.max(end, media.seekable.end(media.seekable.length - 1)); | |
el('seekable-duration').textContent = media.seekable.end(media.seekable.length - 1) - media.seekable.start(0); | |
} | |
if (media.played.length) { | |
start = Math.min(start, media.played.start(0)); | |
end = Math.max(end, media.played.end(media.played.length - 1)); | |
} | |
describeRange('buffered'); | |
describeRange('seekable'); | |
describeRange('played'); | |
drawRange('buffered', start, end); | |
drawRange('seekable', start, end); | |
drawRange('played', start, end); | |
el('current-time').textContent = media.currentTime; | |
el('duration').textContent = media.duration; | |
el('ranges-start').textContent = start; | |
el('ranges-end').textContent = end; | |
listTracks('video'); | |
listTracks('audio'); | |
listTracks('text'); | |
} | |
function listTracks(trackType) { | |
var tracksName = trackType + 'Tracks'; | |
var tracks = media[tracksName]; | |
if (tracks) { | |
var len = tracks.length; | |
el(trackType+'-track-count').textContent = len; | |
//tracks.onchange | |
//tracks.onaddtrack | |
//tracks.onremovetrack | |
for (var i=0; i<len; i++) { | |
var track = tracks.item(i); | |
var element = el(trackType+'-track-'+i); | |
if (!element) { | |
element = create('span', trackType+'-track-'+i, 'track'); | |
el(trackType+'-track-count').appendChild(element); | |
element.onclick = element.ontouchstart = (function(tr) { | |
return function() { | |
console.log(tr); | |
if (tr.enabled !== undefined) { | |
tr.enabled = true; | |
} else if (tr.selected !== undefined) { | |
tr.selected = true; | |
} else if (tr.mode) { | |
tr.mode = (tr.mode === 'showing') ? | |
'hidden' : (tr.mode === 'hidden' ? 'disabled': 'showing'); | |
} | |
}; | |
})(track); | |
// enable metadata tracks | |
if (track.kind === 'metadata') { | |
track.mode = 'showing'; | |
} | |
} | |
element.textContent = JSON.stringify({ | |
id: track.id || undefined, | |
kind: track.kind, | |
language: track.language || undefined, | |
label: track.label || undefined, | |
mode: track.mode, | |
enabled: track.enabled, | |
selected: track.selected, | |
cues: track.cues ? ([track.cues.length, track.cues]) : undefined | |
}, null, 1).replace(/"|}|{/g, ''); | |
} | |
} else { | |
el(trackType+'-track-count').textContent = 'unknown'; | |
} | |
} | |
function describeRange(rangesName) { | |
el(rangesName+'-count').textContent = media[rangesName].length; | |
if (media[rangesName].length) { | |
el(rangesName+'-start').textContent = media[rangesName].start(media[rangesName].length - 1); | |
el(rangesName+'-end').textContent = media[rangesName].end(media[rangesName].length - 1); | |
} | |
} | |
function drawRange(rangesName, start, end) { | |
var len = media[rangesName].length; | |
if (len) { | |
var rangeSize = end - start; | |
for (var i=0; i<len; i++) { | |
var a = media[rangesName].start(i) - start; | |
var b = media[rangesName].end(i) - start; | |
var element = el(rangesName+'-range-'+i); | |
if (!element) { | |
element = create('span', rangesName+'-range-'+i, 'range'); | |
el(rangesName+'-range-0').parentNode.appendChild(element); | |
} | |
element.style.left = ''+(a*100/rangeSize)+'%'; | |
element.style.right = ''+(100-(b*100/rangeSize))+'%'; | |
} | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment