jellyfin / jellyfin-kodi

Jellyfin Plugin for Kodi
https://jellyfin.org
GNU General Public License v3.0
845 stars 113 forks source link

Transcoding due to server-set bitrate limit fails #713

Open njmdietrich opened 1 year ago

njmdietrich commented 1 year ago

Describe the bug When the max bitrate in the kodi addon settings is set to a larger value than the max bitrate on the server side (Internet streaming bitrate limit) the kodi addon will still direct play the video, although the audio may get transcoded. I believe the issue is that JELLYFIN.jellyfin_kodi.helper.playutils receives the correct bitrate from the server, but JELLYFIN.jellyfin_kodi.player then sends the bitrate as set in the kodi settings.

To Reproduce

  1. Enable an internet streaming bitrate limit in the jellyfin server settings
  2. connect the kodi jellyfin client via wan
  3. set the kodi client max bitrate to a value that still allows direct play of the video
  4. start the video

Expected behavior

The kodi client should adhere to the server settings and play a transcoded video. Logs

These are the two log entries with the differing bitrates:

2023-03-13 23:23:58.942 T:15891    info <general>: JELLYFIN.jellyfin_kodi.helper.playutils -> INFO::jellyfin_kodi/helper/playutils.py:82 {'MediaSources': [{'Protocol': 'File', 'Id': '96a3d2ffe0061add5b12ab5c7cdb5881', 'Path': '/data/Series/Community/Season6/Community-S06E03-Basic_Crisis_Room_Decorum[Bluray-1080p_Remux].mkv', 'Type': 'Default', 'Container': 'mkv', 'Size': 3259736320, 'Name': 'Community-S06E03-Basic_Crisis_Room_Decorum[Bluray-1080p_Remux]', 'IsRemote': False, 'ETag': 'f995c7ccbaabd87865d04f3b44b8ffb8', 'RunTimeTicks': 14759329792, 'ReadAtNativeFramerate': False, 'IgnoreDts': False, 'IgnoreIndex': False, 'GenPtsInput': False, 'SupportsTranscoding': True, 'SupportsDirectStream': False, 'SupportsDirectPlay': False, 'IsInfiniteStream': False, 'RequiresOpening': False, 'RequiresClosing': False, 'RequiresLooping': False, 'SupportsProbing': True, 'VideoType': 'VideoFile', 'MediaStreams': [{'Codec': 'subrip', 'Language': 'ger', 'TimeBase': '1/1000', 'LocalizedUndefined': 'Undefined', 'LocalizedDefault': 'Default', 'LocalizedForced': 'Forced', 'LocalizedExternal': 'External', 'DisplayTitle': 'Ger - SUBRIP - External', 'IsInterlaced': False, 'IsDefault': False, 'IsForced': False, 'Type': 'Subtitle', 'Index': 0, 'IsExternal': True, 'DeliveryMethod': 'External', 'DeliveryUrl': '/Videos/96a3d2ff-e006-1add-5b12-ab5c7cdb5881/96a3d2ffe0061add5b12ab5c7cdb5881/Subtitles/0/0/Stream.srt?api_key={jellyfin-token}', 'IsExternalUrl': False, 'IsTextSubtitleStream': True, 'SupportsExternalStream': True, 'Path': '/data/Series/Community/Season6/Community-S06E03-Basic_Crisis_Room_Decorum[Bluray-1080p_Remux].de.srt', 'Level': 0}, {'Codec': 'h264', 'Language': 'eng', 'ColorSpace': 'bt709', 'ColorTransfer': 'bt709', 'ColorPrimaries': 'bt709', 'TimeBase': '1/1000', 'Title': 'MPEG-4 AVC Video / 14979 kbps / 1080p / 23.976 fps / 16:9 / High Profile 4.1', 'VideoRange': 'SDR', 'VideoRangeType': 'SDR', 'DisplayTitle': 'MPEG-4 AVC Video / 14979 kbps / 1080p / 23.976 fps / 16:9 / High Profile 4.1 - H264 - SDR', 'NalLengthSize': '4', 'IsInterlaced': False, 'IsAVC': True, 'BitRate': 17668750, 'BitDepth': 8, 'RefFrames': 1, 'IsDefault': True, 'IsForced': False, 'Height': 1080, 'Width': 1920, 'AverageFrameRate': 23.976025, 'RealFrameRate': 23.976025, 'Profile': 'High', 'Type': 'Video', 'AspectRatio': '16:9', 'Index': 1, 'IsExternal': False, 'IsTextSubtitleStream': False, 'SupportsExternalStream': False, 'PixelFormat': 'yuv420p', 'Level': 41}, {'Codec': 'dts', 'Language': 'eng', 'TimeBase': '1/1000', 'Title': 'DTS-HD Master Audio / 5.1 / 48 kHz / 2795 kbps / 24-bit', 'DisplayTitle': 'DTS-HD Master Audio / 5.1 / 48 kHz / 2795 kbps / 24-bit - English - Default', 'IsInterlaced': False, 'ChannelLayout': '5.1', 'BitRate': 2794697, 'BitDepth': 24, 'Channels': 6, 'SampleRate': 48000, 'IsDefault': True, 'IsForced': False, 'Profile': 'DTS-HD MA', 'Type': 'Audio', 'Index': 2, 'IsExternal': False, 'IsTextSubtitleStream': False, 'SupportsExternalStream': False, 'Level': 0}, {'Codec': 'ac3', 'Language': 'eng', 'TimeBase': '1/1000', 'Title': 'Commentary by series creator Dan Harmon', 'DisplayTitle': 'Commentary by series creator Dan Harmon - English - Dolby Digital - Stereo', 'IsInterlaced': False, 'ChannelLayout': 'stereo', 'BitRate': 192000, 'Channels': 2, 'SampleRate': 48000, 'IsDefault': False, 'IsForced': False, 'Type': 'Audio', 'Index': 3, 'IsExternal': False, 'IsTextSubtitleStream': False, 'SupportsExternalStream': False, 'Level': 0}, {'Codec': 'subrip', 'Language': 'eng', 'TimeBase': '1/1000', 'Title': 'English', 'LocalizedUndefined': 'Undefined', 'LocalizedDefault': 'Default', 'LocalizedForced': 'Forced', 'LocalizedExternal': 'External', 'DisplayTitle': 'English - Default - SUBRIP', 'IsInterlaced': False, 'IsDefault': True, 'IsForced': False, 'Type': 'Subtitle', 'Index': 4, 'IsExternal': False, 'DeliveryMethod': 'External', 'DeliveryUrl': '/Videos/96a3d2ff-e006-1add-5b12-ab5c7cdb5881/96a3d2ffe0061add5b12ab5c7cdb5881/Subtitles/4/0/Stream.srt?api_key={jellyfin-token}', 'IsExternalUrl': False, 'IsTextSubtitleStream': True, 'SupportsExternalStream': True, 'Level': 0}, {'Codec': 'subrip', 'Language': 'eng', 'TimeBase': '1/1000', 'Title': 'English SDH', 'LocalizedUndefined': 'Undefined', 'LocalizedDefault': 'Default', 'LocalizedForced': 'Forced', 'LocalizedExternal': 'External', 'DisplayTitle': 'English SDH - SUBRIP', 'IsInterlaced': False, 'IsDefault': False, 'IsForced': False, 'Type': 'Subtitle', 'Index': 5, 'IsExternal': False, 'DeliveryMethod': 'External', 'DeliveryUrl': '/Videos/96a3d2ff-e006-1add-5b12-ab5c7cdb5881/96a3d2ffe0061add5b12ab5c7cdb5881/Subtitles/5/0/Stream.srt?api_key={jellyfin-token}', 'IsExternalUrl': False, 'IsTextSubtitleStream': True, 'SupportsExternalStream': True, 'Level': 0}, {'Codec': 'PGSSUB', 'Language': 'eng', 'TimeBase': '1/1000', 'Title': 'SDH', 'LocalizedUndefined': 'Undefined', 'LocalizedDefault': 'Default', 'LocalizedForced': 'Forced', 'LocalizedExternal': 'External', 'DisplayTitle': 'SDH - English - PGSSUB', 'IsInterlaced': False, 'IsDefault': False, 'IsForced': False, 'Type': 'Subtitle', 'Index': 6, 'IsExternal': False, 'DeliveryMethod': 'External', 'DeliveryUrl': '/Videos/96a3d2ff-e006-1add-5b12-ab5c7cdb5881/96a3d2ffe0061add5b12ab5c7cdb5881/Subtitles/6/0/Stream.pgssub?api_key={jellyfin-token}', 'IsExternalUrl': False, 'IsTextSubtitleStream': False, 'SupportsExternalStream': False, 'Level': 0}], 'MediaAttachments': [], 'Formats': [], 'Bitrate': 20655447, 'RequiredHttpHeaders': {}, 'TranscodingUrl': '/videos/96a3d2ff-e006-1add-5b12-ab5c7cdb5881/stream.m3u8?DeviceId=Unknown%20Device%20id&MediaSourceId=96a3d2ffe0061add5b12ab5c7cdb5881&VideoCodec=h264,hevc,h265,mpeg4,mpeg2video,vc1,h264&AudioCodec=aac,mp3,ac3,opus,flac,vorbis&AudioStreamIndex=2&VideoBitrate=4360000&AudioBitrate=640000&MaxFramerate=23.976025&PlaySessionId=f73565dcc8864e6080af7e08bed07750&api_key={jellyfin-token}&SubtitleMethod=Encode&TranscodingMaxAudioChannels=6&RequireAvc=false&Tag=f995c7ccbaabd87865d04f3b44b8ffb8&h264-level=41&h264-videobitdepth=8&h264-profile=high&TranscodeReasons=ContainerBitrateExceedsLimit', 'TranscodingSubProtocol': '', 'TranscodingContainer': 'm3u8', 'DefaultAudioStreamIndex': 2, 'DefaultSubtitleStreamIndex': -1}], 'PlaySessionId': 'f73565dcc8864e6080af7e08bed07750'}

