diff --git a/ffmpeg.go b/ffmpeg.go index d32656f46..8c91492f9 100644 --- a/ffmpeg.go +++ b/ffmpeg.go @@ -39,7 +39,6 @@ func showStreamOfflineState(configuration Config) { streamMaps = append(streamMaps, fmt.Sprintf("v:%d", index)) videoMapsString = strings.Join(videoMaps, " ") } - } framerate := 25 @@ -48,29 +47,32 @@ func showStreamOfflineState(configuration Config) { ffmpegFlags := []string{ "-hide_banner", - "-stream_loop 5000", + // "-stream_loop 100", + // "-fflags", "+genpts", "-i", configuration.VideoSettings.OfflineImage, + "-i", "webroot/thumbnail.png", + "-filter_complex", "\"[0:v]scale=2640:2360[bg];[bg][1:v]overlay=200:250:enable='between(t,0,3)'\"", videoMapsString, // All the different video variants "-f hls", - "-hls_list_size " + strconv.Itoa(configuration.Files.MaxNumberInPlaylist), - "-hls_time " + strconv.Itoa(configuration.VideoSettings.ChunkLengthInSeconds), - "-strftime 1", - "-use_localtime 1", + // "-hls_list_size " + strconv.Itoa(configuration.Files.MaxNumberInPlaylist), + "-hls_time 4", // + strconv.Itoa(configuration.VideoSettings.ChunkLengthInSeconds), "-hls_playlist_type", "event", "-master_pl_name", "stream.m3u8", + "-strftime 1", "-use_localtime 1", - "-hls_flags program_date_time+temp_file", + "-hls_flags temp_file", "-tune", "zerolatency", - "-framerate " + strconv.Itoa(framerate), "-g " + strconv.Itoa(framerate*2), " -keyint_min " + strconv.Itoa(framerate*2), // multiply your output frame rate * 2. For example, if your input is -framerate 30, then use -g 60 + "-framerate " + strconv.Itoa(framerate), "-preset " + configuration.VideoSettings.EncoderPreset, "-sc_threshold 0", // don't create key frames on scene change - only according to -g - "-profile:v", "high", // Main – for standard definition (SD) to 640×480, High – for high definition (HD) to 1920×1080 - "-movflags +faststart", + "-profile:v", "main", // Main – for standard definition (SD) to 640×480, High – for high definition (HD) to 1920×1080 + // "-movflags +faststart", "-pix_fmt yuv420p", streamMappingString, "-hls_segment_filename " + path.Join(outputDir, "offline-%s.ts"), + // "-s", "720x480", // size variantPlaylistName, } @@ -83,7 +85,6 @@ func showStreamOfflineState(configuration Config) { _, err := exec.Command("sh", "-c", ffmpegCmd).Output() fmt.Println(err) verifyError(err) - } func startFfmpeg(configuration Config) { @@ -126,7 +127,8 @@ func startFfmpeg(configuration Config) { streamMappingString = "-var_stream_map \"" + strings.Join(streamMaps, " ") + "\"" ffmpegFlags := []string{ "-hide_banner", - "-re", + // "-re", + "-fflags", "+genpts", "-i pipe:", // "-vf scale=900:-2", // Re-enable in the future with a config to togging resizing? // "-sws_flags fast_bilinear", @@ -150,6 +152,7 @@ func startFfmpeg(configuration Config) { "-hls_segment_filename " + path.Join(outputDir, "stream-%Y%m%d-%s.ts"), "-hls_flags delete_segments+program_date_time+temp_file", "-tune zerolatency", + // "-s", "720x480", // size streamMappingString, variantPlaylistName, diff --git a/static/logo-900x720.png b/static/logo-900x720.png new file mode 100644 index 000000000..24acf3e00 Binary files /dev/null and b/static/logo-900x720.png differ diff --git a/static/offline.m4v b/static/offline.m4v new file mode 100644 index 000000000..0f8ce537a Binary files /dev/null and b/static/offline.m4v differ diff --git a/webroot/index.html b/webroot/index.html index 7d6a845f2..a8ce1fea5 100644 --- a/webroot/index.html +++ b/webroot/index.html @@ -8,10 +8,9 @@ - - + - + @@ -73,7 +72,7 @@ GW TODO: playsinline muted poster="/thumbnail.png" - data-setup='{}' + data-setup='{"vhs": { "enableLowInitialPlaylist": true, "smoothQualityChange": true, "handlePartialData": true }}' > @@ -156,12 +155,12 @@ GW TODO: + - \ No newline at end of file diff --git a/webroot/js/app.js b/webroot/js/app.js index edc63e56f..d485d653c 100644 --- a/webroot/js/app.js +++ b/webroot/js/app.js @@ -20,9 +20,6 @@ async function setupApp() { }, }); - // style hackings - window.VIDEOJS_NO_DYNAMIC_STYLE = true; - // init messaging interactions var appMessagingMisc = new Messaging(); appMessagingMisc.init(); @@ -43,14 +40,7 @@ async function getStatus() { // The stream was offline, but now it's online. Force start of playback after an arbitrary // delay to make sure the stream has actual data ready to go. setTimeout(function () { - try { - const player = videojs('video'); - player.src(player.src()); // Reload the same video - player.load(); - player.play(); - } catch (e) { - console.log(e) - } + restartPlayer(); }, 3000) } @@ -117,11 +107,5 @@ function setupWebsocket() { setupApp() -// Wait until the player is setup before we start polling status -videojs.hookOnce('setup', function (player) { - getStatus(); - setInterval(getStatus, 5000); -}); - setupWebsocket() diff --git a/webroot/js/player/player.js b/webroot/js/player/player.js new file mode 100644 index 000000000..53b2d6930 --- /dev/null +++ b/webroot/js/player/player.js @@ -0,0 +1,66 @@ +// style hackings +window.VIDEOJS_NO_DYNAMIC_STYLE = true; + +var waitingTimeoutTimer; + +// Wait until the player is setup before we start polling status +videojs.hookOnce('setup', function (player) { + // console.log('setup') + getStatus(); + setInterval(getStatus, 5000); + setupPlayerEventHandlers(); +}); + +function setupPlayerEventHandlers() { + const player = videojs('video'); + + player.on('error', function (e) { + console.log(e); + }) + + player.on('loadeddata', function (e) { + console.log("loadeddata"); + }) + + player.on('ended', function (e) { + console.log("ended"); + }) + + // player.on('abort', function (e) { + // console.log("abort"); + // }) + + // player.on('durationchange', function (e) { + // console.log("durationchange"); + // }) + + // player.on('stalled', function (e) { + // console.log("stalled"); + // }) + + player.on('playing', function (e) { + // console.log("playing"); + clearTimeout(waitingTimeoutTimer); + }) + + player.on('waiting', function (e) { + // console.log("waiting"); + + // waitingTimeoutTimer = setTimeout(function () { + // restartPlayer(); + // }, 3000) + }) +} + +function restartPlayer() { + try { + const player = videojs('video'); + + player.src(player.src()); // Reload the same video + player.load(); + player.play(); + } catch (e) { + console.log(e) + } + +} \ No newline at end of file