jellyfin / jellyfin-chromecast

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

Using fmp4 causes chromecast gen 2 to freeze #76

Open YouKnowBlom opened 3 years ago

YouKnowBlom commented 3 years ago

Describe the bug When hardcoding a transcoding profile to fmp4 over HLS the chromecast locks up completely

{
                 Container: "mp4",
                 Type: "Video",
                 AudioCodec: "aac",
                 VideoCodec: "h264",
                 Context: "Streaming",
                 Protocol: "hls",
                 MaxAudioChannels: physicalAudioChannels.toString(),
                 MinSegments: "1",
                 BreakOnNonKeyFrames: false
}

To Reproduce

  1. Hardcode above profile
  2. Try to play something that requires transcoding

Expected behavior No freezing and playback works as it should

System (please complete the following information):

nyanmisaka commented 3 years ago

Does chromecast have a native HLS player that support fMP4? https://developers.google.com/cast/docs/media

hls.js and mpv can play fMP4 AFAIK.

YouKnowBlom commented 3 years ago

Yeah it should. They have an example here showing it working here (scroll down just a bit) https://developers.google.com/cast/docs/web_receiver/streaming_protocols#content_protection

nyanmisaka commented 3 years ago

Where did it stuck at? master.m3u8 or main.m3u8? ffmpeg launched or not?

YouKnowBlom commented 3 years ago

master.m3u8, main.m3u8 and the first few segments are requested successfully from what I can tell (including -1.mp4).

Could it be related to CORS?

nyanmisaka commented 3 years ago

master.m3u8, main.m3u8 and the first few segments are requested successfully from what I can tell (including -1.mp4).

Could it be related to CORS?

I dont think so as TS segments can be requested in the same way. Might be related to codecs/profile? H.264 High Profile up to level 4.1 (720p/60fps or 1080p/30fps)

YouKnowBlom commented 3 years ago

I dont think so as TS segments can be requested in the same way. Might be related to codecs/profile? H.264 High Profile up to level 4.1 (720p/60fps or 1080p/30fps)

Yeah that's a good point.

Usually it refuses to play if the level is unsupported, either way there is a limit defined for H.264 in the codecprofiles part of the deviceprofile.

nyanmisaka commented 3 years ago

Here are some fMP4 examples from Apple with different profiles. You can give it a try. https://developer.apple.com/streaming/examples/

YouKnowBlom commented 3 years ago

I'll try a few of those when I get the time. Thanks :p

hawken93 commented 3 years ago

idittansikte commented 5 hours ago "I also tried the same thing to enable fmp4 as #76 and played hevc/aac.surr but my CC Ultra froze 60 seconds in (after about 10 segements). But played nicely with sound before that. I had to also set loadRequestData.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.FMP4; in order for it to work at all though."

Just leaving this here :)

ericsun6 commented 2 years ago

Is there any updates for this issue now? We met same issue but it seems this ticket still undergoing as an open ticket now. Can anyone has a clue how to do?

miquels commented 2 years ago

I ran into the this problem myself today while hacking on one of my projects. Spent hours googling, then created a custom web receiver so that I could debug on the chromecast side. After trying lots of things I think I have managed to solve it on the client (web sender) side. During my googling this github issue also turned up, so I thought I should share. Hope this helps :)

    let mediaInfo = new chrome.cast.media.MediaInfo(mediaData.src, 'video/mp4');
    mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED;

    if (mediaData.src.endsWith(".m3u8")) {
      // These must be set to FMP4, or the chromecast will hang.
      mediaInfo.hlsSegmentFormat = chrome.cast.media.HlsSegmentFormat.FMP4;
      mediaInfo.hlsVideoSegmentFormat = chrome.cast.media.HlsVideoSegmentFormat.FMP4;
      // StreamType must be LIVE or OTHER, not BUFFERED.
      mediaInfo.streamType = chrome.cast.media.StreamType.OTHER;
      // And ofcourse the MIME type.
      mediaInfo.contentType = 'application/x-mpegURL';
    }

EDIT: forgot to mention, if you have implemented your own custom web receiver on the chromecast, you can also intercept the LOAD request and fix it up there instead (if you know the HLS stream is fmp4 instead of .ts).

ferferga commented 2 years ago

Care to make a PR? :) @miquels

miquels commented 2 years ago

Ha, no thanks. This was just a drive-by comment :).