Add posters script ot display background image with thumbnail of stream

master
Thomas Lynch 2 years ago
parent 562aec2a05
commit 8bf857fc5b
No known key found for this signature in database
GPG Key ID: FBAB081F9B6E14B2
  1. 32
      nginx/www/stream/dash.html
  2. 33
      nginx/www/stream/hls.html
  3. BIN
      nginx/www/stream/offline.png
  4. 17
      posters.sh

@ -17,6 +17,8 @@ body::after{ position: absolute; width: 100%; height: 100%; content: ""; z-index
video, #video{max-width:100%;max-height:100%;display:flex;margin:0 auto;width:calc(100% - 400px); height: 100%;}
a,a:visited {color:unset;}
#chat{width: 400px;height: 100vh;align-self: start;}
#viewers{position:absolute;top:0;left:3px;width:5em;height:1.5em;z-index:1}
.vjs-modal-dialog-content, .vjs-error .vjs-error-display::before{display:none;}
@media only screen and (max-width:600px) {
#chat{width: 100%;max-width: 100%;}
.main{flex-direction: column;max-height: 100%;}
@ -30,12 +32,16 @@ a,a:visited {color:unset;}
<body>
<noscript>JavaScript is required for video playback.</noscript>
<div class="main">
<iframe id="viewers"
title="viewers"
frameBorder="0"
marginheight="0"
src="/viewers/tom.txt">
</iframe>
<video id="video"
class="video-js vjs-default-skin"
class="video-js vjs-default-skin vjs-big-play-centered"
controls
preload="auto"
style=""
data-setup='{}'>
preload="auto">
</video>
<iframe id="chat"
title="irc"
@ -57,8 +63,21 @@ a,a:visited {color:unset;}
</div>
<script>
const source = window.location.search.substr(1) || 'tom';
const chat = document.getElementById('chat');
chat.src = chat.src.replace('@tom', `@${source}`);
const viewers = document.getElementById('viewers');
viewers.src= viewers.src.replace('/tom', `/${source}`);
viewers.addEventListener("load", () => {
const style = document.createElement('style');
style.textContent = `pre,body{margin:0;padding:0;color:white;text-shadow: 1px 1px 2px black;}`;
viewers.contentDocument.body.appendChild(style);
});
const video = document.getElementById('video');
video.setAttribute('poster', `/posters/${source}.jpg`);
document
.getElementById('footer')
.querySelectorAll('div:first-of-type a:not(:last-child)')
@ -71,15 +90,18 @@ document
}
});
window.HELP_IMPROVE_VIDEOJS = false;
const player = videojs('video', {
html5: {
vhs: {
experimentalBufferBasedABR: true,
liveRangeSafeTimeDelta: 10,
handlePartialData: true,
allowSeeksWithinUnsafeLiveWindow: true,
},
},
liveTracker: {
trackingThreshold: 5,
},
liveui: true,
autoplay: 'any',
});

@ -17,6 +17,9 @@ body::after{ position: absolute; width: 100%; height: 100%; content: ""; z-index
video, #video{max-width:100%;max-height:100%;display:flex;margin:0 auto;width:calc(100% - 400px); height: 100%;}
a,a:visited {color:unset;}
#chat{width: 400px;height: 100vh;align-self: start;}
#viewers{position:absolute;top:0;left:3px;width:5em;height:1.5em;z-index:1}
.vjs-modal-dialog-content, .vjs-error .vjs-error-display::before{display:none;}
.vjs-modal-dialog-content{display:none;}
@media only screen and (max-width:600px) {
#chat{width: 100%;max-width: 100%;}
.main{flex-direction: column;max-height: 100%;}
@ -30,12 +33,16 @@ a,a:visited {color:unset;}
<body>
<noscript>JavaScript is required for video playback.</noscript>
<div class="main">
<iframe id="viewers"
title="viewers"
frameBorder="0"
marginheight="0"
src="/viewers/tom.txt">
</iframe>
<video id="video"
class="video-js vjs-default-skin"
class="video-js vjs-default-skin vjs-big-play-centered"
controls
preload="auto"
style=""
data-setup='{}'>
preload="auto">
</video>
<iframe id="chat"
title="irc"
@ -57,8 +64,21 @@ a,a:visited {color:unset;}
</div>
<script>
const source = window.location.search.substr(1) || 'tom';
const chat = document.getElementById('chat');
chat.src = chat.src.replace('@tom', `@${source}`);
const viewers = document.getElementById('viewers');
viewers.src= viewers.src.replace('/tom', `/${source}`);
viewers.addEventListener("load", () => {
const style = document.createElement('style');
style.textContent = `pre,body{margin:0;padding:0;color:white;text-shadow: 1px 1px 2px black;}`;
viewers.contentDocument.body.appendChild(style);
});
const video = document.getElementById('video');
video.setAttribute('poster', `/posters/${source}.jpg`);
document
.getElementById('footer')
.querySelectorAll('div:first-of-type a:not(:last-child)')
@ -71,15 +91,18 @@ document
}
});
window.HELP_IMPROVE_VIDEOJS = false;
const player = videojs('video', {
html5: {
vhs: {
experimentalBufferBasedABR: true,
liveRangeSafeTimeDelta: 10,
handlePartialData: true,
allowSeeksWithinUnsafeLiveWindow: true,
},
},
liveTracker: {
trackingThreshold: 5,
},
liveui: true,
autoplay: 'any',
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

@ -0,0 +1,17 @@
#!/bin/bash
# create "poster" files for an image preview if livestream before the user clicks play
# get all live streams
all_live=`ls /tmp/hls/*.m3u8 | cut -d/ -f4 | cut -d. -f1 | uniq`
# for each streamer, make a poster of their latest video chunk
while read -r streamer
do
tsfile=`bash -c "ls -t /tmp/hls/$streamer-*.ts" | head -n1`
ffmpeg -hide_banner -loglevel error -y \
-ss 00:00:00.00 -i "$tsfile" \
-frames:v 1 "/var/www/stream/posters/$streamer.jpg" < /dev/null;
done <<< "$all_live"
# delete old posters
bash -c 'find /var/www/stream/posters/* -mmin +2 -exec rm {} \;'
Loading…
Cancel
Save