diff --git a/index.html b/index.html
index b48f62c..4fe54d1 100644
--- a/index.html
+++ b/index.html
@@ -22,7 +22,7 @@
if (app.ports !== undefined && app.ports.registerVideo !== undefined) {
app.ports.registerVideo.subscribe(function(args) {
window.scrollTo(0, 0);
- var time = parseInt(args[2], 10) || undefined;
+ var time = vd.parseTime(args[2]) || undefined;
requestAnimationFrame(function() {
if (args[0] !== lastId) {
@@ -30,7 +30,7 @@
player = vd.setup(args[0], {
v: args[1] + "/manifest.mpd",
- t: parseInt(args[2], 10) || 0,
+ t: time,
focus: true
});
} else if (time !== undefined ){
diff --git a/js/vd.js b/js/vd.js
index 3eaffcb..e6acf5a 100644
--- a/js/vd.js
+++ b/js/vd.js
@@ -3,488 +3,547 @@ const vd = (function() {
let vd = {};
- function createEl(tagName = 'div', properties = {}, attributes = {}, content) {
- const el = document.createElement(tagName);
+function createEl(tagName = 'div', properties = {}, attributes = {}, content) {
+ const el = document.createElement(tagName);
- Object.getOwnPropertyNames(properties).forEach(function(propName) {
- const val = properties[propName];
+ Object.getOwnPropertyNames(properties).forEach(function(propName) {
+ const val = properties[propName];
- // See #2176
- // We originally were accepting both properties and attributes in the
- // same object, but that doesn't work so well.
- if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
- log.warn(tsml`Setting attributes in the second argument of createEl()
+ // See #2176
+ // We originally were accepting both properties and attributes in the
+ // same object, but that doesn't work so well.
+ if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
+ log.warn(tsml`Setting attributes in the second argument of createEl()
has been deprecated. Use the third argument instead.
createEl(type, properties, attributes). Attempting to set ${propName} to ${val}.`);
- el.setAttribute(propName, val);
+ el.setAttribute(propName, val);
- // Handle textContent since it's not supported everywhere and we have a
- // method for it.
- } else if (propName === 'textContent') {
- textContent(el, val);
- } else {
- el[propName] = val;
+ // Handle textContent since it's not supported everywhere and we have a
+ // method for it.
+ } else if (propName === 'textContent') {
+ textContent(el, val);
+ } else {
+ el[propName] = val;
+ }
+ });
+
+ return el;
+}
+
+function findPosition(el) {
+ let box;
+
+ if (el.getBoundingClientRect && el.parentNode) {
+ box = el.getBoundingClientRect();
+ }
+
+ if (!box) {
+ return {
+ left: 0,
+ top: 0
+ };
+ }
+
+ const docEl = document.documentElement;
+ const body = document.body;
+
+ const clientLeft = docEl.clientLeft || body.clientLeft || 0;
+ const scrollLeft = window.pageXOffset || body.scrollLeft;
+ const left = box.left + scrollLeft - clientLeft;
+
+ const clientTop = docEl.clientTop || body.clientTop || 0;
+ const scrollTop = window.pageYOffset || body.scrollTop;
+ const top = box.top + scrollTop - clientTop;
+
+ // Android sometimes returns slightly off decimal values, so need to round
+ return {
+ left: Math.round(left),
+ top: Math.round(top)
+ };
+}
+
+function getBoundingClientRect(el) {
+ if (el && el.getBoundingClientRect && el.parentNode) {
+ const rect = el.getBoundingClientRect();
+ const result = {};
+
+ ['bottom', 'height', 'left', 'right', 'top', 'width'].forEach(k => {
+ if (rect[k] !== undefined) {
+ result[k] = rect[k];
}
});
+ if (!result.height) {
+ result.height = parseFloat(computedStyle(el, 'height'));
+ }
+
+ if (!result.width) {
+ result.width = parseFloat(computedStyle(el, 'width'));
+ }
+
+ return result;
+ }
+}
+
+function getPointerPosition(el, event) {
+ const position = {};
+ const box = findPosition(el);
+ const boxW = el.offsetWidth;
+ const boxH = el.offsetHeight;
+
+ const boxY = box.top;
+ const boxX = box.left;
+ let pageY = event.pageY;
+ let pageX = event.pageX;
+
+ if (event.changedTouches) {
+ pageX = event.changedTouches[0].pageX;
+ pageY = event.changedTouches[0].pageY;
+ }
+
+ position.y = Math.max(0, Math.min(1, ((boxY - pageY) + boxH) / boxH));
+ position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
+
+ return position;
+}
+
+let vjs = {};
+vjs.Component = videojs.getComponent('Component');
+vjs.Menu = videojs.getComponent('Menu');
+vjs.MenuButton = videojs.getComponent('MenuButton');
+vjs.MenuItem = videojs.getComponent('MenuItem');
+
+class MenuButton extends vjs.MenuButton {
+
+ constructor(player, options) {
+ super(player, options);
+ this.updateLabel(options === undefined ? "" : options.label || "");
+ }
+
+ createEl() {
+ const el = super.createEl();
+
+ this.labelEl_ = createEl('div', {
+ className: 'vjs-playback-rate-value',
+ innerHTML: 'auto'
+ });
+
+ el.appendChild(this.labelEl_);
+
return el;
}
- function findPosition(el) {
- let box;
-
- if (el.getBoundingClientRect && el.parentNode) {
- box = el.getBoundingClientRect();
- }
-
- if (!box) {
- return {
- left: 0,
- top: 0
- };
- }
-
- const docEl = document.documentElement;
- const body = document.body;
-
- const clientLeft = docEl.clientLeft || body.clientLeft || 0;
- const scrollLeft = window.pageXOffset || body.scrollLeft;
- const left = box.left + scrollLeft - clientLeft;
-
- const clientTop = docEl.clientTop || body.clientTop || 0;
- const scrollTop = window.pageYOffset || body.scrollTop;
- const top = box.top + scrollTop - clientTop;
-
- // Android sometimes returns slightly off decimal values, so need to round
- return {
- left: Math.round(left),
- top: Math.round(top)
- };
+ dispose() {
+ this.labelEl_ = null;
+ super.dispose();
}
- function getBoundingClientRect(el) {
- if (el && el.getBoundingClientRect && el.parentNode) {
- const rect = el.getBoundingClientRect();
- const result = {};
+ buildCSSClass() {
+ return `vjs-playback-rate ${super.buildCSSClass()}`;
+ }
- ['bottom', 'height', 'left', 'right', 'top', 'width'].forEach(k => {
- if (rect[k] !== undefined) {
- result[k] = rect[k];
- }
+ buildWrapperCSSClass() {
+ return `vjs-playback-rate ${super.buildWrapperCSSClass()}`;
+ }
+
+ createMenu() {
+ const menu = new vjs.Menu(this.player());
+ return menu;
+ }
+
+ updateARIAAttributes() {
+ this.el().setAttribute('aria-valuenow', this.labelEl_.innerHTML);
+ }
+
+ updateLabel(newLabel) {
+ this.labelEl_.innerHTML = newLabel;
+ }
+
+}
+
+class ResolutionItem extends vjs.MenuItem {
+ constructor() {
+ super(...arguments);
+ this.representation = arguments[1].representation;
+ this.menuButton = arguments[1].menuButton;
+ this.label = arguments[1].label;
+ }
+
+ handleClick() {
+ if (this.representation === undefined) {
+ // Clicked on the auto button
+ this.player().tech({IWillNotUseThisInPlugins: true}).hls.representations().forEach(function(rep) {
+ rep.enabled(true);
});
- if (!result.height) {
- result.height = parseFloat(computedStyle(el, 'height'));
- }
-
- if (!result.width) {
- result.width = parseFloat(computedStyle(el, 'width'));
- }
-
- return result;
- }
- }
-
- function getPointerPosition(el, event) {
- const position = {};
- const box = findPosition(el);
- const boxW = el.offsetWidth;
- const boxH = el.offsetHeight;
-
- const boxY = box.top;
- const boxX = box.left;
- let pageY = event.pageY;
- let pageX = event.pageX;
-
- if (event.changedTouches) {
- pageX = event.changedTouches[0].pageX;
- pageY = event.changedTouches[0].pageY;
- }
-
- position.y = Math.max(0, Math.min(1, ((boxY - pageY) + boxH) / boxH));
- position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
-
- return position;
- }
-
- function setupRepresentations(menuButton, player) {
-
- let hls = player.tech({IWillNotUseThisInPlugins: true}).hls;
-
- if (hls === undefined) {
- setTimeout(() => setupRepresentations(menuButton, player), 500);
- return;
- }
-
- let representations = hls.representations();
- representations.sort((a, b) => b.height - a.height);
-
- menuButton.menu.items = [];
- menuButton.menu.addAndRecordItem = function(item) {
- this.addItem(item);
- this.items.push(item);
- }
-
- menuButton.menu.addAndRecordItem(new MenuItem(player, { label: "auto", menuButton }));
- for (let representation of representations) {
- menuButton.menu.addAndRecordItem(new MenuItem(player, {
- label: representation.height + "p",
- representation,
- menuButton
- }));
- }
- }
-
- function setupSpeed(menuButton, player) {
- let speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
- menuButton.updateLabel('x1');
- menuButton.menu.items = [];
- menuButton.menu.addAndRecordItem = function(item) {
- this.addItem(item);
- this.items.push(item);
- }
-
- for (let speed of speeds) {
- menuButton.menu.addAndRecordItem(new SpeedItem(player, {
- label: "x" + speed,
- speed,
- }));
- }
- }
-
- let vjs = {};
-
- vjs.Component = videojs.getComponent('Component');
- vjs.Menu = videojs.getComponent('Menu');
- vjs.MenuButton = videojs.getComponent('MenuButton');
- vjs.MenuItem = videojs.getComponent('MenuItem');
-
- class MenuButton extends vjs.MenuButton {
-
- constructor(player, options) {
- super(player, options);
- this.updateLabel('auto');
- }
-
- createEl() {
- const el = super.createEl();
-
- this.labelEl_ = createEl('div', {
- className: 'vjs-playback-rate-value',
- innerHTML: 'auto'
+ } else {
+ // Clicked on another button
+ let self = this;
+ this.player().tech({IWillNotUseThisInPlugins: true}).hls.representations().forEach(function(rep) {
+ rep.enabled(rep.height === self.options_.representation.height);
});
-
- el.appendChild(this.labelEl_);
-
- return el;
- }
-
- dispose() {
- this.labelEl_ = null;
- super.dispose();
- }
-
- buildCSSClass() {
- return `vjs-playback-rate ${super.buildCSSClass()}`;
- }
-
- buildWrapperCSSClass() {
- return `vjs-playback-rate ${super.buildWrapperCSSClass()}`;
- }
-
- createMenu() {
- const menu = new vjs.Menu(this.player());
- return menu;
- }
-
- updateARIAAttributes() {
- this.el().setAttribute('aria-valuenow', this.labelEl_.innerHTML);
- }
-
- updateLabel(newLabel) {
- this.labelEl_.innerHTML = newLabel;
}
+ this.menuButton.updateLabel(this.label);
+ }
+}
+class SpeedItem extends vjs.MenuItem {
+ constructor() {
+ super(...arguments);
+ this.label = arguments[1].label;
+ this.speed = arguments[1].speed;
}
- class MenuItem extends vjs.MenuItem {
- constructor() {
- super(...arguments);
- this.representation = arguments[1].representation;
- this.menuButton = arguments[1].menuButton;
- this.label = arguments[1].label;
- }
+ handleClick() {
+ this.player().playbackRate(this.speed);
+ }
+}
- handleClick() {
- if (this.representation === undefined) {
- // Clicked on the auto button
- this.player().tech({IWillNotUseThisInPlugins: true}).hls.representations().forEach(function(rep) {
- rep.enabled(true);
- });
-
- } else {
- // Clicked on another button
- let self = this;
- this.player().tech({IWillNotUseThisInPlugins: true}).hls.representations().forEach(function(rep) {
- rep.enabled(rep.height === self.options_.representation.height);
- });
- }
- this.menuButton.updateLabel(this.label);
- }
+class Thumbnail extends vjs.Component {
+ constructor() {
+ super(...arguments);
+ this.thumbnails = arguments[1].thumbnails;
+ this.width = arguments[1].width;
+ this.height = arguments[1].height;
}
- class SpeedItem extends vjs.MenuItem {
- constructor() {
- super(...arguments);
- this.label = arguments[1].label;
- this.speed = arguments[1].speed;
- }
-
- handleClick() {
- this.player().playbackRate(this.speed);
- }
- }
-
- class Thumbnail extends vjs.Component {
- constructor() {
- super(...arguments);
- this.thumbnails = arguments[1].thumbnails;
- this.width = arguments[1].width;
- this.height = arguments[1].height;
- }
-
- createEl() {
- let el = super.createEl('img', {
- src: this.options_.thumbnails[0],
- width: '0px',
- });
-
- el.style.position = 'absolute';
- el.style.left = '0px';
- el.style.top = -this.options_.height + "px";
- el.style.border = "solid";
- el.style.borderColor = "black";
- el.style.borderWidth = "1px";
-
- return el;
- }
-
- update(ratio) {
- this.el().src = this.options_.thumbnails[Math.round(100 * ratio)];
- }
- }
-
-
- vd.setup = function(video, args) {
-
- let src;
-
- if (typeof video === 'string' || video instanceof String) {
- video = document.getElementById(video);
- }
-
- if (video === undefined) {
- throw new Error("video element or ID invalid");
- }
-
- if (typeof args === "string" || args instanceof String) {
- src = args;
- }
-
- if (typeof args === "object") {
- src = args.v;
- }
-
- if (src === undefined) {
- throw new Error("video src is undefined");
- }
-
- let player = videojs(video);
- player.src({
- src,
- type: 'application/dash+xml'
+ createEl() {
+ let el = super.createEl('img', {
+ src: this.options_.thumbnails[0],
+ width: '0px',
});
- if (args.focus === true) {
- player.focus();
- }
+ el.style.position = 'absolute';
+ el.style.left = '0px';
+ el.style.top = -this.options_.height + "px";
+ el.style.border = "solid";
+ el.style.borderColor = "black";
+ el.style.borderWidth = "1px";
- player._oldRequestFullscreen = player.requestFullscreen;
- player.requestFullscreen = function() {
- var player = document.getElementById(this.id());
- if (player === null) {
+ return el;
+ }
+
+ update(ratio) {
+ this.el().src = this.options_.thumbnails[Math.round(100 * ratio)];
+ }
+}
+
+function createRepresentationButtons(player, menuButton = undefined) {
+ if (menuButton === undefined) {
+ menuButton = new MenuButton(player);
+ menuButton.updateLabel("auto");
+ }
+
+ let hls = player.tech({IWillNotUseThisInPlugins: true}).hls;
+
+ if (hls === undefined) {
+ setTimeout(() => createRepresentationButtons(player, menuButton), 500);
+ return menuButton;
+ }
+
+ let representations = hls.representations();
+ representations.sort((a, b) => b.height - a.height);
+
+ menuButton.menu.items = [];
+ menuButton.menu.addAndRecordItem = function(item) {
+ this.addItem(item);
+ this.items.push(item);
+ }
+
+ menuButton.menu.addAndRecordItem(new ResolutionItem(player, { label: "auto", menuButton }));
+ for (let representation of representations) {
+ menuButton.menu.addAndRecordItem(new ResolutionItem(player, {
+ label: representation.height + "p",
+ representation,
+ menuButton
+ }));
+ }
+
+ return menuButton;
+}
+
+function createSpeedButtons(player) {
+ let menuButton = new MenuButton(player);
+
+ let speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
+ menuButton.updateLabel('x1');
+ menuButton.menu.items = [];
+ menuButton.menu.addAndRecordItem = function(item) {
+ this.addItem(item);
+ this.items.push(item);
+ }
+
+ for (let speed of speeds) {
+ menuButton.menu.addAndRecordItem(new SpeedItem(player, {
+ label: "x" + speed,
+ speed,
+ }));
+ }
+
+ return menuButton;
+}
+
+vd.parseTime = function(t) {
+ let parsed = 1 * t;
+
+ if (!isNaN(parsed)) {
+ return parsed;
+ }
+
+ // Compute the split
+ let split = t.split("h");
+
+ let hours;
+ let minutes;
+ let seconds;
+
+ switch (split.length) {
+ case 1:
+ hours = 0;
+ split = split[0].split("m");
+ break;
+ case 2:
+ hours = 1 * split[0];
+ if (isNaN(hours)) {
+ return NaN;
+ }
+ split = split[1].split("m");
+ break;
+ default:
+ return NaN;
+ }
+
+ switch (split.length) {
+ case 1:
+ minutes = 0;
+ split = split[0].split("s");
+ break;
+ case 2:
+ minutes = 1 * split[0];
+ if (isNaN(minutes)) {
+ return NaN;
+ }
+ split = split[1].split("s");
+ break;
+ default:
+ return NaN;
+ }
+
+ seconds = 1 * split[0];
+ if ((split.length !== 1 && (! (split.length == 2 && split[1] === ""))) || isNaN(seconds)) {
+ return NaN;
+ }
+
+ return 3600 * hours + 60 * minutes + seconds;
+}
+
+vd.setup = function(video, args) {
+
+ let src;
+
+ if (typeof video === 'string' || video instanceof String) {
+ video = document.getElementById(video);
+ }
+
+ if (video === undefined) {
+ throw new Error("video element or ID invalid");
+ }
+
+ if (typeof args === "string" || args instanceof String) {
+ src = args;
+ }
+
+ if (typeof args === "object") {
+ src = args.v;
+ }
+
+ if (src === undefined) {
+ throw new Error("video src is undefined");
+ }
+
+ let player = videojs(video);
+ player.src({
+ src,
+ type: 'application/dash+xml'
+ });
+
+ if (args.focus === true) {
+ player.focus();
+ }
+
+ player._oldRequestFullscreen = player.requestFullscreen;
+ player.requestFullscreen = function() {
+ var player = document.getElementById(this.id());
+ if (player === null) {
+ return;
+ }
+ player = typeof player.player === "function" ? player.player() : player.player;
+ player._oldRequestFullscreen(...arguments);
+ setTimeout(() => {
+ if (screen.orientation) {
+ screen.orientation.lock("landscape")
+ }
+ }, 1000);
+ };
+
+ player._oldExitFullscreen = player.exitFullscreen;
+ player.exitFullscreen = function() {
+ var player = document.getElementById(this.id());
+ if (player === null) {
+ return;
+ }
+ player = typeof player.player === "function" ? player.player() : player.player;
+ player._oldExitFullscreen(...arguments);
+ setTimeout(() => {
+ if (screen.orientation) {
+ screen.orientation.unlock();
+ }
+ }, 1000);
+ };
+
+ if (args.t !== undefined) {
+ let time = vd.parseTime(args.t);
+ if (!isNaN(time)) {
+ player.currentTime(time);
+ }
+ }
+
+
+ if (player.getAttribute('disable-shortcuts') == undefined) {
+ player.el().addEventListener('keydown', (e) => {
+ if (e.ctrlKey || e.shiftKey || e.altKey) {
return;
}
- player = typeof player.player === "function" ? player.player() : player.player;
- player._oldRequestFullscreen(...arguments);
- setTimeout(() => {
- if (screen.orientation) {
- screen.orientation.lock("landscape")
- }
- }, 1000);
- };
- player._oldExitFullscreen = player.exitFullscreen;
- player.exitFullscreen = function() {
- var player = document.getElementById(this.id());
- if (player === null) {
+ let p = document.getElementById(player.id());
+ if (p === null) {
return;
}
- player = typeof player.player === "function" ? player.player() : player.player;
- player._oldExitFullscreen(...arguments);
- setTimeout(() => {
- if (screen.orientation) {
- screen.orientation.unlock();
- }
- }, 1000);
- };
+ p = typeof p.player === "function" ? p.player() : p.player;
- if (args.t !== undefined) {
- let time = parseFloat(args.t);
- if (!isNaN(time)) {
- player.currentTime(time);
+ switch (e.keyCode) {
+ case 37: e.preventDefault(); p.currentTime(p.currentTime() - 5); break;
+ case 39: e.preventDefault(); p.currentTime(p.currentTime() + 5); break;
+ case 32: e.preventDefault(); if (p.paused()) p.play(); else p.pause(); break;
+ case 40: e.preventDefault(); p.volume(p.volume() - 0.1); break;
+ case 38: e.preventDefault(); p.volume(p.volume() + 0.1); break;
}
- }
+ }, true);
+ document.body.addEventListener('keydown', (e) => {
+ if (e.ctrlKey || e.shiftKey || e.altKey) {
+ return;
+ }
- if (player.getAttribute('disable-shortcuts') == undefined) {
- player.el().addEventListener('keydown', (e) => {
- if (e.ctrlKey || e.shiftKey || e.altKey) {
- return;
- }
+ let p = document.getElementById(player.id());
+ if (p === null) {
+ return;
+ }
+ p = typeof p.player === "function" ? p.player() : p.player;
- let p = document.getElementById(player.id());
- if (p === null) {
- return;
- }
- p = typeof p.player === "function" ? p.player() : p.player;
-
- switch (e.keyCode) {
- case 37: e.preventDefault(); p.currentTime(p.currentTime() - 5); break;
- case 39: e.preventDefault(); p.currentTime(p.currentTime() + 5); break;
- case 32: e.preventDefault(); if (p.paused()) p.play(); else p.pause(); break;
- case 40: e.preventDefault(); p.volume(p.volume() - 0.1); break;
- case 38: e.preventDefault(); p.volume(p.volume() + 0.1); break;
- }
- }, true);
-
- document.body.addEventListener('keydown', (e) => {
- if (e.ctrlKey || e.shiftKey || e.altKey) {
- return;
- }
-
- let p = document.getElementById(player.id());
- if (p === null) {
- return;
- }
- p = typeof p.player === "function" ? p.player() : p.player;
-
- switch (e.keyCode) {
- case 74: e.preventDefault(); p.currentTime(p.currentTime() - 10); break; // J -> -10s
- case 76: e.preventDefault(); p.currentTime(p.currentTime() + 10); break; // L -> +10s
- case 75: e.preventDefault(); if (p.paused()) p.play(); else p.pause(); break; // K -> play/pause
- case 77: e.preventDefault(); p.muted(!p.muted()); break; // M -> mute
+ switch (e.keyCode) {
+ case 74: e.preventDefault(); p.currentTime(p.currentTime() - 10); break; // J -> -10s
+ case 76: e.preventDefault(); p.currentTime(p.currentTime() + 10); break; // L -> +10s
+ case 75: e.preventDefault(); if (p.paused()) p.play(); else p.pause(); break; // K -> play/pause
+ case 77: e.preventDefault(); p.muted(!p.muted()); break; // M -> mute
// F -> toggle fullscreen
- case 70:
- e.preventDefault();
+ case 70:
+ e.preventDefault();
- if (p.isFullscreen()) {
- p.exitFullscreen();
- } else {
- p.requestFullscreen();
- }
- break;
+ if (p.isFullscreen()) {
+ p.exitFullscreen();
+ } else {
+ p.requestFullscreen();
+ }
+ break;
// Seek shortcuts
- case 48: case 96: e.preventDefault(); p.currentTime(0); break;
- case 49: case 97: e.preventDefault(); p.currentTime( p.duration() / 10); break;
- case 50: case 98: e.preventDefault(); p.currentTime(2 * p.duration() / 10); break;
- case 51: case 99: e.preventDefault(); p.currentTime(3 * p.duration() / 10); break;
- case 52: case 100: e.preventDefault(); p.currentTime(4 * p.duration() / 10); break;
- case 53: case 101: e.preventDefault(); p.currentTime(5 * p.duration() / 10); break;
- case 54: case 102: e.preventDefault(); p.currentTime(6 * p.duration() / 10); break;
- case 55: case 103: e.preventDefault(); p.currentTime(7 * p.duration() / 10); break;
- case 56: case 104: e.preventDefault(); p.currentTime(8 * p.duration() / 10); break;
- case 57: case 105: e.preventDefault(); p.currentTime(9 * p.duration() / 10); break;
- }
- }, true);
- }
-
- let root = src.split('/').slice(0, -1).join('/');
- if (root !== "") {
- root += "/";
- }
-
- if (player.getAttribute('disable-thumbnails') == undefined) {
-
- let thumbnails = [];
- const MAX_INDEX = 100;
- for (let i = 0; i <= MAX_INDEX; i++) {
- thumbnails.push(root + "miniature-" + ("" + i).padStart(3, "0") + ".png");
+ case 48: case 96: e.preventDefault(); p.currentTime(0); break;
+ case 49: case 97: e.preventDefault(); p.currentTime( p.duration() / 10); break;
+ case 50: case 98: e.preventDefault(); p.currentTime(2 * p.duration() / 10); break;
+ case 51: case 99: e.preventDefault(); p.currentTime(3 * p.duration() / 10); break;
+ case 52: case 100: e.preventDefault(); p.currentTime(4 * p.duration() / 10); break;
+ case 53: case 101: e.preventDefault(); p.currentTime(5 * p.duration() / 10); break;
+ case 54: case 102: e.preventDefault(); p.currentTime(6 * p.duration() / 10); break;
+ case 55: case 103: e.preventDefault(); p.currentTime(7 * p.duration() / 10); break;
+ case 56: case 104: e.preventDefault(); p.currentTime(8 * p.duration() / 10); break;
+ case 57: case 105: e.preventDefault(); p.currentTime(9 * p.duration() / 10); break;
}
-
- let thumbnail = new Thumbnail(player, {
- thumbnails,
- width: 192 * 0.75,
- height: 108 * 0.75,
- });
-
- player.controlBar.progressControl.addChild(thumbnail);
-
-
- player.controlBar.progressControl.el().addEventListener('mouseenter', e => {
- thumbnail.el().width = thumbnail.width;
- thumbnail.update(e.offsetX / e.target.offsetWidth);
- });
-
- player.controlBar.progressControl.el().addEventListener('mouseleave', e => {
- thumbnail.el().width = 0;
- });
-
- player.controlBar.progressControl.on('mousemove', (event) => {
- const seekBar = player.controlBar.progressControl.seekBar;
-
- const seekBarEl = seekBar.el();
- const seekBarRect = getBoundingClientRect(seekBarEl);
- let seekBarPoint = getPointerPosition(seekBarEl, event).x;
-
- seekBarPoint = Math.max(0, Math.min(1, seekBarPoint));
- thumbnail.update(seekBarPoint);
- thumbnail.el().style.left = (seekBarPoint * seekBarRect.width - thumbnail.width / 2) + "px";
- });
-
- }
-
- let controlBar = player.getChild('controlBar');
- let fullscreenButton = controlBar.children()[controlBar.children().length - 1];
- controlBar.removeChild(fullscreenButton);
- let menuButton = new MenuButton(player);
- let speedButton = new MenuButton(player);
- controlBar.addChild(speedButton, {});
- controlBar.addChild(menuButton, {});
- controlBar.addChild(fullscreenButton, {});
-
- setupSpeed(speedButton, player);
- setupRepresentations(menuButton, player);
-
- // videojs.Html5DashJS.hook('beforeinitialize', (p, mp) => setupRepresentations(menuButton, p, mp));
- window.player = player;
-
- if (video.getAttribute('autoplay') != undefined) {
- player.play();
- }
-
- return player;
+ }, true);
}
- for (let element of document.getElementsByTagName('video')) {
- let src = element.getAttribute('data-dash-src');
- if (src != undefined) {
- vd.setup(element, src);
- }
+ let root = src.split('/').slice(0, -1).join('/');
+ if (root !== "") {
+ root += "/";
}
+ if (player.getAttribute('disable-thumbnails') == undefined) {
+
+ let thumbnails = [];
+ const MAX_INDEX = 100;
+ for (let i = 0; i <= MAX_INDEX; i++) {
+ thumbnails.push(root + "miniature-" + ("" + i).padStart(3, "0") + ".png");
+ }
+
+ let thumbnail = new Thumbnail(player, {
+ thumbnails,
+ width: 192 * 0.75,
+ height: 108 * 0.75,
+ });
+
+ player.controlBar.progressControl.addChild(thumbnail);
+
+
+ player.controlBar.progressControl.el().addEventListener('mouseenter', e => {
+ thumbnail.el().width = thumbnail.width;
+ thumbnail.update(e.offsetX / e.target.offsetWidth);
+ });
+
+ player.controlBar.progressControl.el().addEventListener('mouseleave', e => {
+ thumbnail.el().width = 0;
+ });
+
+ player.controlBar.progressControl.on('mousemove', (event) => {
+ const seekBar = player.controlBar.progressControl.seekBar;
+
+ const seekBarEl = seekBar.el();
+ const seekBarRect = getBoundingClientRect(seekBarEl);
+ let seekBarPoint = getPointerPosition(seekBarEl, event).x;
+
+ seekBarPoint = Math.max(0, Math.min(1, seekBarPoint));
+ thumbnail.update(seekBarPoint);
+ thumbnail.el().style.left = (seekBarPoint * seekBarRect.width - thumbnail.width / 2) + "px";
+ });
+
+ }
+
+ let controlBar = player.getChild('controlBar');
+ let fullscreenButton = controlBar.children()[controlBar.children().length - 1];
+ controlBar.removeChild(fullscreenButton);
+
+ let menuButton = createRepresentationButtons(player);
+ let speedButton = createSpeedButtons(player);
+ controlBar.addChild(speedButton, {});
+ controlBar.addChild(menuButton, {});
+ controlBar.addChild(fullscreenButton, {});
+
+ window.player = player;
+
+ if (video.getAttribute('autoplay') != undefined) {
+ player.play();
+ }
+
+ return player;
+}
+
+for (let element of document.getElementsByTagName('video')) {
+ let src = element.getAttribute('data-dash-src');
+ if (src != undefined) {
+ vd.setup(element, src);
+ }
+}
+
+
return vd;
-
})();
diff --git a/src/Core.elm b/src/Core.elm
index 9e4aba4..bc85487 100644
--- a/src/Core.elm
+++ b/src/Core.elm
@@ -185,11 +185,11 @@ update msg model =
( [], Dict.empty )
time =
- case Maybe.map String.toInt (Dict.get "t" args) of
- Just (Just 0) ->
+ case Dict.get "t" args of
+ Just "0" ->
Nothing
- Just (Just t) ->
+ Just t ->
Just t
_ ->
diff --git a/src/Ports.elm b/src/Ports.elm
index cdf4d98..9756a7b 100644
--- a/src/Ports.elm
+++ b/src/Ports.elm
@@ -1,7 +1,7 @@
port module Ports exposing (eraseVideo, registerVideo)
-port registerVideo : ( String, String, Maybe Int ) -> Cmd msg
+port registerVideo : ( String, String, Maybe String ) -> Cmd msg
port eraseVideo : () -> Cmd msg