openvibers/openvibe.mediahub Commits

The small player plays the plain file, named on the watch page (#376)

OP OpenVibers committed 3 days ago · 8101adf772 · 3 files, +8 −6

The page's script gives the video element its streaming playlist once it runs; the small player on the next page was handed that, could not play it, and closed itself. The watch pages now name the file (data-ov-mini-src).

Changes

ddiff --git a/server/video/pages.js b/server/video/pages.js
iindex 8c58fdc..80d839e 100644
---- a/server/video/pages.js
++++ b/server/video/pages.js
@@@ -114,8 +114,10 @@ function posterAttr(url) {
* A watch page's video may come along (openvibe-shared 4.192 mini.js): the player's picture-in-picture button takes the
* person to the front page and the video goes on in the small player, on every page, from the same second.
*/
--function miniAttr(title, by, page) {
-- return html` data-ov-mini data-ov-mini-title="${String(title || 'Video')}" data-ov-mini-by="${String(by || '')}" data-ov-mini-page="${String(page || '')}"`;
++function miniAttr(title, by, page, file) {
++ // The file is named here: the page's script gives the element its streaming playlist once it runs, and the small
++ // player on another page plays the plain file (11-10: it was handed the playlist and drew nothing).
++ return html` data-ov-mini data-ov-mini-title="${String(title || 'Video')}" data-ov-mini-by="${String(by || '')}" data-ov-mini-page="${String(page || '')}"${file ? html` data-ov-mini-src="${String(file)}"` : ''}`;
}
function avatarAttr(username, networkUrl) {
@@@ -1502,7 +1504,7 @@ ${found ? sections.map((x) => (x.cards.length || kind ? html`<section class="ovv
<div class="ovv-col ovv-col--main">
<div class="ovv-stage">
${savedNotice(req)}${ownOnly ? notice('Private: only you (and OpenVibe staff) can see this recording.', 'info') : ''}
--<div class="ovv-player-wrap"${labelsUi.attrs(labelsUi.inForce(vod), { owner: vod.username, opened: true })}><video class="ovv-player" data-ov-player${miniAttr(vod.title || 'Stream recording', channelName || vod.username, watchPath)} controls preload="metadata" playsinline${posterAttr(httpsUrl(vod.thumbnail_url))}${avatarAttr(vod.username, config.networkUrl)}${shapeAttr} src="${fileOf(vod) || ''}" data-ovv-video${nextAttr}${viewAttr}${hlsAttr}>${segs.length ? html`<track kind="captions" label="Transcript (AI)" src="/v/${id}/captions.vtt" default>` : ''}${mems.length ? html`<track kind="chapters" src="/v/${id}/chapters.vtt">` : ''}</video>${pipsTag(pips)}</div>
++<div class="ovv-player-wrap"${labelsUi.attrs(labelsUi.inForce(vod), { owner: vod.username, opened: true })}><video class="ovv-player" data-ov-player${miniAttr(vod.title || 'Stream recording', channelName || vod.username, watchPath, fileOf(vod))} controls preload="metadata" playsinline${posterAttr(httpsUrl(vod.thumbnail_url))}${avatarAttr(vod.username, config.networkUrl)}${shapeAttr} src="${fileOf(vod) || ''}" data-ovv-video${nextAttr}${viewAttr}${hlsAttr}>${segs.length ? html`<track kind="captions" label="Transcript (AI)" src="/v/${id}/captions.vtt" default>` : ''}${mems.length ? html`<track kind="chapters" src="/v/${id}/chapters.vtt">` : ''}</video>${pipsTag(pips)}</div>
<div class="ovv-head">
${titleLine('Stream recording', vod.title || 'Stream recording')}
${labelsUi.chips(labelsUi.inForce(vod))}
@@@ -1628,7 +1630,7 @@ ${more || ''}
<div class="ovv-stage">
${savedNotice(req)}${req.query.made === '1' ? notice('Your clip was made. It is credited to you on OpenVibe.Live and here.', 'ok') : ''}${ownOnly ? notice('Private: only you (and OpenVibe staff) can see this clip.', 'info') : ''}
${cutting ? html`<div class="ovv-player-wrap ovv-cutting" role="status" data-ovv-reload="8"><p><i class="fa-solid fa-scissors" aria-hidden="true"></i> This clip is being cut. It plays here in a moment; the page checks again by itself.</p></div>`
-- : html`<div class="ovv-player-wrap"${labelsUi.attrs(labelsUi.inForce(clip), { owner: clip.username, opened: true })}><video class="ovv-player" data-ov-player${miniAttr(clip.title || 'Clip', clip.source_streamer_display_name || clip.display_name || clip.username, watchPath)} controls preload="metadata" playsinline${avatarAttr(clip.username, config.networkUrl)}${posterAttr(httpsUrl(clip.thumbnail_url))} src="${fileOf(clip) || ''}" data-ovv-video${nextAttr}${viewAttr}${hlsAttr}></video></div>`}
++ : html`<div class="ovv-player-wrap"${labelsUi.attrs(labelsUi.inForce(clip), { owner: clip.username, opened: true })}><video class="ovv-player" data-ov-player${miniAttr(clip.title || 'Clip', clip.source_streamer_display_name || clip.display_name || clip.username, watchPath, fileOf(clip))} controls preload="metadata" playsinline${avatarAttr(clip.username, config.networkUrl)}${posterAttr(httpsUrl(clip.thumbnail_url))} src="${fileOf(clip) || ''}" data-ovv-video${nextAttr}${viewAttr}${hlsAttr}></video></div>`}
<div class="ovv-head">
${titleLine(aiClip ? 'AI clip' : 'Clip', clip.title || 'Clip')}
${labelsUi.chips(labelsUi.inForce(clip))}
ddiff --git a/test/labels-ui.test.js b/test/labels-ui.test.js
iindex 69f878a..69a025b 100644
---- a/test/labels-ui.test.js
++++ b/test/labels-ui.test.js
@@@ -145,7 +145,7 @@ function hreq(base, host, path, { method = 'GET', cookie, form, body, type, same
const v = await video('/v/301');
const more = (v.text.split('<section class="ovv-panel ovv-also"')[1] || '').split('</section>')[0];
// The video may come along (the small player): it carries its title, who made it and its own page.
-- assert.match(v.text, /<video class="ovv-player" data-ov-player data-ov-mini data-ov-mini-title="[^"]+" data-ov-mini-by="[^"]*" data-ov-mini-page="\/(?:watch\?v=[^"]+|v\/301)"/, 'a recording says it may come along');
++ assert.match(v.text, /<video class="ovv-player" data-ov-player data-ov-mini data-ov-mini-title="[^"]+" data-ov-mini-by="[^"]*" data-ov-mini-page="\/(?:watch\?v=[^"]+|v\/301)"(?: data-ov-mini-src="[^"]+")?/, 'a recording says it may come along');
assert.match(v.text, /<script src="[^"]*mini[^"]*\.js[^"]*" defer><\/script>/, 'every Video page loads the small player');
assert.ok(!/Kim labelled/.test(more), 'never the recording playing');
assert.ok(!/Kim clip/.test(more), 'its own clips are in Clips from this stream, not again here');
ddiff --git a/test/video-pages.test.js b/test/video-pages.test.js
iindex 931a045..9aece0c 100644
---- a/test/video-pages.test.js
++++ b/test/video-pages.test.js
@@@ -348,7 +348,7 @@ function countOccurrences(haystack, needle) {
assert.ok(r.text.includes('playsinline'));
assert.ok(r.text.includes('data-ovv-video'));
// The network's player (openvibe-shared player.js/css): marked, and both files load on the page.
-- assert.ok(/<video class="ovv-player" data-ov-player data-ov-mini data-ov-mini-title="[^"]+" data-ov-mini-by="[^"]*" data-ov-mini-page="[^"]+" controls /.test(r.text), 'the video takes the network player, and may come along in the small player');
++ assert.ok(/<video class="ovv-player" data-ov-player data-ov-mini data-ov-mini-title="[^"]+" data-ov-mini-by="[^"]*" data-ov-mini-page="[^"]+" data-ov-mini-src="[^"]+" controls /.test(r.text), 'the video takes the network player, and may come along in the small player');
// The streamer's face for an audio-only recording (openvibe-shared 4.90 player.js, plan R4): Network's avatar URL.
assert.match(r.text, /<video class="ovv-player"[^>]* data-ov-avatar="[^"]+\/avatar\/streamer"/, 'the player knows the streamer\'s face');
assert.ok(/<link rel="stylesheet" href="\/shared\/player\.css\?v=[0-9a-f]+">/.test(r.text) && /<script src="\/shared\/player\.js\?v=[0-9a-f]+" defer><\/script>/.test(r.text), 'player.css and player.js load');