jellyfin / jellyfin-roku

The Official Roku Client for Jellyfin
https://jellyfin.org
GNU General Public License v2.0
421 stars 129 forks source link

Roku Ultra transcoding AC3 audio despite being plugged into and detecting AC3-capable HDMI receiver #546

Closed rudism closed 2 years ago

rudism commented 2 years ago

Describe the bug Roku Ultra hooked up to AC3/Dolby capable receiver via HDMI is not reporting AC3 as a supported codec, causing videos with AC3 5.1 audio to be transcoded.

Roku settings:

To Reproduce

  1. Hook Roku up to HDMI receiver that can play AC3 5.1
  2. Play video (HEVC 10-bit video track, AC3 5.1 audio track) in Jellyfin
  3. Check Jellyfin dashboard from a web browser and see that the video is being transcoded due to the audio format not being supported (in 10.7.7 the video is transcoded too, however this seems to be fixed in 10.8.0-beta1 and only the audio is transcoded).

Expected behavior The Roku Ultra is capable of playing HEVC 10-bit video and the receiver is capable of playing AC3 5.1 audio, so I would expect this to play without any transcoding.

Logs This showed up in the logs while using 10.7.7 when playing a file on the Roku. I haven't seen a similar profile message show up since switching to 10.8.0-beta1 and not sure how to enable this more verbose logging.

