jellyfin-chromecast icon indicating copy to clipboard operation
jellyfin-chromecast copied to clipboard

Using fmp4 causes chromecast gen 2 to freeze

Open YouKnowBlom opened this issue 4 years ago • 13 comments

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):

  • OS: Docker
  • Browser: Chrome
  • Jellyfin Version: 10.7-unstable
  • Cast client: Gen 2

YouKnowBlom avatar Nov 21 '20 14:11 YouKnowBlom

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.

nyanmisaka avatar Nov 21 '20 15:11 nyanmisaka

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

YouKnowBlom avatar Nov 21 '20 16:11 YouKnowBlom

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

nyanmisaka avatar Nov 21 '20 16:11 nyanmisaka

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?

YouKnowBlom avatar Nov 21 '20 18:11 YouKnowBlom

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)

nyanmisaka avatar Nov 21 '20 18:11 nyanmisaka

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.

YouKnowBlom avatar Nov 22 '20 11:11 YouKnowBlom

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

nyanmisaka avatar Nov 22 '20 12:11 nyanmisaka

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

YouKnowBlom avatar Nov 25 '20 13:11 YouKnowBlom

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 :)

hawken93 avatar Dec 22 '20 17:12 hawken93

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?

ericsun6 avatar Oct 27 '21 14:10 ericsun6

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).

miquels avatar Dec 30 '21 16:12 miquels

Care to make a PR? :) @miquels

ferferga avatar Dec 30 '21 16:12 ferferga

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

miquels avatar Jan 07 '22 23:01 miquels