jellyfin / jellyfin-chromecast

Chromecast Client for Jellyfin
https://jellyfin.org
GNU General Public License v2.0
132 stars 40 forks source link

Some Transcoded Videos Only Play for a few Seconds #591

Open kevincox opened 1 month ago

kevincox commented 1 month ago

Describe the bug

When starting some videos that require transcoding the video plays for a few seconds (8?) then stutters for under a second, then after another second or two of playback pauses with a spinner forever. This is consistent by video. However when it stutters you can seek and it will play for a bit again as described before freezing again. So it doesn't seem to be any particular part of the video, just the video itself.

To Reproduce

Cast a video.

Expected behavior

Logs

Here are some example HTTP logs. Notice that the client stops requesting new chunks. There are nofailed requests.

HTTP Logs: ``` 2024-07-15T00:35:08+00:00 GET 200 0.002 /Playback/BitrateTest?size=500000 2024-07-15T00:35:08+00:00 GET 200 0.015 /Users//Items?ImageTypes=Backdrop&IncludeItemTypes=Movie%2CSeries&Limit=1&MaxOfficialRating=PG-13&Recursive=true&SortBy=Random 2024-07-15T00:35:08+00:00 GET 200 0.001 /Items/f01c91147bad9923d970a626c9debfcd/Images/Backdrop/0?tag= 2024-07-15T00:35:09+00:00 GET 200 0.080 /Playback/BitrateTest?size=1000000 2024-07-15T00:35:09+00:00 GET 200 0.117 /Playback/BitrateTest?size=2000000 2024-07-15T00:35:09+00:00 GET 200 0.205 /Playback/BitrateTest?size=4000000 2024-07-15T00:35:10+00:00 GET 200 0.479 /Playback/BitrateTest?size=8000000 2024-07-15T00:35:11+00:00 GET 200 1.114 /Playback/BitrateTest?size=10000000 2024-07-15T00:35:11+00:00 OPTIONS 204 0.000 /Sessions/Capabilities/Full 2024-07-15T00:35:11+00:00 POST 204 0.015 /Sessions/Capabilities/Full 2024-07-15T00:35:26+00:00 GET 200 0.007 /Users//Items/ 2024-07-15T00:35:26+00:00 GET 200 0.008 /Users//Items/ 2024-07-15T00:35:26+00:00 OPTIONS 204 0.000 /Items//PlaybackInfo?MaxStreamingBitrate=43956044&StartTimeTicks=0&UserId= 2024-07-15T00:35:26+00:00 POST 200 0.003 /Items//PlaybackInfo?MaxStreamingBitrate=43956044&StartTimeTicks=0&UserId= 2024-07-15T00:35:27+00:00 GET 200 0.002 /videos/
Server logs: ``` [00:35:28] [INF] [75] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: /nix/store/0dhbk8ylq1im1y87f4j9kdlwp279f5fq-jellyfin-ffmpeg-6.0.1-6-bin/bin/ffmpeg -analyzeduration 200M -probesize 1G -init_hw_device drm=dr:/dev/dri/renderD128 -init_hw_device vaapi=va@dr -init_hw_device vulkan=vk@dr -filter_hw_device vk -hwaccel vaapi -hwaccel_output_format vaapi -noautorotate -i file:"
Transcode log: ``` {"Protocol":0,"Id":"8ecc707f0c37612600e57e1610a54da5","Path":"

System (please complete the following information):

kevincox commented 1 month ago

Here are some more logs from different videos. The result is consistent per source file.

Working

Freezing

kevincox commented 1 month ago

I do see that the bitrate for all of the good videos are lower than the bitrate for all of the bad videos.

bad-1-ffmpeg.log:  bitrate: 9707 kb/s
bad-2-ffmpeg.log:  bitrate: 34653 kb/s
bad-3-ffmpeg.log:  bitrate: 12685 kb/s
good-2-ffmpeg.log: bitrate: 1355 kb/s
good-3-ffmpeg.log: bitrate: 2230 kb/s
good-1-ffmpeg.log: bitrate: 3437 kb/s
kevincox commented 1 month ago

It does seem highly correlated to the bitrate. But I don't think it is the full story. I went through my library and it does seem that there is a pivot point. There is only one exception. I have one video with 9707kbps that doesn't play and one with 9846kbps that does play. But other than those two being "flipped" there is a cutoff point where the videos stopped working.

However I noticed that a lot of the videos that were failing used to work. I had watched them in the past. I also noticed that despite having "Allow encoding in HEVC format" enabled all of the videos are being transcoded to h264. Often despite the original being in h265.

I also found https://developers.google.com/cast/docs/media#chromecast_ultra which doesn't have specific bitrate numbers but it does indicate that the Chromecast Ultra supports "H.264 High Profile up to level 4.2 (1080p/60fps)" and "HEVC / H.265 Main and Main10 Profiles up to level 5.1 (4K/60fps)". So it seems like the h265 decoder for that device can handle a lot more data than the h264 one.

So my theory is that something changed that stopped Jellyfin from direct playing h265 and/or stopped it from transcoding to h265. This results in high bitrate videos causing issues on the Chromecast Ultra h264 encoder.

So I guess the questions are:

  1. Why is h265 not playing directly anymore?
  2. Why is the transcode not targeting h265?

Either of these should resolve my issue. But really both should be solved. I also don't know if the problem is in the Jellyfin server or jellyfin-chromecast.

kevincox commented 1 month ago

Even weirder hardware decoding seems to affect the result. Even doing hardware decoding and software encoding causes it not to play. While software decoding and software encoding works.

kevincox commented 1 month ago

Ah, the difference may be the colour space!

Hardware acceleration enabled: nv12 No hardware acceleration: yuv420p

Also a slight bitrate change, but I doubt that is the problem:

Hardware accelerated: 35342000 Not accelerated: 31425000

In fact it doesn't even seem like it is ever hardware decoding. Only some scaling is done in hardware.

Hardware accelerated: -vf "setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_vaapi=format=nv12,hwdownload,format=nv12" No acceleration: -vf "setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale=trunc(min(max(iw\,ih*a)\,3840)/2)*2:trunc(ow/a/2)*2,format=yuv420p"

kevincox commented 1 month ago

I feel like I'm going crazy. Even with the same settings the result can be different. For example these are all with no hardware acceleration at all. It worked three times in a row. Then I togged on "Allow encoding in HEVC format" and it failed. Then I turned it back off and it still failed! Then I played again and it worked again.

I checked the logs and it seems that for some reason different resolution and bitrate is being requested.

So sometimes it is deciding to scale to 1080p which works. IDK why this isn't consistent. I also don't know why this isn't using h265.

It seems like the bitrate test is giving varying results. (Despite being a wired connection to the server) so if you get lucky it plays. I can see various different values passed to /Items/<video id>/PlaybackInfo?MaxStreamingBitrate=??? endpoint. This means that it may or may not work depending on if you get lucky or not. It seems that this "bitrate test" is more of a connection speed test.

It also seems that this wouldn't be an issue if h265 was used.

kevincox commented 1 month ago

So the root of the problem seems to be that HLS is now preferred, and HLS is hardcoded to be h264 only.

https://github.com/jellyfin/jellyfin-chromecast/blob/be87b4e80ae4c6b56d4e9bfe5bd6d646f19189f1/src/components/codecSupportHelper.ts#L245-L249

This results in a high bitrate h264 file that the Chromecast Ultra can't play and somehow locks up.

So possible fixes may be:

  1. Allow HLS with h265.
  2. Properly set the max bitrate to transcode to a low enough bitrate that h264 works.
rj45jack commented 1 day ago

I just wanted to say that I've been having this issue for months and this is the first mention of my exact issue. Frustrating since I recorded all my media to 265 and then this happens 🤷