jellyfin / jellyfin-roku

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

Live TV player crashes to home screen for certain channels #2043

Open johnpc opened 3 days ago

johnpc commented 3 days ago

Software Versions

Describe the bug

The Live TV player in the Jellyfin Roku app is experiencing crashes that return the user to the Jellyfin home screen. This issue occurs in two scenarios:

  1. Immediately when attempting to play specific channels (these channels don't work at all on jellyfin-roku. Note that the channel works fine in jellyfin-web, jellyfin-android-tv, and vlc app)
  2. Randomly after viewing a channel for some time (unfortunately I do not have logs for this case as it is more difficult to reproduce)

How To Reproduce

  1. Open the Jellyfin Roku app
  2. Navigate to Live TV
  3. Select an affected channel to watch (see logs for more info)
  4. Observe that the live tv viewer crashes and the app returns to the home screen

Expected behavior

I expect the Jellyfin Roku client to play the channel, which works well on jellyfin web, jellyfin android-tv, and vlc app.

Logs

Server logs at time of crash:

[2024-11-10 17:32:54.989 +00:00] [INF] [32] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for "John". EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True
[2024-11-10 17:32:54.990 +00:00] [INF] [32] Jellyfin.LiveTv.LiveTvMediaSourceProvider: Opening channel stream from "Emby", external channel Id: "m3u_26c7a1eb3571583bbf7b831cc77850b8f5e7412ae9203a19ee883eb7a1b0ba5d"
[2024-11-10 17:32:54.990 +00:00] [INF] [32] Jellyfin.LiveTv.DefaultLiveTvService: Streaming Channel "m3u_26c7a1eb3571583bbf7b831cc77850b8f5e7412ae9203a19ee883eb7a1b0ba5d"
[2024-11-10 17:32:55.139 +00:00] [INF] [32] Jellyfin.LiveTv.TunerHosts.M3UTunerHost: Live stream opened after 0.0039ms
[2024-11-10 17:32:55.139 +00:00] [INF] [32] Jellyfin.LiveTv.DefaultLiveTvService: Returning mediasource streamId "f5e7412ae9203a19ee883eb7a1b0ba5d", mediaSource.Id "f5e7412ae9203a19ee883eb7a1b0ba5d", mediaSource.LiveStreamId null
[2024-11-10 17:32:55.140 +00:00] [INF] [32] Emby.Server.Implementations.Library.MediaSourceManager: Live tv media info probe took "0.0004234" seconds
[2024-11-10 17:32:55.140 +00:00] [INF] [32] Emby.Server.Implementations.Library.MediaSourceManager: Live stream opened: MediaSourceInfo { Protocol: Http, Id: "f5e7412ae9203a19ee883eb7a1b0ba5d", Path: "https://dumdumbullet.com/1012138582/BQUsq7CDEA/900001168395", EncoderPath: null, EncoderProtocol: null, Type: Default, Container: "mpegts", Size: null, Name: null, IsRemote: True, ETag: null, RunTimeTicks: null, ReadAtNativeFramerate: False, IgnoreDts: True, IgnoreIndex: False, GenPtsInput: False, SupportsTranscoding: True, SupportsDirectStream: True, SupportsDirectPlay: False, IsInfiniteStream: True, UseMostCompatibleTranscodingProfile: True, RequiresOpening: True, OpenToken: null, RequiresClosing: True, LiveStreamId: "e2329f4997b378e64ccf8fa396deb76e_af999c25a00715699361240d4c6c7a53_f5e7412ae9203a19ee883eb7a1b0ba5d", BufferMs: null, RequiresLooping: False, SupportsProbing: True, VideoType: null, IsoType: null, Video3DFormat: null, MediaStreams: [MediaStream { Codec: "h264", CodecTag: null, Language: null, ColorRange: "tv", ColorSpace: "bt709", ColorTransfer: "bt709", ColorPrimaries: "bt709", DvVersionMajor: null, DvVersionMinor: null, DvProfile: null, DvLevel: null, RpuPresentFlag: null, ElPresentFlag: null, BlPresentFlag: null, DvBlSignalCompatibilityId: null, Rotation: null, Comment: null, TimeBase: "1/90000", CodecTimeBase: null, Title: null, VideoRange: SDR, VideoRangeType: SDR, VideoDoViTitle: null, AudioSpatialFormat: None, LocalizedUndefined: null, LocalizedDefault: null, LocalizedForced: null, LocalizedExternal: null, LocalizedHearingImpaired: null, DisplayTitle: "720p H264 SDR", NalLengthSize: "0", IsInterlaced: False, IsAVC: null, ChannelLayout: null, BitRate: 8000000, BitDepth: 8, RefFrames: 1, PacketLength: null, Channels: null, SampleRate: null, IsDefault: False, IsForced: False, IsHearingImpaired: False, Height: 720, Width: 1280, AverageFrameRate: 59.94006, RealFrameRate: 59.94006, ReferenceFrameRate: 59.94006, Profile: "Main", Type: Video, AspectRatio: "16:9", Index: -1, Score: null, IsExternal: False, DeliveryMethod: null, DeliveryUrl: null, IsExternalUrl: null, IsTextSubtitleStream: False, IsPgsSubtitleStream: False, IsExtractableSubtitleStream: False, SupportsExternalStream: False, Path: null, PixelFormat: "yuv420p", Level: 40, IsAnamorphic: False }, MediaStream { Codec: "aac", CodecTag: null, Language: null, ColorRange: null, ColorSpace: null, ColorTransfer: null, ColorPrimaries: null, DvVersionMajor: null, DvVersionMinor: null, DvProfile: null, DvLevel: null, RpuPresentFlag: null, ElPresentFlag: null, BlPresentFlag: null, DvBlSignalCompatibilityId: null, Rotation: null, Comment: null, TimeBase: "1/90000", CodecTimeBase: null, Title: null, VideoRange: Unknown, VideoRangeType: Unknown, VideoDoViTitle: null, AudioSpatialFormat: None, LocalizedUndefined: null, LocalizedDefault: null, LocalizedForced: null, LocalizedExternal: null, LocalizedHearingImpaired: null, DisplayTitle: "HE-AAC - Stereo", NalLengthSize: null, IsInterlaced: False, IsAVC: False, ChannelLayout: "stereo", BitRate: 95375, BitDepth: null, RefFrames: null, PacketLength: null, Channels: 2, SampleRate: 48000, IsDefault: False, IsForced: False, IsHearingImpaired: False, Height: null, Width: null, AverageFrameRate: null, RealFrameRate: null, ReferenceFrameRate: null, Profile: "HE-AAC", Type: Audio, AspectRatio: null, Index: -1, Score: null, IsExternal: False, DeliveryMethod: null, DeliveryUrl: null, IsExternalUrl: null, IsTextSubtitleStream: False, IsPgsSubtitleStream: False, IsExtractableSubtitleStream: False, SupportsExternalStream: False, Path: null, PixelFormat: null, Level: 0, IsAnamorphic: null }], MediaAttachments: [], Formats: [], Bitrate: 8095375, FallbackMaxStreamingBitrate: 30000000, Timestamp: null, RequiredHttpHeaders: [("User-Agent": "NutterButter")], TranscodingUrl: null, TranscodingSubProtocol: http, TranscodingContainer: null, AnalyzeDurationMs: 3000, TranscodeReasons: 0, DefaultAudioStreamIndex: null, DefaultSubtitleStreamIndex: null, HasSegments: False, VideoStream: MediaStream { Codec: "h264", CodecTag: null, Language: null, ColorRange: "tv", ColorSpace: "bt709", ColorTransfer: "bt709", ColorPrimaries: "bt709", DvVersionMajor: null, DvVersionMinor: null, DvProfile: null, DvLevel: null, RpuPresentFlag: null, ElPresentFlag: null, BlPresentFlag: null, DvBlSignalCompatibilityId: null, Rotation: null, Comment: null, TimeBase: "1/90000", CodecTimeBase: null, Title: null, VideoRange: SDR, VideoRangeType: SDR, VideoDoViTitle: null, AudioSpatialFormat: None, LocalizedUndefined: null, LocalizedDefault: null, LocalizedForced: null, LocalizedExternal: null, LocalizedHearingImpaired: null, DisplayTitle: "720p H264 SDR", NalLengthSize: "0", IsInterlaced: False, IsAVC: null, ChannelLayout: null, BitRate: 8000000, BitDepth: 8, RefFrames: 1, PacketLength: null, Channels: null, SampleRate: null, IsDefault: False, IsForced: False, IsHearingImpaired: False, Height: 720, Width: 1280, AverageFrameRate: 59.94006, RealFrameRate: 59.94006, ReferenceFrameRate: 59.94006, Profile: "Main", Type: Video, AspectRatio: "16:9", Index: -1, Score: null, IsExternal: False, DeliveryMethod: null, DeliveryUrl: null, IsExternalUrl: null, IsTextSubtitleStream: False, IsPgsSubtitleStream: False, IsExtractableSubtitleStream: False, SupportsExternalStream: False, Path: null, PixelFormat: "yuv420p", Level: 40, IsAnamorphic: False } }
[2024-11-10 17:32:55.141 +00:00] [INF] [32] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for "John". EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True
[2024-11-10 17:32:55.629 +00:00] [INF] [32] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: "/usr/lib/jellyfin-ffmpeg/ffmpeg" "-analyzeduration 3000000 -probesize 1G -user_agent \"NutterButter\" -fflags +igndts  -i \"https://dumdumbullet.com/1012138582/BQUsq7CDEA/900001168395\" -map_metadata -1 -map_chapters -1 -threads 0 -sn -codec:v:0 libx265 -tag:v:0 hvc1 -preset veryfast -crf 28 -maxrate 7000000 -bufsize 14000000 -profile:v:0 main -x265-params:0 subme=3:merange=25:rc-lookahead=10:me=star:ctu=32:max-tu-size=32:min-cu-size=16:rskip=2:rskip-edge-threshold=2:no-sao=1:no-strong-intra-smoothing=1:no-scenecut=1:no-open-gop=1:no-info=1 -force_key_frames:0 \"expr:gte(t,n_forced*3)\" -vf \"setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale=trunc(min(max(iw\,ih*a)\,1280)/2)*2:trunc(ow/a/2)*2,format=yuv420p\" -flags -global_header -codec:a:0 copy -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_base_url \"hls/f8a48f3e09bae82a3776ef6f00b91452/\" -hls_segment_filename \"/config/cache/transcodes/f8a48f3e09bae82a3776ef6f00b91452%d.ts\" -hls_playlist_type event -hls_list_size 0 -y \"/config/cache/transcodes/f8a48f3e09bae82a3776ef6f00b91452.m3u8\""
[2024-11-10 17:32:59.670 +00:00] [INF] [3] MediaBrowser.Controller.MediaEncoding.TranscodingJob: Stopping ffmpeg process with q command for "/config/cache/transcodes/f8a48f3e09bae82a3776ef6f00b91452.m3u8"
[2024-11-10 17:32:59.940 +00:00] [INF] [41] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: FFmpeg exited with code 0
[2024-11-10 17:32:59.940 +00:00] [INF] [3] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: Deleting partial stream file(s) "/config/cache/transcodes/f8a48f3e09bae82a3776ef6f00b91452.m3u8"
[2024-11-10 17:33:01.442 +00:00] [INF] [54] Emby.Server.Implementations.Session.SessionManager: Playback stopped reported by app "Jellyfin Roku" "2.2.2" playing "US: FOX 2 Detroit (WJBK)". Stopped at "0" ms
[2024-11-10 17:33:01.443 +00:00] [INF] [54] Emby.Server.Implementations.Library.MediaSourceManager: Live stream "f5e7412ae9203a19ee883eb7a1b0ba5d" consumer count is now 0
[2024-11-10 17:33:01.443 +00:00] [INF] [54] Emby.Server.Implementations.Library.MediaSourceManager: Closing live stream "e2329f4997b378e64ccf8fa396deb76e_af999c25a00715699361240d4c6c7a53_f5e7412ae9203a19ee883eb7a1b0ba5d"
[2024-11-10 17:33:01.443 +00:00] [INF] [54] Jellyfin.LiveTv.TunerHosts.M3UTunerHost: Closing "LiveStream"
[2024-11-10 17:33:01.443 +00:00] [INF] [54] Emby.Server.Implementations.Library.MediaSourceManager: Live stream "e2329f4997b378e64ccf8fa396deb76e_af999c25a00715699361240d4c6c7a53_f5e7412ae9203a19ee883eb7a1b0ba5d" closed successfully
[2024-11-10 17:33:01.445 +00:00] [INF] [3] Jellyfin.Plugin.PlaybackReporting.EventMonitorEntryPoint: Playback stop did not have a tracker : "f250abc5-2441-56d8-b857-8980aa429917John-2fee110568a441a1b148020b5843d5c9-906bfc81d87291504865731c7b0c05e6"

Jellyfin Client logs:

DEBUG file:///Users/xss/repo/jellyfin-roku/components/video/VideoPlayerView.bs:615 start onState() buffering
DEBUG file:///Users/xss/repo/jellyfin-roku/components/video/VideoPlayerView.bs:676 end onState() buffering
DEBUG file:///Users/xss/repo/jellyfin-roku/components/video/VideoPlayerView.bs:615 start onState() error
ERROR file:///Users/xss/repo/jellyfin-roku/components/video/VideoPlayerView.bs:630 -5 malformed data decoder:pump:Unsupported AAC stream. -5
<Component: roAssociativeArray> =
{
    category: "mediaerror"
    clipid: 1
    dbgmsg: "decoder:pump:Unsupported AAC stream."
    drmerrcode: 0
    errcode: 1
    ignored: false
    source: ""
}
DEBUG file:///Users/xss/repo/jellyfin-roku/components/video/VideoPlayerView.bs:676 end onState() error
DEBUG file:///Users/xss/repo/jellyfin-roku/components/video/VideoPlayerView.bs:615 start onState() finished
DEBUG file:///Users/xss/repo/jellyfin-roku/components/video/VideoPlayerView.bs:684 start ReportPlayback() finished 0
DEBUG file:///Users/xss/repo/jellyfin-roku/components/video/VideoPlayerView.bs:705 end ReportPlayback() finished 0
DEBUG file:///Users/xss/repo/jellyfin-roku/components/video/VideoPlayerView.bs:676 end onState() finished

ffmpeg logs: https://paste.jpc.io/snippet/b30da9cc-4e89-43cd-9f34-62bcea8e972b

ffmpeg logs when invoked via android-tv app: https://paste.jpc.io/snippet/8e83be93-b2a5-42a3-aed9-0182266593eb

The main difference I see between the ffmpeg logs is that when invoked from the roku client, I see

[q] command received. Exiting.

whereas I don't see that from the android-tv client.

Screenshots

iPhone recording of the repro (I couldn't figure out how to screen record the roku without it being a headache): https://files.jpc.io/d/Yx2mW-IMG_7343.mov

Connection Information

Additional context

Playback info for affected channel when working on jellyfin web client:

Playback Info
* Player: Html Video Player
* Play method: Remuxing
* Protocol: https
* Stream type: HLS

Video Info
* Player dimensions: 3456x1920
* Video resolution: 1280x720
* Dropped frames: 0
* Corrupted frames: 0

Remuxing Info
* Video codec: H264 (direct)
* Audio codec: AAC (direct)

Original Media Info
* Container: mpegts
* Bitrate: 8.1 Mbps
* Video codec: H264 Main
* Video bitrate: 8.0 Mbps
* Video range type: SDR
* Audio codec: AAC HE-AAC
* Audio bitrate: 95 kbps
* Audio channels: 2
* Audio sample rate: 48000 Hz

Roku software info:

cewert commented 3 days ago

The error message is correct - rokus don't support HE-AAC (only v2).

The server doesn't support converting one AAC profile to another, so I have HE-AAC being converted to MP3 #1963

1963 only triggers when the container is ts or mp4 https://github.com/jellyfin/jellyfin-roku/pull/1963/files#diff-944396a3daefd786f2db28996ea075470a1e36b59c973c3001853d8dcafdc4adR50

I noticed in your log that the input file is from a URL. I only use local files and I don't use live tv so I'm not much help. I tried to download the file myself but there was no file extension? Is it possible this file isn't triggering #1963 because of the files container?

johnpc commented 3 days ago

I did include that url only in the paste so that I can remove it more easily in the future... I don't think I want that link floating around long term.

You can download VLC Media Player and chose "File > Open Network..." and paste that url, it streams perfectly fine.

I have several other channels that work the same way, with no extension, and those channels do work perfectly in jellyfin roku and other clients. The logs seem to indicate that it's being recognized as a .ts if I'm reading the logs correctly.

That's a good point about AAC in roku - surprising to me that roku doesn't support it but it makes sense.

Given that, I think the transcoding should happen on the server, doing it on the client like in https://github.com/jellyfin/jellyfin-roku/pull/1963/files feels like it's just asking for trouble. It could also be the source of some audio synchronization issues I've observed where the audio can be slightly delayed compared to the video. Do you know if there's an issue I can follow in the jellyfin server repo to track AAC transcoding behavior?

yorah commented 19 hours ago

In the log file, I can see: `Container: "mpegts"

The code added in #1963 specifically checks for ts or mp4. Could that be the reason why it is not transcoding?

cewert commented 18 hours ago

Hopefully it was 1963 because that should be an easy fix. I don't have live tv so if one of you could test I would appreciate it https://github.com/jellyfin/jellyfin-roku/pull/2047