You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
768 lines
22 KiB
768 lines
22 KiB
/* global window document */ |
|
/* eslint-disable vars-on-top, no-var, object-shorthand, no-console */ |
|
(function (window) { |
|
var representationsEl = document.getElementById('representations'); |
|
|
|
representationsEl.addEventListener('change', function () { |
|
var selectedIndex = representationsEl.selectedIndex; |
|
|
|
if (!selectedIndex || selectedIndex < 1 || !window.vhs) { |
|
return; |
|
} |
|
var selectedOption = |
|
representationsEl.options[representationsEl.selectedIndex]; |
|
|
|
if (!selectedOption) { |
|
return; |
|
} |
|
|
|
var id = selectedOption.value; |
|
|
|
window.vhs.representations().forEach(function (rep) { |
|
rep.playlist.disabled = rep.id !== id; |
|
}); |
|
|
|
window.mpc.fastQualityChange_(); |
|
}); |
|
var isManifestObjectType = function (url) { |
|
return /application\/vnd\.videojs\.vhs\+json/.test(url); |
|
}; |
|
var hlsOptGroup = document.querySelector('[label="hls"]'); |
|
var dashOptGroup = document.querySelector('[label="dash"]'); |
|
var drmOptGroup = document.querySelector('[label="drm"]'); |
|
var liveOptGroup = document.querySelector('[label="live"]'); |
|
var llliveOptGroup = document.querySelector('[label="low latency live"]'); |
|
var manifestOptGroup = document.querySelector( |
|
'[label="json manifest object"]' |
|
); |
|
|
|
var sourceList; |
|
var hlsDataManifest; |
|
var dashDataManifest; |
|
|
|
var addSourcesToDom = function () { |
|
if (!sourceList || !hlsDataManifest || !dashDataManifest) { |
|
return; |
|
} |
|
|
|
sourceList.forEach(function (source) { |
|
var option = document.createElement('option'); |
|
|
|
option.innerText = source.name; |
|
option.value = source.uri; |
|
|
|
if (source.keySystems) { |
|
option.setAttribute( |
|
'data-key-systems', |
|
JSON.stringify(source.keySystems, null, 2) |
|
); |
|
} |
|
|
|
if (source.mimetype) { |
|
option.setAttribute('data-mimetype', source.mimetype); |
|
} |
|
|
|
if (source.features.indexOf('live') !== -1) { |
|
liveOptGroup.appendChild(option); |
|
} else if (source.mimetype === 'application/x-mpegurl') { |
|
hlsOptGroup.appendChild(option); |
|
} |
|
}); |
|
|
|
var hlsOption = document.createElement('option'); |
|
var dashOption = document.createElement('option'); |
|
|
|
dashOption.innerText = |
|
'Dash Manifest Object Test, does not survive page reload'; |
|
dashOption.value = `data:application/vnd.videojs.vhs+json,${dashDataManifest}`; |
|
hlsOption.innerText = |
|
'HLS Manifest Object Test, does not survive page reload'; |
|
hlsOption.value = `data:application/vnd.videojs.vhs+json,${hlsDataManifest}`; |
|
|
|
// manifestOptGroup.appendChild(hlsOption); |
|
// manifestOptGroup.appendChild(dashOption); |
|
}; |
|
|
|
var sourcesXhr = new window.XMLHttpRequest(); |
|
|
|
sourcesXhr.addEventListener('load', function () { |
|
sourceList = JSON.parse(sourcesXhr.responseText); |
|
addSourcesToDom(); |
|
}); |
|
sourcesXhr.open('GET', './scripts/sources.json'); |
|
sourcesXhr.send(); |
|
|
|
var hlsManifestXhr = new window.XMLHttpRequest(); |
|
|
|
hlsManifestXhr.addEventListener('load', function () { |
|
hlsDataManifest = hlsManifestXhr.responseText; |
|
addSourcesToDom(); |
|
}); |
|
hlsManifestXhr.open('GET', './scripts/hls-manifest-object.json'); |
|
hlsManifestXhr.send(); |
|
|
|
var dashManifestXhr = new window.XMLHttpRequest(); |
|
|
|
dashManifestXhr.addEventListener('load', function () { |
|
dashDataManifest = dashManifestXhr.responseText; |
|
addSourcesToDom(); |
|
}); |
|
dashManifestXhr.open('GET', './scripts/dash-manifest-object.json'); |
|
dashManifestXhr.send(); |
|
|
|
// all relevant elements |
|
var urlButton = document.getElementById('load-url'); |
|
var sources = document.getElementById('load-source'); |
|
var stateEls = {}; |
|
|
|
var getInputValue = function (el) { |
|
if ( |
|
el.type === 'url' || |
|
el.type === 'text' || |
|
el.nodeName.toLowerCase() === 'textarea' |
|
) { |
|
if (isManifestObjectType(el.value)) { |
|
return ''; |
|
} |
|
return encodeURIComponent(el.value); |
|
} else if (el.type === 'select-one') { |
|
return el.options[el.selectedIndex].value; |
|
} else if (el.type === 'checkbox') { |
|
return el.checked; |
|
} |
|
|
|
console.warn('unhandled input type ' + el.type); |
|
return ''; |
|
}; |
|
|
|
var setInputValue = function (el, value) { |
|
if ( |
|
el.type === 'url' || |
|
el.type === 'text' || |
|
el.nodeName.toLowerCase() === 'textarea' |
|
) { |
|
el.value = decodeURIComponent(value); |
|
} else if (el.type === 'select-one') { |
|
for (var i = 0; i < el.options.length; i++) { |
|
if (el.options[i].value === value) { |
|
el.options[i].selected = true; |
|
} |
|
} |
|
} else { |
|
// get the `value` into a Boolean. |
|
el.checked = JSON.parse(value); |
|
} |
|
}; |
|
|
|
var newEvent = function (name) { |
|
var event; |
|
|
|
if (typeof window.Event === 'function') { |
|
event = new window.Event(name); |
|
} else { |
|
event = document.createEvent('Event'); |
|
event.initEvent(name, true, true); |
|
} |
|
|
|
return event; |
|
}; |
|
|
|
// taken from video.js |
|
var getFileExtension = function (path) { |
|
var splitPathRe; |
|
var pathParts; |
|
|
|
if (typeof path === 'string') { |
|
splitPathRe = |
|
/^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]*?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i; |
|
pathParts = splitPathRe.exec(path); |
|
|
|
if (pathParts) { |
|
return pathParts.pop().toLowerCase(); |
|
} |
|
} |
|
|
|
return ''; |
|
}; |
|
|
|
var saveState = function () { |
|
var query = ''; |
|
|
|
if (!window.history.replaceState) { |
|
return; |
|
} |
|
|
|
Object.keys(stateEls).forEach(function (elName) { |
|
var symbol = query.length ? '&' : '?'; |
|
|
|
query += symbol + elName + '=' + getInputValue(stateEls[elName]); |
|
}); |
|
|
|
window.history.replaceState({}, 'vhs demo', query); |
|
}; |
|
|
|
window.URLSearchParams = |
|
window.URLSearchParams || |
|
function (locationSearch) { |
|
this.get = function (name) { |
|
var results = new RegExp('[?&]' + name + '=([^&#]*)').exec( |
|
locationSearch |
|
); |
|
|
|
return results ? decodeURIComponent(results[1]) : null; |
|
}; |
|
}; |
|
|
|
// eslint-disable-next-line |
|
var loadState = function () { |
|
var params = new window.URLSearchParams(window.location.search); |
|
|
|
return Object.keys(stateEls).reduce(function (acc, elName) { |
|
acc[elName] = |
|
typeof params.get(elName) !== 'object' |
|
? params.get(elName) |
|
: getInputValue(stateEls[elName]); |
|
return acc; |
|
}, {}); |
|
}; |
|
|
|
// eslint-disable-next-line |
|
var reloadScripts = function (urls, cb) { |
|
console.log('blah') |
|
var el = document.getElementById('reload-scripts'); |
|
|
|
if (!el) { |
|
el = document.createElement('div'); |
|
el.id = 'reload-scripts'; |
|
document.body.appendChild(el); |
|
} |
|
|
|
while (el.firstChild) { |
|
el.removeChild(el.firstChild); |
|
} |
|
|
|
var loaded = []; |
|
|
|
var checkDone = function () { |
|
if (loaded.length === urls.length) { |
|
cb(); |
|
} |
|
}; |
|
|
|
urls.forEach(function (url) { |
|
console.log(url) |
|
var script = document.createElement('script'); |
|
|
|
// scripts marked as defer will be loaded asynchronously but will be executed in the order they are in the DOM |
|
script.defer = true; |
|
// dynamically created scripts are async by default unless otherwise specified |
|
// async scripts are loaded asynchronously but also executed as soon as they are loaded |
|
// we want to load them in the order they are added therefore we want to turn off async |
|
script.async = false; |
|
script.src = url; |
|
script.onload = function () { |
|
loaded.push(url); |
|
checkDone(); |
|
}; |
|
el.appendChild(script); |
|
}); |
|
|
|
}; |
|
|
|
var regenerateRepresentations = function () { |
|
while (representationsEl.firstChild) { |
|
representationsEl.removeChild(representationsEl.firstChild); |
|
} |
|
|
|
var selectedIndex; |
|
|
|
window.vhs.representations().forEach(function (rep, i) { |
|
var option = document.createElement('option'); |
|
|
|
option.value = rep.id; |
|
option.innerText = JSON.stringify({ |
|
id: rep.id, |
|
videoCodec: rep.codecs.video, |
|
audioCodec: rep.codecs.audio, |
|
bandwidth: rep.bandwidth, |
|
heigth: rep.heigth, |
|
width: rep.width, |
|
}); |
|
|
|
if (window.mpc.media().id === rep.id) { |
|
selectedIndex = i; |
|
} |
|
|
|
representationsEl.appendChild(option); |
|
}); |
|
|
|
representationsEl.selectedIndex = selectedIndex; |
|
}; |
|
|
|
function getBuffered(buffered) { |
|
var bufferedText = ''; |
|
|
|
if (!buffered) { |
|
return bufferedText; |
|
} |
|
|
|
if (buffered.length) { |
|
bufferedText += buffered.start(0) + ' - ' + buffered.end(0); |
|
} |
|
for (var i = 1; i < buffered.length; i++) { |
|
bufferedText += ', ' + buffered.start(i) + ' - ' + buffered.end(i); |
|
} |
|
return bufferedText; |
|
} |
|
|
|
var setupSegmentMetadata = function (player) { |
|
// setup segment metadata |
|
var segmentMetadata = document.querySelector('#segment-metadata'); |
|
|
|
player.one('loadedmetadata', function () { |
|
var tracks = player.textTracks(); |
|
var segmentMetadataTrack; |
|
|
|
for (var i = 0; i < tracks.length; i++) { |
|
if (tracks[i].label === 'segment-metadata') { |
|
segmentMetadataTrack = tracks[i]; |
|
} |
|
} |
|
|
|
while (segmentMetadata.children.length) { |
|
segmentMetadata.removeChild(segmentMetadata.firstChild); |
|
} |
|
|
|
if (segmentMetadataTrack) { |
|
segmentMetadataTrack.addEventListener('cuechange', function () { |
|
var cues = segmentMetadataTrack.activeCues || []; |
|
|
|
let activeCue = segmentMetadataTrack.activeCues[0].value; |
|
|
|
try { |
|
const latency = |
|
(new Date().getTime() - activeCue.dateTimeObject.getTime()) / |
|
1000; |
|
document.getElementById('displayedSegmentLatency').innerHTML = |
|
latency; |
|
} catch (err) { |
|
console.error(err); |
|
} |
|
|
|
while (segmentMetadata.children.length) { |
|
segmentMetadata.removeChild(segmentMetadata.firstChild); |
|
} |
|
|
|
for (var j = 0; j < cues.length; j++) { |
|
var text = JSON.stringify(JSON.parse(cues[j].text), null, 2); |
|
var li = document.createElement('li'); |
|
var pre = document.createElement('pre'); |
|
|
|
pre.classList.add('border', 'rounded', 'p-2'); |
|
pre.textContent = text; |
|
li.appendChild(pre); |
|
segmentMetadata.appendChild(li); |
|
} |
|
}); |
|
} |
|
}); |
|
}; |
|
|
|
var setupPlayerStats = function (player) { |
|
player.on('dispose', () => { |
|
if (window.statsTimer) { |
|
window.clearInterval(window.statsTimer); |
|
window.statsTimer = null; |
|
} |
|
}); |
|
var currentTimeStat = document.querySelector('.current-time-stat'); |
|
var bufferedStat = document.querySelector('.buffered-stat'); |
|
var videoBufferedStat = document.querySelector('.video-buffered-stat'); |
|
var audioBufferedStat = document.querySelector('.audio-buffered-stat'); |
|
var seekableStartStat = document.querySelector('.seekable-start-stat'); |
|
var seekableEndStat = document.querySelector('.seekable-end-stat'); |
|
var videoBitrateState = document.querySelector('.video-bitrate-stat'); |
|
var measuredBitrateStat = document.querySelector('.measured-bitrate-stat'); |
|
var videoTimestampOffset = document.querySelector('.video-timestampoffset'); |
|
var audioTimestampOffset = document.querySelector('.audio-timestampoffset'); |
|
|
|
player.on('timeupdate', function () { |
|
currentTimeStat.textContent = player.currentTime().toFixed(1); |
|
}); |
|
|
|
window.statsTimer = window.setInterval(function () { |
|
var oldStart; |
|
var oldEnd; |
|
var seekable = player.seekable(); |
|
|
|
if (seekable && seekable.length) { |
|
oldStart = seekableStartStat.textContent; |
|
if (seekable.start(0).toFixed(1) !== oldStart) { |
|
seekableStartStat.textContent = seekable.start(0).toFixed(1); |
|
} |
|
oldEnd = seekableEndStat.textContent; |
|
if (seekable.end(0).toFixed(1) !== oldEnd) { |
|
seekableEndStat.textContent = seekable.end(0).toFixed(1); |
|
} |
|
} |
|
|
|
// buffered |
|
bufferedStat.textContent = getBuffered(player.buffered()); |
|
|
|
// exit early if no VHS |
|
if (!player.tech(true).vhs) { |
|
videoBufferedStat.textContent = ''; |
|
audioBufferedStat.textContent = ''; |
|
videoBitrateState.textContent = ''; |
|
measuredBitrateStat.textContent = ''; |
|
videoTimestampOffset.textContent = ''; |
|
audioTimestampOffset.textContent = ''; |
|
return; |
|
} |
|
|
|
videoBufferedStat.textContent = getBuffered( |
|
player.tech(true).vhs.masterPlaylistController_.mainSegmentLoader_ |
|
.sourceUpdater_.videoBuffer && |
|
player.tech(true).vhs.masterPlaylistController_.mainSegmentLoader_ |
|
.sourceUpdater_.videoBuffer.buffered |
|
); |
|
|
|
// demuxed audio |
|
var audioBuffer = getBuffered( |
|
player.tech(true).vhs.masterPlaylistController_.audioSegmentLoader_ |
|
.sourceUpdater_.audioBuffer && |
|
player.tech(true).vhs.masterPlaylistController_.audioSegmentLoader_ |
|
.sourceUpdater_.audioBuffer.buffered |
|
); |
|
|
|
// muxed audio |
|
if (!audioBuffer) { |
|
audioBuffer = getBuffered( |
|
player.tech(true).vhs.masterPlaylistController_.mainSegmentLoader_ |
|
.sourceUpdater_.audioBuffer && |
|
player.tech(true).vhs.masterPlaylistController_.mainSegmentLoader_ |
|
.sourceUpdater_.audioBuffer.buffered |
|
); |
|
} |
|
audioBufferedStat.textContent = audioBuffer; |
|
|
|
if ( |
|
player.tech(true).vhs.masterPlaylistController_.audioSegmentLoader_ |
|
.sourceUpdater_.audioBuffer |
|
) { |
|
audioTimestampOffset.textContent = |
|
player.tech( |
|
true |
|
).vhs.masterPlaylistController_.audioSegmentLoader_.sourceUpdater_.audioBuffer.timestampOffset; |
|
} else if ( |
|
player.tech(true).vhs.masterPlaylistController_.mainSegmentLoader_ |
|
.sourceUpdater_.audioBuffer |
|
) { |
|
audioTimestampOffset.textContent = |
|
player.tech( |
|
true |
|
).vhs.masterPlaylistController_.mainSegmentLoader_.sourceUpdater_.audioBuffer.timestampOffset; |
|
} |
|
|
|
if ( |
|
player.tech(true).vhs.masterPlaylistController_.mainSegmentLoader_ |
|
.sourceUpdater_.videoBuffer |
|
) { |
|
videoTimestampOffset.textContent = |
|
player.tech( |
|
true |
|
).vhs.masterPlaylistController_.mainSegmentLoader_.sourceUpdater_.videoBuffer.timestampOffset; |
|
} |
|
|
|
// bitrates |
|
var playlist = player.tech_.vhs.playlists.media(); |
|
|
|
if (playlist && playlist.attributes && playlist.attributes.BANDWIDTH) { |
|
videoBitrateState.textContent = |
|
(playlist.attributes.BANDWIDTH / 1024).toLocaleString(undefined, { |
|
maximumFractionDigits: 1, |
|
}) + ' kbps'; |
|
} |
|
if (player.tech_.vhs.bandwidth) { |
|
measuredBitrateStat.textContent = |
|
(player.tech_.vhs.bandwidth / 1024).toLocaleString(undefined, { |
|
maximumFractionDigits: 1, |
|
}) + ' kbps'; |
|
} |
|
}, 100); |
|
}; |
|
|
|
[ |
|
'debug', |
|
'autoplay', |
|
'muted', |
|
'fluid', |
|
'minified', |
|
'sync-workers', |
|
'liveui', |
|
'llhls', |
|
'url', |
|
'type', |
|
'buffer-water', |
|
'exact-manifest-timings', |
|
'pixel-diff-selector', |
|
'override-native', |
|
'preload', |
|
'mirror-source', |
|
].forEach(function (name) { |
|
stateEls[name] = document.getElementById(name); |
|
}); |
|
|
|
window.startDemo = function (cb) { |
|
var state = loadState(); |
|
|
|
Object.keys(state).forEach(function (elName) { |
|
setInputValue(stateEls[elName], state[elName]); |
|
}); |
|
|
|
Array.prototype.forEach.call(sources.options, function (s, i) { |
|
if (s.value === state.url) { |
|
sources.selectedIndex = i; |
|
} |
|
}); |
|
|
|
// stateEls that reload the player and scripts |
|
[ |
|
'mirror-source', |
|
'sync-workers', |
|
'preload', |
|
'llhls', |
|
'buffer-water', |
|
'override-native', |
|
'liveui', |
|
'pixel-diff-selector', |
|
'exact-manifest-timings', |
|
].forEach(function (name) { |
|
stateEls[name].addEventListener('change', function (event) { |
|
saveState(); |
|
|
|
stateEls.minified.dispatchEvent(newEvent('change')); |
|
}); |
|
}); |
|
|
|
stateEls.debug.addEventListener('change', function (event) { |
|
saveState(); |
|
window.videojs.log.level(event.target.checked ? 'debug' : 'info'); |
|
}); |
|
|
|
stateEls.minified.addEventListener('change', function (event) { |
|
// let urls = []; |
|
var urls = [].map(function (url) { |
|
return url + (event.target.checked ? '.min' : '') + '.js'; |
|
}); |
|
|
|
// if (stateEls['sync-workers'].checked) { |
|
// urls.push('dist/videojs-http-streaming-sync-workers.js'); |
|
// } else { |
|
urls.push( |
|
'https://vjs.zencdn.net/7.15.4/video.min.js', |
|
'https://cdn.jsdelivr.net/npm/@videojs/http-streaming@2.10.3/dist/videojs-http-streaming.min.js' |
|
); |
|
// } |
|
|
|
saveState(); |
|
|
|
if (window.player) { |
|
window.player.dispose(); |
|
delete window.player; |
|
} |
|
if (window.videojs) { |
|
delete window.videojs; |
|
} |
|
|
|
reloadScripts(urls, function () { |
|
console.log('reloadScripts') |
|
var player; |
|
var fixture = document.getElementById('player-fixture'); |
|
var videoEl = document.createElement('video-js'); |
|
|
|
videoEl.setAttribute('controls', ''); |
|
videoEl.setAttribute('preload', 'auto'); |
|
videoEl.setAttribute('autoplay', ''); |
|
videoEl.setAttribute('muted', ''); |
|
videoEl.setAttribute('fluid', 'true'); |
|
|
|
videoEl.className = 'vjs-default-skin'; |
|
fixture.appendChild(videoEl); |
|
|
|
player = window.player = window.videojs(videoEl, { |
|
html5: { |
|
vhs: { |
|
overrideNative: true, |
|
experimentalBufferBasedABR: getInputValue( |
|
stateEls['buffer-water'] |
|
), |
|
experimentalExactManifestTimings: getInputValue( |
|
stateEls['exact-manifest-timings'] |
|
), |
|
experimentalLeastPixelDiffSelector: getInputValue( |
|
stateEls['pixel-diff-selector'] |
|
), |
|
}, |
|
}, |
|
}); |
|
|
|
window.player = player; |
|
|
|
setupPlayerStats(player); |
|
setupSegmentMetadata(player); |
|
|
|
// save player muted state interation |
|
player.on('volumechange', function () { |
|
if (stateEls.muted.checked !== player.muted()) { |
|
stateEls.muted.checked = player.muted(); |
|
saveState(); |
|
} |
|
}); |
|
|
|
player.on('sourceset', function () { |
|
var source = player.currentSource(); |
|
|
|
if (source.keySystems) { |
|
var copy = JSON.parse(JSON.stringify(source.keySystems)); |
|
|
|
// have to delete pssh as it will often make keySystems too big |
|
// for a uri |
|
Object.keys(copy).forEach(function (key) { |
|
if (copy[key].hasOwnProperty('pssh')) { |
|
delete copy[key].pssh; |
|
} |
|
}); |
|
|
|
stateEls.keysystems.value = JSON.stringify(copy, null, 2); |
|
} |
|
|
|
if (source.src) { |
|
stateEls.url.value = encodeURI(source.src); |
|
} |
|
|
|
if (source.type) { |
|
stateEls.type.value = source.type; |
|
} |
|
|
|
saveState(); |
|
}); |
|
|
|
player.width(640); |
|
player.height(264); |
|
|
|
stateEls.debug.dispatchEvent(newEvent('change')); |
|
stateEls.muted.dispatchEvent(newEvent('change')); |
|
stateEls.fluid.dispatchEvent(newEvent('change')); |
|
stateEls.autoplay.dispatchEvent(newEvent('change')); |
|
|
|
// run the load url handler for the intial source |
|
if (stateEls.url.value) { |
|
urlButton.dispatchEvent(newEvent('click')); |
|
} else { |
|
sources.dispatchEvent(newEvent('change')); |
|
} |
|
player.on('loadedmetadata', function () { |
|
if (player.tech_.vhs) { |
|
window.vhs = player.tech_.vhs; |
|
window.mpc = player.tech_.vhs.masterPlaylistController_; |
|
window.mpc.masterPlaylistLoader_.on( |
|
'mediachange', |
|
regenerateRepresentations |
|
); |
|
regenerateRepresentations(); |
|
} else { |
|
window.vhs = null; |
|
window.mpc = null; |
|
} |
|
}); |
|
cb(player); |
|
}); |
|
}); |
|
|
|
var urlButtonClick = function (event) { |
|
var ext; |
|
var type = stateEls.type.value; |
|
|
|
// reset type if it's a manifest object's type |
|
if (type === 'application/vnd.videojs.vhs+json') { |
|
type = ''; |
|
} |
|
|
|
if (isManifestObjectType(stateEls.url.value)) { |
|
type = 'application/vnd.videojs.vhs+json'; |
|
} |
|
|
|
if (!type.trim()) { |
|
ext = getFileExtension(stateEls.url.value); |
|
|
|
if (ext === 'mpd') { |
|
type = 'application/dash+xml'; |
|
} else if (ext === 'm3u8') { |
|
type = 'application/x-mpegURL'; |
|
} |
|
} |
|
|
|
saveState(); |
|
|
|
var source = { |
|
src: stateEls.url.value, |
|
type: type, |
|
}; |
|
|
|
sources.selectedIndex = -1; |
|
|
|
Array.prototype.forEach.call(sources.options, function (s, i) { |
|
if (s.value === stateEls.url.value) { |
|
sources.selectedIndex = i; |
|
} |
|
}); |
|
|
|
window.player.src(source); |
|
const src = source.src; |
|
window.currentSrc = src; |
|
|
|
window.shaka.load(src); |
|
window.clapprPlayer.load(src); |
|
const nativePlayer = document.getElementById('native-player'); |
|
nativePlayer.setAttribute('src', src); |
|
}; |
|
|
|
urlButton.addEventListener('click', urlButtonClick); |
|
urlButton.addEventListener('tap', urlButtonClick); |
|
|
|
sources.addEventListener('change', function (event) { |
|
var selectedOption = sources.options[sources.selectedIndex]; |
|
|
|
if (!selectedOption) { |
|
return; |
|
} |
|
var src = selectedOption.value; |
|
|
|
stateEls.url.value = src; |
|
stateEls.type.value = selectedOption.getAttribute('data-mimetype'); |
|
// stateEls.keysystems.value = selectedOption.getAttribute('data-key-systems'); |
|
|
|
urlButton.dispatchEvent(newEvent('click')); |
|
}); |
|
|
|
stateEls.url.addEventListener('keyup', function (event) { |
|
if (event.key === 'Enter') { |
|
urlButton.click(); |
|
} |
|
}); |
|
stateEls.url.addEventListener('input', function (event) { |
|
if (stateEls.type.value.length) { |
|
stateEls.type.value = ''; |
|
} |
|
}); |
|
stateEls.type.addEventListener('keyup', function (event) { |
|
if (event.key === 'Enter') { |
|
urlButton.click(); |
|
} |
|
}); |
|
|
|
// run the change handler for the first time |
|
stateEls.minified.dispatchEvent(newEvent('change')); |
|
}; |
|
})(window);
|
|
|