mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-04 18:09:12 +03:00
Broken seek to time function, on HLS feed.. jellyfin HLS controller creates Invalid M3U8 files #2900
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @davesargrad on GitHub (Apr 7, 2021).
Hi. I have jellyfin running.
I used these instructions to get Jellyfin running on a fresh k8s 1.20 cluster.
I am able to play a 1650x1022 video back using the following HLS URL:
http://chad.corp.sensis.com:32004/Videos/75510f1b6c3d24954abec73b2329806c/main.m3u8?api_key=c6bf7f6eca6d458ebaed741a677e5699
I find that the playback is a bit sluggish. I also find that "seekto a point in time" fails to _seek, or succeeds, but only after several minutes.
One tell-tale issue I see is in the Jellyfin server log:

I see this happen whenever I click on the function that should seek to a point in time.
[12:43:53] [WRN] [429] Jellyfin.Api.Controllers.DynamicHlsController: cannot serve /config/transcodes/7bfcae043c5fb93c677b4fcd2b82600554.ts as it doesn't exist and no transcode is runningA quick search of the Jellyfin issue database uncovered this. Is ffmpeg not part of the Jellyfin image that I picked up from docker? Shouldnt it be?
I currently use ReactPlayer to playback my Jellyfin HLS stream. This seems to work ok for the basic video playback function on the HLS stream that Jellyfin serves.
However I am not able to reliably seek to a given point in time.
I am able to perform functions such as "seek" just fine on other movies that I HLS stream from a Jellyfin instance outside of kubernetes. I also have no problem streaming with this player from a variety of video sources, including HLS sources.
I need help isolating this extremely sluggish response to functions such as "seek to a point in time"
Question 1:
Why does the "zoom to a point in time" fail?
Question 2:
What logs can I view to see how Jellyfin is responding to commands that should govern which portion of the HLS stream are being streamed?
Question 3:
Given that the transcode is not found, and given issues such as this, is ffmpeg not part of the Jellyfin image that I picked up from docker? Shouldnt it be?
Server System (please complete the following information):
Client System (please complete the following information):