[2022-03-30 00:37:20.981 +00:00] [INF] [33] Jellyfin.Api.Controllers.MediaInfoController: GetPostedPlaybackInfo profile: DeviceProfile { Name: null, Id: null, Identification: null, FriendlyName: null, Manufacturer: null, ManufacturerUrl: null, ModelName: null, ModelDescription: null, ModelNumber: null, ModelUrl: null, SerialNumber: null, EnableAlbumArtInDidl: False, EnableSingleAlbumArtLimit: False, EnableSingleSubtitleLimit: False, SupportedMediaTypes: "Audio,Photo,Video", UserId: null, AlbumArtPn: null, MaxAlbumArtWidth: 0, MaxAlbumArtHeight: 0, MaxIconWidth: null, MaxIconHeight: null, MaxStreamingBitrate: 120000000, MaxStaticBitrate: 100000000, MusicStreamingTranscodingBitrate: 192000, MaxStaticMusicBitrate: null, SonyAggregationFlags: null, ProtocolInfo: null, TimelineOffsetSeconds: 0, RequiresPlainVideoItems: False, RequiresPlainFolders: False, EnableMSMediaReceiverRegistrar: False, IgnoreTranscodeByteRangeRequests: False, XmlRootAttributes: [], DirectPlayProfiles: [DirectPlayProfile { Container: "mp4,m4v,mov", AudioCodec: "mp3,pcm,lpcm,wav,alac,aac", VideoCodec: "h264,h265,hevc,mpeg2video", Type: Video }, DirectPlayProfile { Container: "mkv,webm", AudioCodec: "mp3,pcm,lpcm,wav,flac,alac,aac,opus,vorbis", VideoCodec: "h264,vp8,h265,hevc,vp9,mpeg2video", Type: Video }, DirectPlayProfile { Container: "mp3,pcm,lpcm,wav,wma,flac,alac,aac,wmapro", AudioCodec: null, VideoCodec: null, Type: Audio }], TranscodingProfiles: [TranscodingProfile { Container: "aac", Type: Audio, VideoCodec: null, AudioCodec: "aac", Protocol: "http", EstimateContentLength: False, EnableMpegtsM2TsMode: False, TranscodeSeekInfo: Auto, CopyTimestamps: False, Context: Streaming, EnableSubtitlesInManifest: False, MaxAudioChannels: " 2", MinSegments: 0, SegmentLength: 0, BreakOnNonKeyFrames: False }, TranscodingProfile { Container: "mp3", Type: Audio, VideoCodec: null, AudioCodec: "mp3", Protocol: "http", EstimateContentLength: False, EnableMpegtsM2TsMode: False, TranscodeSeekInfo: Auto, CopyTimestamps: False, Context: Streaming, EnableSubtitlesInManifest: False, MaxAudioChannels: "2", MinSegments: 0, SegmentLength: 0, BreakOnNonKeyFrames: False }, TranscodingProfile { Container: "mp3", Type: Audio, VideoCodec: null, AudioCodec: "mp3", Protocol: "http", EstimateContentLength: False, EnableMpegtsM2TsMode: False, TranscodeSeekInfo: Auto, CopyTimestamps: False, Context: Static, EnableSubtitlesInManifest: False, MaxAudioChannels: "2", MinSegments: 0, SegmentLength: 0, BreakOnNonKeyFrames: False }, TranscodingProfile { Container: "aac", Type: Audio, VideoCodec: null, AudioCodec: "aac", Protocol: "http", EstimateContentLength: False, EnableMpegtsM2TsMode: False, TranscodeSeekInfo: Auto, CopyTimestamps: False, Context: Static, EnableSubtitlesInManifest: False, MaxAudioChannels: " 2", MinSegments: 0, SegmentLength: 0, BreakOnNonKeyFrames: False }, TranscodingProfile { Container: "ts", Type: Video, VideoCodec: "h264,mpeg2video", AudioCodec: "aac", Protocol: "hls", EstimateContentLength: False, EnableMpegtsM2TsMode: False, TranscodeSeekInfo: Auto, CopyTimestamps: False, Context: Streaming, EnableSubtitlesInManifest: False, MaxAudioChannels: " 2", MinSegments: 1, SegmentLength: 0, BreakOnNonKeyFrames: True }, TranscodingProfile { Container: "mp4", Type: Video, VideoCodec: "h264", AudioCodec: "aac,opus,flac,vorbis", Protocol: "http", EstimateContentLength: False, EnableMpegtsM2TsMode: False, TranscodeSeekInfo: Auto, CopyTimestamps: False, Context: Static, EnableSubtitlesInManifest: False, MaxAudioChannels: null, MinSegments: 0, SegmentLength: 0, BreakOnNonKeyFrames: False }], ContainerProfiles: [], CodecProfiles: [CodecProfile { Type: VideoAudio, Conditions: [ProfileCondition { Condition: Equals, Property: IsSecondaryAudio, Value: "false", IsRequired: False }], ApplyConditions: [], Codec: "aac", Container: null }, CodecProfile { Type: VideoAudio, Conditions: [ProfileCondition { Condition: LessThanEqual, Property: AudioChannels, Value: " 2", IsRequired: False }], ApplyConditions: [], Codec: "mp3,pcm,lpcm,wav,flac,alac,aac,opus,vorbis", Container: null }, CodecProfile { Type: Video, Conditions: [ProfileCondition { Condition: EqualsAny, Property: VideoProfile, Value: "high|main|baseline|constrained baseline", IsRequired: False }, ProfileCondition { Condition: LessThanEqual, Property: VideoLevel, Value: "51", IsRequired: False }], ApplyConditions: [], Codec: "h264", Container: null }], ResponseProfiles: [], SubtitleProfiles: [SubtitleProfile { Format: "vtt", Method: External, DidlMode: null, Language: null, Container: null }, SubtitleProfile { Format: "srt", Method: External, DidlMode: null, Language: null, Container: null }, SubtitleProfile { Format: "ttml", Method: External, DidlMode: null, Language: null, Container: null }] }
[2022-03-30 00:37:20.983 +00:00] [INF] [33] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for "rudism". EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True
[2022-03-30 00:37:20.983 +00:00] [INF] [33] Jellyfin.Api.Helpers.MediaInfoHelper: Profile: "Unknown Profile", Path: "/media/beeblebrox/bdrip-movies/Mimic (1997).mkv", isEligibleForDirectPlay: True, isEligibleForDirectStream: True
[2022-03-30 00:37:20.983 +00:00] [INF] [33] Jellyfin.Api.Helpers.MediaInfoHelper: Profile: "Unknown Profile", No video direct play profiles found for "/media/beeblebrox/bdrip-movies/Mimic (1997).mkv" with codec "hevc"
[2022-03-30 00:37:20.983 +00:00] [INF] [33] Jellyfin.Api.Helpers.MediaInfoHelper: Profile: "Unknown Profile", Path: "/media/beeblebrox/bdrip-movies/Mimic (1997).mkv", isEligibleForDirectPlay: True, isEligibleForDirectStream: True
[2022-03-30 00:37:20.984 +00:00] [INF] [33] Jellyfin.Api.Helpers.MediaInfoHelper: Profile: "Unknown Profile", No video direct play profiles found for "/media/beeblebrox/bdrip-movies/Mimic (1997).mkv" with codec "hevc"
[2022-03-30 00:37:20.984 +00:00] [INF] [33] Jellyfin.Api.Helpers.MediaInfoHelper: Profile: "Unknown Profile", Path: "/media/beeblebrox/bdrip-movies/Mimic (1997).mkv", isEligibleForDirectPlay: True, isEligibleForDirectStream: True
[2022-03-30 00:37:20.984 +00:00] [INF] [33] Jellyfin.Api.Helpers.MediaInfoHelper: Profile: "Unknown Profile", No video direct play profiles found for "/media/beeblebrox/bdrip-movies/Mimic (1997).mkv" with codec "hevc"
[2022-03-30 00:37:21.485 +00:00] [INF] [4] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[2022-03-30 00:37:21.487 +00:00] [INF] [4] Jellyfin.Api.Helpers.TranscodingJobHelper: /usr/lib/jellyfin-ffmpeg/ffmpeg -f matroska,webm -i file:"/media/beeblebrox/bdrip-movies/Mimic (1997).mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 libx264 -pix_fmt yuv420p -preset veryfast -crf 23 -maxrate 14601493 -bufsize 29202986 -profile:v:0 high -level 41 -x264opts:0 subme=0:me_range=4:rc_lookahead=10:me=dia:no_chroma_me:8x8dct=0:partitions=none  -force_key_frames:0 "expr:gte(t,0+n_forced*3)" -vf "scale=trunc(min(max(iw\,ih*dar)\,min(1920\,1040*dar))/2)*2:trunc(min(max(iw/dar\,ih)\,min(1920/dar\,1040))/2)*2" -start_at_zero -vsync -1 -codec:a:0 aac -ac 2 -ab 384000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/config/transcodes/29bc919f2659386641de1998f937a995%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/config/transcodes/29bc919f2659386641de1998f937a995.m3u8"

Screenshots

Additional context I did manage to find a work-around:

This is not optimal, though, since there are other cases where I have media that really is not compatible with the Roku and those can no longer be played with these settings.

Possibly related to #532 but in this case as far as I can tell the Roku is correctly detecting that the receiver supports all the Dolby Digital formats and yet those audio formats are not being posted to Jellyfin as being compatible with direct play.

The Plex Roku app plays the same media fine without transcoding, and I can cast to a Chromecast Ultra connected to the same receiver from the Jellyfin Android app and it plays fine without transcoding.

whiteowl3 commented 2 years ago

It is likely because of the roku's device profile. There was a condition where AAC will be transcoded if it's not first or default. There is an open PR which will correct it. https://github.com/jellyfin/jellyfin-roku/pull/543 if you want it to start working now, use 10.8 and delete the AAC Codec profile as indicated in the PR.

rudism commented 2 years ago

Is it possible to remove a codec from the Roku's profile on the server side?

whiteowl3 commented 2 years ago

no but 543 has been merged so if you just clone the git and sideload according to the development guide, it will work with a 10.8b1 server

rudism commented 2 years ago

Nice, I never knew it was so easy to sideload to the Roku. That merge appears to have fixed my problem so I'll close this. Thanks.