jellyfin / jellyfin-chromecast

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

Some Transcoded Videos Only Play for a few Seconds #591

Open kevincox opened 4 months ago

kevincox commented 4 months 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 4 months ago

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

Working

Freezing

kevincox commented 4 months 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 4 months 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 4 months 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 4 months 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 4 months 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 4 months 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 2 months 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 🤷

3flex commented 2 months ago

Allow HLS with h265

The comment on the linked code snippet is not correct now as fMP4-HLS is supported by the server. However, it's behind a flag and I understand is disabled by default.

In theory Chromecast could declare support for HEVC (and AV1) on HLS and server would support direct stream/play to Chromecast if "Prefer fMP4-HLS Media Container" is enabled in Playback settings and the hardware supports it, falling back to h264 transcode if not.

BeleziaKhanid commented 1 month ago

Is there any update or idea for a workaround regarding this issue? Ever since I upgraded to the latest jellyfin version a few months ago I'm experiencing the same issue. Everything with a low bitrate works fine on chromcast, high bitrates get the spinning wheel of eternity. All other devices work fine, regardless of bitrate.