Chrome:
@davesargrad commented on GitHub (Apr 7, 2021):
I just realized.. that the reason that "seek" may be because React Player doesnt support Jellyfin. I'm not sure though since it seems to work at times.
I just posted an issue on the React Player issue database to see what I can learn from there. I didnt think of it but it may be that a React Player Jellyfin HLS plugin is required to implement the seek function.
@davesargrad commented on GitHub (Apr 8, 2021):
I just verified that playback of the Jellyfin HLS stream works fine with ReactPlayer. My application works just fine as it streams HLS feeds from a Jellyfin instance that I stood up on a VirtualBox machine, rather than on kubernetes. I am able to "seek", "rewind", "fast-forward", "slow-forward", etc. Today I will see if I can isolate the problem. I'm still hoping to get thoughts from any of the Jellyfin experts, as to why "seek" and "fast-forward" functions might fail for streams I am receiving from my Jellyfin instance running inside kubernetes.
I've tweaked the words of the issue, to ensure that its clear that I dont really see this as a ReactPlayer problem.
@davesargrad commented on GitHub (Apr 8, 2021):
I just viewed the log from the jellyfin runtime service.. Every time I click on the "seek" function I see the following:
[12:43:53] [WRN] [429] Jellyfin.Api.Controllers.DynamicHlsController: cannot serve /config/transcodes/7bfcae043c5fb93c677b4fcd2b82600554.ts as it doesn't exist and no transcode is runningI see related issues such as this one.
@davesargrad commented on GitHub (Apr 8, 2021):
@davesargrad commented on GitHub (Apr 8, 2021):
Am I using the wrong docker image:
image: docker.io/jellyfin/jellyfin
@davesargrad commented on GitHub (Apr 8, 2021):
@davesargrad commented on GitHub (Apr 8, 2021):
The linuxserver docker image seemed to sort of fix my "seek" problem, it at least fixed the "ffmpeg missing" problem
LinuxServer.io image: linuxserver/jellyfinI still see a huge lag on the delay function (10's of seconds). How do I isolate and refine why it takes so long to seek to a given time in my video?
Notice I now see this message:
@davesargrad commented on GitHub (Apr 8, 2021):
From the time I clicked on seek, it took about 15 seconds before I saw this in the jellyfin log
Then I waited for a while, but the video did not actually start playing again at that time.. so something still lurks.
It looks like ffmpeg is creating the TS and M3U8 files.. Does the jellyfin HLS controller log each command that says "download this TS file"?
@davesargrad commented on GitHub (Apr 8, 2021):
The video I am trying to play back is about 13 minutes long. I just noticed that when I get into this failure mode, I can seek the start of the video. I can also seek to about 8 or 9 minutes in. In those two cases the video starts to play immediately at those times. Its when I seek to times between around 2 and 7 minutes, that the video does not start to play. Its almost as if there is a series of TS files missing.
I just played the file from start to finish, and it played without any missing data.. so as long as i simply leave the video running the whole thing plays. This implies that there are no missing TS files.
I'm scratching my head here... and could use some suggestions from the experts.
@davesargrad commented on GitHub (Apr 8, 2021):
I find the network timing, and gaps seemingly interesting.. The play actually continues during those times where there seems to be gaps.
This run was from the start.. and for a couple of minutes

This is a separate run from the start.. and for a couple of minutes

In both cases I seemed to see all the data displayed.. I think this means the "ts" files are being cached in the browser (and hence they are not requested from the service)... not sure though. Along with this I have noticed that if I wait long enough, and play through the file multiple times, then the seeks seem to happen faster and faster .. and more and more reliably.
@davesargrad commented on GitHub (Apr 8, 2021):
Here is some more data. I deleted my jellyfin deployment.. i reinstantiated it. I cleared the browser cache.
I registered the same media folder and image. I streamed it to the browser.. from time 0.
Within just a few seconds I found 64 ts files and 1 m3u8 file in the transcodes folder.
I monitored the entire sequence of ts requests/responses in the browser diagnostic tools. There were no gaps. All of the 64 TS files were requested and downloaded in a timely fashion. Each TS files was roughly 12 to 23 seconds in duration.
I am a bit perplexed when I see the 63rd TS file requested, I sort of expected that to be the last request since it was the end of file.
I see continued requests and indeed now I see additional TS files
@davesargrad commented on GitHub (Apr 8, 2021):
This is the part I really find interesting.
The m3u8 file that is currently in the jellyfin config/data/transcodes folder has 34 TS entries.
The initial had 64 entries. The sum of those two is 98. Indeed there are currently 98 TS files in that folder

I guess my question is.. is the m3u8 file getting "corrupted" somehow? It seems to change at the end of the played file.
@davesargrad commented on GitHub (Apr 8, 2021):
I think I am close. I dont know why the m3u8 file is overwritten. I am doing a very controlled experiment to see that this happens again and again in a somewhat repeatable fashion.
For this run, this is the first ffmpeg log
[root@qatar log]# cat FFmpeg.Remux-2021-04-08_16-40-12__4c4d9f27.log
/Videos/75510f1b6c3d24954abec73b2329806c/hls1/main/0.ts
{"Protocol":0,"Id":"75510f1b6c3d24954abec73b2329806c","Path":"/data/media/videos/Hamburg/North/HamburgNorth.mp4","EncoderPath":null,"EncoderProtocol":null,"Type":0,"Container":"mov,mp4,m4a,3gp,3g2,mj2","Size":436275259,"Name":"HamburgNorth","IsRemote":false,"ETag":"543b6ca4c9f21c87d81daf7a932499c0","RunTimeTicks":8138162000,"ReadAtNativeFramerate":false,"IgnoreDts":false,"IgnoreIndex":false,"GenPtsInput":false,"SupportsTranscoding":true,"SupportsDirectStream":true,"SupportsDirectPlay":true,"IsInfiniteStream":false,"RequiresOpening":false,"OpenToken":null,"RequiresClosing":false,"LiveStreamId":null,"BufferMs":null,"RequiresLooping":false,"SupportsProbing":true,"VideoType":0,"IsoType":null,"Video3DFormat":null,"MediaStreams":[{"Codec":"h264","CodecTag":"avc1","Language":"und","ColorRange":null,"ColorSpace":null,"ColorTransfer":null,"ColorPrimaries":null,"Comment":null,"TimeBase":"1/10000","CodecTimeBase":"1/20","Title":null,"VideoRange":"SDR","localizedUndefined":null,"localizedDefault":null,"localizedForced":null,"DisplayTitle":"1080p H264 SDR","NalLengthSize":"0","IsInterlaced":false,"IsAVC":false,"ChannelLayout":null,"BitRate":4284669,"BitDepth":8,"RefFrames":1,"PacketLength":null,"Channels":null,"SampleRate":null,"IsDefault":true,"IsForced":false,"Height":1022,"Width":1650,"AverageFrameRate":10,"RealFrameRate":10,"Profile":"Constrained Baseline","Type":1,"AspectRatio":"825:511","Index":0,"Score":null,"IsExternal":false,"DeliveryMethod":null,"DeliveryUrl":null,"IsExternalUrl":null,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Path":null,"PixelFormat":"yuv420p","Level":40,"IsAnamorphic":null},{"Codec":"aac","CodecTag":"mp4a","Language":"und","ColorRange":null,"ColorSpace":null,"ColorTransfer":null,"ColorPrimaries":null,"Comment":null,"TimeBase":"1/44100","CodecTimeBase":"1/44100","Title":null,"VideoRange":null,"localizedUndefined":null,"localizedDefault":null,"localizedForced":null,"DisplayTitle":"Und - AAC - Mono - Default","NalLengthSize":null,"IsInterlaced":false,"IsAVC":null,"ChannelLayout":"mono","BitRate":1378,"BitDepth":null,"RefFrames":null,"PacketLength":null,"Channels":1,"SampleRate":44100,"IsDefault":true,"IsForced":false,"Height":null,"Width":null,"AverageFrameRate":null,"RealFrameRate":null,"Profile":"LC","Type":0,"AspectRatio":null,"Index":1,"Score":null,"IsExternal":false,"DeliveryMethod":null,"DeliveryUrl":null,"IsExternalUrl":null,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Path":null,"PixelFormat":null,"Level":0,"IsAnamorphic":null}],"MediaAttachments":[],"Formats":[],"Bitrate":4288685,"Timestamp":null,"RequiredHttpHeaders":{},"TranscodingUrl":null,"TranscodingSubProtocol":null,"TranscodingContainer":null,"AnalyzeDurationMs":null,"DefaultAudioStreamIndex":null,"DefaultSubtitleStreamIndex":null}
/usr/lib/jellyfin-ffmpeg/ffmpeg -fflags +genpts -f mov,mp4,m4a,3gp,3g2,mj2 -i file:"/data/media/videos/Hamburg/North/HamburgNorth.mp4" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -start_at_zero -vsync -1 -codec:a:0 copy -strict -2 -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b826005%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b826005.m3u8"
ffmpeg version 4.3.1-Jellyfin Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 9 (Ubuntu 9.3.0-17ubuntu1~20.04)
configuration: --prefix=/usr/lib/jellyfin-ffmpeg --target-os=linux --extra-version=Jellyfin --disable-doc --disable-ffplay --disable-shared --disable-libxcb --disable-sdl2 --disable-xlib --enable-gpl --enable-version3 --enable-static --enable-libfontconfig --enable-fontconfig --enable-gmp --enable-gnutls --enable-libass --enable-libbluray --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libdav1d --enable-libwebp --enable-libvpx --enable-libx264 --enable-libx265 --enable-libzvbi --enable-libzimg --arch=amd64 --enable-opencl --enable-vaapi --enable-amf --enable-libmfx --enable-vdpau --enable-cuda --enable-cuda-llvm --enable-cuvid --enable-nvenc --enable-nvdec --enable-ffnvcodec
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'file:/data/media/videos/Hamburg/North/HamburgNorth.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp41isom
creation_time : 2021-03-19T11:51:09.000000Z
Duration: 00:13:33.82, start: 0.000000, bitrate: 4288 kb/s
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1650x1022 [SAR 1:1 DAR 825:511], 4284 kb/s, 10 fps, 10 tbr, 10k tbn, 20 tbc (default)
Metadata:
creation_time : 2021-03-19T11:51:09.000000Z
handler_name : VideoHandler
encoder : AVC Coding
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 1 kb/s (default)
Metadata:
creation_time : 2021-03-19T11:51:09.000000Z
handler_name : SoundHandler
Output #0, hls, to '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b826005.m3u8':
Metadata:
encoder : Lavf58.45.100
Stream #0:0: Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1650x1022 [SAR 1:1 DAR 825:511], q=2-31, 4284 kb/s, 10 fps, 10 tbr, 90k tbn, 10 tbc (default)
Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 1 kb/s (default)
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b8260050.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b8260051.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b8260052.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b8260053.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b8260054.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b8260055.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b8260056.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b8260057.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b8260058.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b8260059.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600510.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600511.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600512.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600513.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600514.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600515.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600516.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600517.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600518.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600519.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600520.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600521.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600522.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600523.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600524.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600525.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600526.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600527.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600528.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600529.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600530.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600531.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600532.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600533.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600534.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600535.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600536.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600537.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600538.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600539.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600540.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600541.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600542.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600543.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600544.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600545.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600546.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600547.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600548.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600549.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600550.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600551.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600552.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600553.ts' for writing
frame= 6915 fps=0.0 q=-1.0 size=N/A time=00:11:31.50 bitrate=N/A speed=1.38e+03x
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600554.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600555.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600556.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600557.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600558.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600559.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600560.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600561.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600562.ts' for writing
[hls @ 0x556aa3a3c5c0] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600563.ts' for writing
frame= 8138 fps=0.0 q=-1.0 Lsize=N/A time=00:13:33.80 bitrate=N/A speed=1.39e+03x
video:425643kB audio:137kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
1] Why is the m3u8 updated?
2] Why does it contain fewer TS entries?
See here.
@davesargrad commented on GitHub (Apr 8, 2021):
Here is the log for the updated m3u8 file
Notice that it occurs about 16 minutes after the first log was generated.
[root@qatar log]# cat FFmpeg.Remux-2021-04-08_16-56-26__2a5ec543.log
/Videos/75510f1b6c3d24954abec73b2329806c/hls1/main/64.ts
{"Protocol":0,"Id":"75510f1b6c3d24954abec73b2329806c","Path":"/data/media/videos/Hamburg/North/HamburgNorth.mp4","EncoderPath":null,"EncoderProtocol":null,"Type":0,"Container":"mov,mp4,m4a,3gp,3g2,mj2","Size":436275259,"Name":"HamburgNorth","IsRemote":false,"ETag":"543b6ca4c9f21c87d81daf7a932499c0","RunTimeTicks":8138162000,"ReadAtNativeFramerate":false,"IgnoreDts":false,"IgnoreIndex":false,"GenPtsInput":false,"SupportsTranscoding":true,"SupportsDirectStream":true,"SupportsDirectPlay":true,"IsInfiniteStream":false,"RequiresOpening":false,"OpenToken":null,"RequiresClosing":false,"LiveStreamId":null,"BufferMs":null,"RequiresLooping":false,"SupportsProbing":true,"VideoType":0,"IsoType":null,"Video3DFormat":null,"MediaStreams":[{"Codec":"h264","CodecTag":"avc1","Language":"und","ColorRange":null,"ColorSpace":null,"ColorTransfer":null,"ColorPrimaries":null,"Comment":null,"TimeBase":"1/10000","CodecTimeBase":"1/20","Title":null,"VideoRange":"SDR","localizedUndefined":null,"localizedDefault":null,"localizedForced":null,"DisplayTitle":"1080p H264 SDR","NalLengthSize":"0","IsInterlaced":false,"IsAVC":false,"ChannelLayout":null,"BitRate":4284669,"BitDepth":8,"RefFrames":1,"PacketLength":null,"Channels":null,"SampleRate":null,"IsDefault":true,"IsForced":false,"Height":1022,"Width":1650,"AverageFrameRate":10,"RealFrameRate":10,"Profile":"Constrained Baseline","Type":1,"AspectRatio":"825:511","Index":0,"Score":null,"IsExternal":false,"DeliveryMethod":null,"DeliveryUrl":null,"IsExternalUrl":null,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Path":null,"PixelFormat":"yuv420p","Level":40,"IsAnamorphic":null},{"Codec":"aac","CodecTag":"mp4a","Language":"und","ColorRange":null,"ColorSpace":null,"ColorTransfer":null,"ColorPrimaries":null,"Comment":null,"TimeBase":"1/44100","CodecTimeBase":"1/44100","Title":null,"VideoRange":null,"localizedUndefined":null,"localizedDefault":null,"localizedForced":null,"DisplayTitle":"Und - AAC - Mono - Default","NalLengthSize":null,"IsInterlaced":false,"IsAVC":null,"ChannelLayout":"mono","BitRate":1378,"BitDepth":null,"RefFrames":null,"PacketLength":null,"Channels":1,"SampleRate":44100,"IsDefault":true,"IsForced":false,"Height":null,"Width":null,"AverageFrameRate":null,"RealFrameRate":null,"Profile":"LC","Type":0,"AspectRatio":null,"Index":1,"Score":null,"IsExternal":false,"DeliveryMethod":null,"DeliveryUrl":null,"IsExternalUrl":null,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Path":null,"PixelFormat":null,"Level":0,"IsAnamorphic":null}],"MediaAttachments":[],"Formats":[],"Bitrate":4288685,"Timestamp":null,"RequiredHttpHeaders":{},"TranscodingUrl":null,"TranscodingSubProtocol":null,"TranscodingContainer":null,"AnalyzeDurationMs":null,"DefaultAudioStreamIndex":null,"DefaultSubtitleStreamIndex":null}
/usr/lib/jellyfin-ffmpeg/ffmpeg -ss 00:06:24.000 -fflags +genpts -noaccurate_seek -f mov,mp4,m4a,3gp,3g2,mj2 -i file:"/data/media/videos/Hamburg/North/HamburgNorth.mp4" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -start_at_zero -vsync -1 -codec:a:0 copy -strict -2 -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type mpegts -start_number 64 -hls_segment_filename "/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b826005%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b826005.m3u8"
ffmpeg version 4.3.1-Jellyfin Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 9 (Ubuntu 9.3.0-17ubuntu1~20.04)
configuration: --prefix=/usr/lib/jellyfin-ffmpeg --target-os=linux --extra-version=Jellyfin --disable-doc --disable-ffplay --disable-shared --disable-libxcb --disable-sdl2 --disable-xlib --enable-gpl --enable-version3 --enable-static --enable-libfontconfig --enable-fontconfig --enable-gmp --enable-gnutls --enable-libass --enable-libbluray --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libdav1d --enable-libwebp --enable-libvpx --enable-libx264 --enable-libx265 --enable-libzvbi --enable-libzimg --arch=amd64 --enable-opencl --enable-vaapi --enable-amf --enable-libmfx --enable-vdpau --enable-cuda --enable-cuda-llvm --enable-cuvid --enable-nvenc --enable-nvdec --enable-ffnvcodec
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'file:/data/media/videos/Hamburg/North/HamburgNorth.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp41isom
creation_time : 2021-03-19T11:51:09.000000Z
Duration: 00:13:33.82, start: 0.000000, bitrate: 4288 kb/s
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1650x1022 [SAR 1:1 DAR 825:511], 4284 kb/s, 10 fps, 10 tbr, 10k tbn, 20 tbc (default)
Metadata:
creation_time : 2021-03-19T11:51:09.000000Z
handler_name : VideoHandler
encoder : AVC Coding
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 1 kb/s (default)
Metadata:
creation_time : 2021-03-19T11:51:09.000000Z
handler_name : SoundHandler
Output #0, hls, to '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b826005.m3u8':
Metadata:
encoder : Lavf58.45.100
Stream #0:0: Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1650x1022 [SAR 1:1 DAR 825:511], q=2-31, 4284 kb/s, 10 fps, 10 tbr, 90k tbn, 10 tbc (default)
Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 1 kb/s (default)
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600564.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600565.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600566.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600567.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600568.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600569.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600570.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600571.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600572.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600573.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600574.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600575.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600576.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600577.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600578.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600579.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600580.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600581.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600582.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600583.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600584.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600585.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600586.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600587.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600588.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600589.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600590.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600591.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600592.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600593.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600594.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600595.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600596.ts' for writing
[hls @ 0x55a0f5d5d600] Opening '/config/data/transcodes/7bfcae043c5fb93c677b4fcd2b82600597.ts' for writing
frame= 4298 fps=0.0 q=-1.0 Lsize=N/A time=00:13:33.80 bitrate=N/A speed=2.51e+03x
video:224807kB audio:72kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
I feel like I'm close.. yet confused.
So this may not be the only problem.. but it seems like it relates strongly to the fact that "seeks" are unreliable.
@davesargrad commented on GitHub (Apr 8, 2021):
Ok. The jellyfin server actually responds to a request for an m3u8 file with the following file

