Update video

This commit is contained in:
Thomas Forgione 2020-11-05 17:18:16 +01:00
parent 57bc1e0a9f
commit a61d2fabcd
4 changed files with 501 additions and 442 deletions

View File

@ -22,7 +22,7 @@
if (app.ports !== undefined && app.ports.registerVideo !== undefined) { if (app.ports !== undefined && app.ports.registerVideo !== undefined) {
app.ports.registerVideo.subscribe(function(args) { app.ports.registerVideo.subscribe(function(args) {
window.scrollTo(0, 0); window.scrollTo(0, 0);
var time = parseInt(args[2], 10) || undefined; var time = vd.parseTime(args[2]) || undefined;
requestAnimationFrame(function() { requestAnimationFrame(function() {
if (args[0] !== lastId) { if (args[0] !== lastId) {
@ -30,7 +30,7 @@
player = vd.setup(args[0], { player = vd.setup(args[0], {
v: args[1] + "/manifest.mpd", v: args[1] + "/manifest.mpd",
t: parseInt(args[2], 10) || 0, t: time,
focus: true focus: true
}); });
} else if (time !== undefined ){ } else if (time !== undefined ){

217
js/vd.js
View File

@ -3,7 +3,7 @@ const vd = (function() {
let vd = {}; let vd = {};
function createEl(tagName = 'div', properties = {}, attributes = {}, content) { function createEl(tagName = 'div', properties = {}, attributes = {}, content) {
const el = document.createElement(tagName); const el = document.createElement(tagName);
Object.getOwnPropertyNames(properties).forEach(function(propName) { Object.getOwnPropertyNames(properties).forEach(function(propName) {
@ -28,9 +28,9 @@ const vd = (function() {
}); });
return el; return el;
} }
function findPosition(el) { function findPosition(el) {
let box; let box;
if (el.getBoundingClientRect && el.parentNode) { if (el.getBoundingClientRect && el.parentNode) {
@ -60,9 +60,9 @@ const vd = (function() {
left: Math.round(left), left: Math.round(left),
top: Math.round(top) top: Math.round(top)
}; };
} }
function getBoundingClientRect(el) { function getBoundingClientRect(el) {
if (el && el.getBoundingClientRect && el.parentNode) { if (el && el.getBoundingClientRect && el.parentNode) {
const rect = el.getBoundingClientRect(); const rect = el.getBoundingClientRect();
const result = {}; const result = {};
@ -83,9 +83,9 @@ const vd = (function() {
return result; return result;
} }
} }
function getPointerPosition(el, event) { function getPointerPosition(el, event) {
const position = {}; const position = {};
const box = findPosition(el); const box = findPosition(el);
const boxW = el.offsetWidth; const boxW = el.offsetWidth;
@ -105,65 +105,19 @@ const vd = (function() {
position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW)); position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
return position; return position;
} }
function setupRepresentations(menuButton, player) { let vjs = {};
vjs.Component = videojs.getComponent('Component');
vjs.Menu = videojs.getComponent('Menu');
vjs.MenuButton = videojs.getComponent('MenuButton');
vjs.MenuItem = videojs.getComponent('MenuItem');
let hls = player.tech({IWillNotUseThisInPlugins: true}).hls; class MenuButton extends vjs.MenuButton {
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) { constructor(player, options) {
super(player, options); super(player, options);
this.updateLabel('auto'); this.updateLabel(options === undefined ? "" : options.label || "");
} }
createEl() { createEl() {
@ -205,9 +159,9 @@ const vd = (function() {
this.labelEl_.innerHTML = newLabel; this.labelEl_.innerHTML = newLabel;
} }
} }
class MenuItem extends vjs.MenuItem { class ResolutionItem extends vjs.MenuItem {
constructor() { constructor() {
super(...arguments); super(...arguments);
this.representation = arguments[1].representation; this.representation = arguments[1].representation;
@ -231,9 +185,9 @@ const vd = (function() {
} }
this.menuButton.updateLabel(this.label); this.menuButton.updateLabel(this.label);
} }
} }
class SpeedItem extends vjs.MenuItem { class SpeedItem extends vjs.MenuItem {
constructor() { constructor() {
super(...arguments); super(...arguments);
this.label = arguments[1].label; this.label = arguments[1].label;
@ -243,9 +197,9 @@ const vd = (function() {
handleClick() { handleClick() {
this.player().playbackRate(this.speed); this.player().playbackRate(this.speed);
} }
} }
class Thumbnail extends vjs.Component { class Thumbnail extends vjs.Component {
constructor() { constructor() {
super(...arguments); super(...arguments);
this.thumbnails = arguments[1].thumbnails; this.thumbnails = arguments[1].thumbnails;
@ -272,10 +226,118 @@ const vd = (function() {
update(ratio) { update(ratio) {
this.el().src = this.options_.thumbnails[Math.round(100 * 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;
vd.setup = function(video, args) { 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; let src;
@ -340,7 +402,7 @@ const vd = (function() {
}; };
if (args.t !== undefined) { if (args.t !== undefined) {
let time = parseFloat(args.t); let time = vd.parseTime(args.t);
if (!isNaN(time)) { if (!isNaN(time)) {
player.currentTime(time); player.currentTime(time);
} }
@ -459,16 +521,13 @@ const vd = (function() {
let controlBar = player.getChild('controlBar'); let controlBar = player.getChild('controlBar');
let fullscreenButton = controlBar.children()[controlBar.children().length - 1]; let fullscreenButton = controlBar.children()[controlBar.children().length - 1];
controlBar.removeChild(fullscreenButton); controlBar.removeChild(fullscreenButton);
let menuButton = new MenuButton(player);
let speedButton = new MenuButton(player); let menuButton = createRepresentationButtons(player);
let speedButton = createSpeedButtons(player);
controlBar.addChild(speedButton, {}); controlBar.addChild(speedButton, {});
controlBar.addChild(menuButton, {}); controlBar.addChild(menuButton, {});
controlBar.addChild(fullscreenButton, {}); controlBar.addChild(fullscreenButton, {});
setupSpeed(speedButton, player);
setupRepresentations(menuButton, player);
// videojs.Html5DashJS.hook('beforeinitialize', (p, mp) => setupRepresentations(menuButton, p, mp));
window.player = player; window.player = player;
if (video.getAttribute('autoplay') != undefined) { if (video.getAttribute('autoplay') != undefined) {
@ -476,15 +535,15 @@ const vd = (function() {
} }
return player; return player;
} }
for (let element of document.getElementsByTagName('video')) { for (let element of document.getElementsByTagName('video')) {
let src = element.getAttribute('data-dash-src'); let src = element.getAttribute('data-dash-src');
if (src != undefined) { if (src != undefined) {
vd.setup(element, src); vd.setup(element, src);
} }
} }
return vd; return vd;
})(); })();

View File

@ -185,11 +185,11 @@ update msg model =
( [], Dict.empty ) ( [], Dict.empty )
time = time =
case Maybe.map String.toInt (Dict.get "t" args) of case Dict.get "t" args of
Just (Just 0) -> Just "0" ->
Nothing Nothing
Just (Just t) -> Just t ->
Just t Just t
_ -> _ ->

View File

@ -1,7 +1,7 @@
port module Ports exposing (eraseVideo, registerVideo) 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 port eraseVideo : () -> Cmd msg