2023-03-13 23:24:01.089 T:15847    info <general>: JELLYFIN.jellyfin_kodi.player -> INFO::jellyfin_kodi/player.py:160 -->[ play/96a3d2ffe0061add5b12ab5c7cdb5881 ] {'Type': 'Episode', 'Id': '96a3d2ffe0061add5b12ab5c7cdb5881', 'Path': 'https://{jellyfin-server}/videos/96a3d2ff-e006-1add-5b12-ab5c7cdb5881/master.m3u8?DeviceId=Unknown%20Device%20id&MediaSourceId=96a3d2ffe0061add5b12ab5c7cdb5881&VideoCodec=h264,hevc,h265,mpeg4,mpeg2video,vc1,h264&AudioCodec=aac,mp3,ac3,opus,flac,vorbis&MaxFramerate=23.976025&PlaySessionId=f73565dcc8864e6080af7e08bed07750&api_key={jellyfin-token}&SubtitleMethod=Encode&TranscodingMaxAudioChannels=6&RequireAvc=false&Tag=f995c7ccbaabd87865d04f3b44b8ffb8&h264-level=41&h264-videobitdepth=8&h264-profile=high&TranscodeReasons=ContainerBitrateExceedsLimit&AudioStreamIndex=2&VideoBitrate=999808000&AudioBitrate=192000&maxWidth=1920&maxHeight=1080', 'PlayMethod': 'Transcode', 'PlayOption': 'Addon', 'MediaSourceId': '96a3d2ffe0061add5b12ab5c7cdb5881', 'Runtime': 14759329792, 'PlaySessionId': 'f73565dcc8864e6080af7e08bed07750', 'ServerId': None, 'DeviceId': '213ae5ed-9efd-473f-8e90-26db875ea878', 'SubsMapping': {'0': 0, '1': 4, '2': 5}, 'AudioStreamIndex': 2, 'SubtitleStreamIndex': -1, 'CurrentPosition': 0, 'CurrentEpisode': {'episodeid': '96a3d2ffe0061add5b12ab5c7cdb5881', 'tvshowid': '25fadf818b1eb8fac1e442ec4624ab08', 'plot': 'The group has to go on the offensive against a claim that Greendale graduated a dog; Abed creates an attack ad discounting the dog; Britta, after pooping her pants, connects with Elroy over the band “Natalie is Freezing;” Chang shoots a single person porn.', 'showtitle': 'Community', 'title': 'Basic Crisis Room Decorum', 'playcount': 12, 'season': 6, 'episode': 3, 'rating': 7.9, 'firstaired': 2015, 'art': {'tvshow.poster': 'https://{jellyfin-server}/Items/25fadf818b1eb8fac1e442ec4624ab08/Images/Primary/0?Format=original&Tag=0b7ef3dcacaeb06f724d4a8e5f374568', 'thumb': 'https://{jellyfin-server}/Items/96a3d2ffe0061add5b12ab5c7cdb5881/Images/Primary/0?Format=original&Tag=1dfd6e87e3f09ffdcb1c69c3063532f3', 'tvshow.fanart': 'https://{jellyfin-server}/Items/25fadf818b1eb8fac1e442ec4624ab08/Images/Backdrop/0?Format=original&Tag=c101d8f65bec8642d55e2739d809d337'}}, 'File': 'https://{jellyfin-server}/videos/96a3d2ff-e006-1add-5b12-ab5c7cdb5881/master.m3u8?DeviceId=Unknown%20Device%20id&MediaSourceId=96a3d2ffe0061add5b12ab5c7cdb5881&VideoCodec=h264,hevc,h265,mpeg4,mpeg2video,vc1,h264&AudioCodec=aac,mp3,ac3,opus,flac,vorbis&MaxFramerate=23.976025&PlaySessionId=f73565dcc8864e6080af7e08bed07750&api_key={jellyfin-token}&SubtitleMethod=Encode&TranscodingMaxAudioChannels=6&RequireAvc=false&Tag=f995c7ccbaabd87865d04f3b44b8ffb8&h264-level=41&h264-videobitdepth=8&h264-profile=high&TranscodeReasons=ContainerBitrateExceedsLimit&AudioStreamIndex=2&VideoBitrate=999808000&AudioBitrate=192000&maxWidth=1920&maxHeight=1080', 'Muted': False, 'Volume': 100, 'Server': <jellyfin_kodi.jellyfin.client.JellyfinClient object at 0xb39ff570>, 'Paused': False}

System (please complete the following information):

TheTyrius commented 1 year ago

I just noticed this as well when first experimenting with the addon. I think this has been the case for a while as it seems similar to this older issue: https://github.com/jellyfin/jellyfin-kodi/issues/498

Using the addon setting for max bitrate is not quite the same, as it also restricts the resolution, while the server-side streaming bitrate limit allows me to get 4K at lower bitrates (10-20mbps H265 is often good enough for 4K).