This has many more TS entries (135.ts is the last entry I see)

So it seems as if the total number of TS files in the transcodes folder (98) is short. It also seems that the m3u8 file that is there, only addresses a portion of the data.
@davesargrad commented on GitHub (Apr 8, 2021):
To me this feels like a bug in the HLS controller.
@cvium commented on GitHub (Apr 8, 2021):
There's a lot going on here and I don't have time to go through it all but I can give you some pointers:
@davesargrad commented on GitHub (Apr 9, 2021):
@cvium
Ty. The very fact that I have your attention is much appreciated. I also appreciate your time sensitivity. I will do my best to provide accurate detail, and if I can also get guidance I will dig as much as I can to help isolate and solve this problem.
I will do my best to respect your time concerns. However I'm also glad to see you respond, it highlights that you are interested in seeing such issues resolved.
The instance is not visible from the internet. And the key is not a concern since this is a test system that i stand up and rip down frequently... The key changes frequently. :)
I do find that the ffmpeg (once spawned) generates files extremely quickly, and the hardware has plenty of resources.
I'm not smart enough about HLS to even begin a proper guess. I have dug carefully for clues both on the client side and on the server side. Furthermore I have enough systems and software engineering experience to be able to help isolate this, if only I can get the right pointers along the way.
The problems I am seeing, I did not see at all with the same client, and with a jellyfin instance running outside k8s. Yet I didnt have enough experience with that configuration to say that the problem wasnt there.
I see enough of the client/server interaction to believe that both are fundamentally able to speak HLS. I've waffled from thinking that this is a server issue to a client issue, and back.
Is it your gut feeling that the problem I am seeing is client side or server side? Are there specific experiments that you can recommend to help me further isolate?
@davesargrad commented on GitHub (Apr 9, 2021):
By the way, I tried to reduce the image size and the frame rate by adding the following to the URL (after the API Key)
&width=825&height=511&framerate=4.0This did not seem to have an effect. I'm not sure those parameters are actually used (I saw them in the API)
I chose the width and height to preserve the aspect ratio. Should these parameters have had an impact on the streamed HLS frames?
Is there a way for me to pregenerate the playlist (TS and M3U8)? So I dont have to generate it again and again?
@davesargrad commented on GitHub (Apr 9, 2021):
I'm trying to set up an experiment using curl.. I have successfully been able to curl the TS files that are listed in the playlist that the client receives. I then diff these against the actual TS files that are in the transcode folder, and I'm able to see that these are the same.
In the following 0.ts is a file I downloaded using curl. I ran diff against the 0'th file in the playlist, and they were the same.
I may be able to set up an experiment where I emulate the client using a command such as curl. I could wrap this in a python script to build out a client emulator. This would allow me to potentially isolate the problem further.
The experiment would have me request the initial playlist, then request each of the segments in order, or out of order. I could then compare the received files to the actual segment files.
It would probably take me a day or two to build this test client, at its core would be commands of the following types:
curl http://chad.corp.sensis.com:32004/Videos/75510f1b6c3d24954abec73b2329806c/main.m3u8?api_key=172a2553ddeb4149958e9fadd42783c2sudo curl -o 1.ts http://chad.corp.sensis.com:32004/Videos/75510f1b6c3d24954abec73b2329806c/hls1/main/1.ts?api_key=172a2553ddeb4149958e9fadd42783c2Then I'd measure timing for receipt of each of the received TS files.. and I'd request many of them in various patterns (to emulate random seeks).
I have noticed that its not the request for the m3u8 file that triggers generation of the TS files. Its the request for a TS file that triggers generation (if the TS files arent in the transcode folder). Its easy to verify this, by deleting all the files in the transcode folder, and then using curl to request a TS file.
@davesargrad commented on GitHub (Apr 9, 2021):
Hi @cvium
Could you please help me to understand this from the client applications perspective. Perhaps this is the core of the issue I am having. If the playlist is not technically valid.
@davesargrad commented on GitHub (Apr 9, 2021):
Added some additional learning to the react-player issue.
@davesargrad commented on GitHub (Apr 12, 2021):
@cvium
I've now tried two different players (ReactPlayer and VideoJS) with the HLS stream provided by Jellyfin. They both can play the content to some extent. However they are both flaky when I begin to use their ability to "seek" positions within the stream.
It strikes me that this may relate to the fact that the playlist is not valid as you mentioned.
At this point I will find a different HLS service. I think I've ruled out the client-side as a source of problem. Its too bad. I found Jellyfin quite attractive at first glance. I just dont think its HLS support is there yet.
I'll post my findings back here once I've integrated an alternative HLS service.
@davesargrad commented on GitHub (Apr 12, 2021):
@cvium
Ok. For the HLS service piece of my architecture, I've now replaced jellyfin with nginx in combination with a background generation (via ffmpeg) of the M3U8 and TS files (which I can easily automate).
My service now works without the flakiness that I saw when using the Jellyfin HLS interface.
At this stage of the game, the issue (in my mind) is clearly the mismatch between the playlist created by the Jellyfin HLS controller, and the specification for HLS.
Until this is fixed, the HLS controller within Jellyfin seems to be unusable as a general purpose HLS service.
@davesargrad commented on GitHub (Apr 12, 2021):
It does strike me that Jellyfin could easily solve this problem, by using the M3U8 created by ffmpeg. FFmpeg could be invoked in the background as content is added, and the static files (m3u8 and ts) could be stored until the user deletes them, or configures them to be deleted through some automated thresholding process. This is a feature that you could disable by default, but enable, when the user configures use of HLS.
@cvium commented on GitHub (Apr 12, 2021):
You should read the spec.
The reason for the "invalid" playlist is that in order to seek forward the playlist has to be complete ie. a VOD playlist. Our playlist is not valid because the
EXTINFduration is supposed to be the duration of the individual segments, BUT we do not know the lengths of the segments beforehand because the transcode happens on-the-fly.Jellyfin is a home media server, not a CDN.
Jellyfin is not a general purpose HLS service...
@davesargrad commented on GitHub (Apr 12, 2021):
@cvium
No need to read the spec.. will not use jellyfin, my only issue with it is that it doesnt serve media very well (at least via HLS), other than that it looks really good... Ty though.