Skip to content
This repository has been archived by the owner on Oct 13, 2024. It is now read-only.

Some theme music files won't play on Jellyfin Tizen (Jellyfin 10.9.2) #364

Open
dusanhatvani opened this issue May 23, 2024 · 13 comments
Open

Comments

@dusanhatvani
Copy link

Describe the Bug

Hello,

After upgrading Jellyfin server to the latest version 10.9.2 and also upgrading Jellyfin Tizen clien and Themerr plugin, some new mp3 theme files like for a movie "Legend (2015)" are not playing at all. Old mp3 files, which were already downloaded are unaffected. Jellyfin Tizen client is reporting error when trying to play theme music that media is not supported.

I analyzed jellyfin logs and found this error: MediaBrowser.Providers.Music.AudioMetadataService: Error in "Probe Provider"
TagLib.CorruptFileException: MPEG audio header not found.

I then analyzed specific mp3 files with this program https://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header and confirmed that MPEG audio header is indeed missing ("No frame found within tolerance range" error). Files that Jellyfin Tizen client can play with no problems show correct MPEG Audio Header.

Just a note that these files with missing MPEG audio header are playing with no problems on Windows client

Expected Behavior

No response

Additional Context

No response

@ReenigneArcher
Copy link
Member

ReenigneArcher commented May 23, 2024

Thanks for reporting this. I'm not sure how to fix it at the moment, but I can probably come up with something.

Linking this here just for reference, which was a previously similar (but different) issue. #98

Is there a way for you test if the affected files play in an older version of Jellyfin?

@dusanhatvani
Copy link
Author

Is there a way for you test if the affected files play in an older version of Jellyfin?

Unfortunately I won't be able to test it with older versions of Jellyfin. I keep only one production instance

@chiva
Copy link

chiva commented May 25, 2024

Having the same issue here, just started using Jellyfin and installed Themerr

These errors appear all around in the logs when downloading the theme songs:

[2024-05-24 23:29:31.098 +02:00] [INF] [23] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Starting "/usr/lib/jellyfin-ffmpeg/ffprobe" with args "-analyzeduration 200M -probesize 1G -i file:\"/data/movies/Gone with the Wind (1939)/theme.mp3\" -threads 0 -v warning -print_format json -show_streams -show_format"
[2024-05-24 23:29:31.134 +02:00] [ERR] [18] MediaBrowser.Providers.Music.AudioMetadataService: Error in "Probe Provider"
TagLib.CorruptFileException: MPEG audio header not found.
   at TagLib.Mpeg.AudioFile.ReadStart(Int64 start, ReadStyle propertiesStyle)
   at TagLib.NonContainer.File.Read(ReadStyle propertiesStyle)
   at TagLib.NonContainer.File..ctor(IFileAbstraction abstraction, ReadStyle propertiesStyle)
   at TagLib.Mpeg.AudioFile..ctor(IFileAbstraction abstraction, ReadStyle propertiesStyle)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)   at TagLib.File.Create(IFileAbstraction abstraction, String mimetype, ReadStyle propertiesStyle)
   at TagLib.File.Create(String path, String mimetype, ReadStyle propertiesStyle)
   at TagLib.File.Create(String path)
   at MediaBrowser.Providers.MediaInfo.AudioFileProber.FetchDataFromTags(Audio audio, MediaInfo mediaInfo, MetadataRefreshOptions options, Boolean tryExtractEmbeddedLyrics)
   at MediaBrowser.Providers.MediaInfo.AudioFileProber.FetchAsync(Audio audio, MediaInfo mediaInfo, MetadataRefreshOptions options, CancellationToken cancellationToken)
   at MediaBrowser.Providers.MediaInfo.AudioFileProber.Probe[T](T item, MetadataRefreshOptions options, CancellationToken cancellationToken)
   at MediaBrowser.Providers.Manager.MetadataService`2.RunCustomProvider(ICustomMetadataProvider`1 provider, TItemType item, String logName, MetadataRefreshOptions options, RefreshResult refreshResult, CancellationToken cancellationToken)

The movie was identified to this TMDB url: https://www.themoviedb.org/movie/770

Then when visiting the film page

[2024-05-25 12:25:52.804 +02:00] [INF] [35] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Starting "/usr/lib/jellyfin-ffmpeg/ffprobe" with args "-analyzeduration 200M -probesize 1G -i file:\"/data/movies/Gone with the Wind (1939)/theme.mp3\" -threads 0 -v warning -print_format json -show_streams -show_format"
[2024-05-25 12:25:53.065 +02:00] [ERR] [31] MediaBrowser.Providers.Music.AudioMetadataService: Error in "Probe Provider"
TagLib.CorruptFileException: MPEG audio header not found.
   at TagLib.Mpeg.AudioFile.ReadStart(Int64 start, ReadStyle propertiesStyle)
   at TagLib.NonContainer.File.Read(ReadStyle propertiesStyle)
   at TagLib.NonContainer.File..ctor(IFileAbstraction abstraction, ReadStyle propertiesStyle)
   at TagLib.Mpeg.AudioFile..ctor(IFileAbstraction abstraction, ReadStyle propertiesStyle)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)   at TagLib.File.Create(IFileAbstraction abstraction, String mimetype, ReadStyle propertiesStyle)
   at TagLib.File.Create(String path, String mimetype, ReadStyle propertiesStyle)
   at TagLib.File.Create(String path)
   at MediaBrowser.Providers.MediaInfo.AudioFileProber.FetchDataFromTags(Audio audio, MediaInfo mediaInfo, MetadataRefreshOptions options, Boolean tryExtractEmbeddedLyrics)
   at MediaBrowser.Providers.MediaInfo.AudioFileProber.FetchAsync(Audio audio, MediaInfo mediaInfo, MetadataRefreshOptions options, CancellationToken cancellationToken)
   at MediaBrowser.Providers.MediaInfo.AudioFileProber.Probe[T](T item, MetadataRefreshOptions options, CancellationToken cancellationToken)
   at MediaBrowser.Providers.Manager.MetadataService`2.RunCustomProvider(ICustomMetadataProvider`1 provider, TItemType item, String logName, MetadataRefreshOptions options, RefreshResult refreshResult, CancellationToken cancellationToken)
[2024-05-25 12:25:53.071 +02:00] [INF] [31] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for "admin". EnableAudioPlaybackTranscoding: True
[2024-05-25 12:25:53.079 +02:00] [ERR] [31] Jellyfin.Api.Middleware.ExceptionMiddleware: Error processing request. URL "HEAD" "/Audio/fedd9be397fffd557951d1b7d735dac9/universal".
System.NullReferenceException: Object reference not set to an instance of an object.
   at MediaBrowser.Model.Dlna.StreamBuilder.GetAudioDirectPlayProfile(MediaSourceInfo item, MediaStream audioStream, MediaOptions options)
   at MediaBrowser.Model.Dlna.StreamBuilder.GetOptimalAudioStream(MediaSourceInfo item, MediaOptions options)
   at MediaBrowser.Model.Dlna.StreamBuilder.GetOptimalAudioStream(MediaOptions options)
   at Jellyfin.Api.Helpers.MediaInfoHelper.SetDeviceSpecificData(BaseItem item, MediaSourceInfo mediaSource, DeviceProfile profile, ClaimsPrincipal claimsPrincipal, Nullable`1 maxBitrate, Int64 startTimeTicks, String mediaSourceId, Nullable`1 audioStreamIndex, Nullable`1 subtitleStreamIndex, Nullable`1 maxAudioChannels, String playSessionId, Guid userId, Boolean enableDirectPlay, Boolean enableDirectStream, Boolean enableTranscoding, Boolean allowVideoStreamCopy, Boolean allowAudioStreamCopy, IPAddress ipAddress)
   at Jellyfin.Api.Controllers.UniversalAudioController.GetUniversalAudioStream(Guid itemId, String[] container, String mediaSourceId, String deviceId, Nullable`1 userId, String audioCodec, Nullable`1 maxAudioChannels, Nullable`1 transcodingAudioChannels, Nullable`1 maxStreamingBitrate, Nullable`1 audioBitRate, Nullable`1 startTimeTicks, String transcodingContainer, Nullable`1 transcodingProtocol, Nullable`1 maxAudioSampleRate, Nullable`1 maxAudioBitDepth, Nullable`1 enableRemoteMedia, Boolean breakOnNonKeyFrames, Boolean enableRedirection)
   at lambda_method1572(Closure, Object)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Jellyfin.Api.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager)
   at Jellyfin.Api.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager)
   at Jellyfin.Api.Middleware.IPBasedAccessValidationMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager)
   at Jellyfin.Api.Middleware.LanFilteringMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Api.Middleware.QueryStringDecodingMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.ReDoc.ReDocMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Api.Middleware.RobotsRedirectionMiddleware.Invoke(HttpContext httpContext)
   at Jellyfin.Api.Middleware.LegacyEmbyRouteRewriteMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext context)
   at Jellyfin.Api.Middleware.ResponseTimeMiddleware.Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager)
   at Jellyfin.Api.Middleware.ExceptionMiddleware.Invoke(HttpContext context)
[2024-05-25 12:25:53.238 +02:00] [INF] [34] Jellyfin.Api.Controllers.UniversalAudioController: GetPostedPlaybackInfo profile: DeviceProfile { Name: null, Id: null, MaxStreamingBitrate: 8000000, MaxStaticBitrate: 8000000, MusicStreamingTranscodingBitrate: 128000, MaxStaticMusicBitrate: 8000000, DirectPlayProfiles: [DirectPlayProfile { Container: "opus", AudioCodec: null, VideoCodec: null, Type: Audio }, DirectPlayProfile { Container: "webm", AudioCodec: "opus", VideoCodec: null, Type: Audio }, DirectPlayProfile { Container: "mp3", AudioCodec: null, VideoCodec: null, Type: Audio }, DirectPlayProfile { Container: "aac", AudioCodec: null, VideoCodec: null, Type: Audio }, DirectPlayProfile { Container: "m4a", AudioCodec: "aac", VideoCodec: null, Type: Audio }, DirectPlayProfile { Container: "m4b", AudioCodec: "aac", VideoCodec: null, Type: Audio }, DirectPlayProfile { Container: "flac", AudioCodec: null, VideoCodec: null, Type: Audio }, DirectPlayProfile { Container: "webma", AudioCodec: null, VideoCodec: null, Type: Audio }, DirectPlayProfile { Container: "webm", AudioCodec: "webma", VideoCodec: null, Type: Audio }, DirectPlayProfile { Container: "wav", AudioCodec: null, VideoCodec: null, Type: Audio }, DirectPlayProfile { Container: "ogg", AudioCodec: null, VideoCodec: null, Type: Audio }], TranscodingProfiles: [TranscodingProfile { Container: "mp4", Type: Audio, VideoCodec: "", AudioCodec: "aac", Protocol: hls, EstimateContentLength: False, EnableMpegtsM2TsMode: False, TranscodeSeekInfo: Auto, CopyTimestamps: False, Context: Streaming, EnableSubtitlesInManifest: False, MaxAudioChannels: null, MinSegments: 0, SegmentLength: 0, BreakOnNonKeyFrames: False, Conditions: [] }], ContainerProfiles: [], CodecProfiles: [], SubtitleProfiles: [] }
[2024-05-25 12:25:53.245 +02:00] [INF] [34] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Starting "/usr/lib/jellyfin-ffmpeg/ffprobe" with args "-analyzeduration 200M -probesize 1G -i file:\"/data/movies/Gone with the Wind (1939)/theme.mp3\" -threads 0 -v warning -print_format json -show_streams -show_format"
[2024-05-25 12:25:53.448 +02:00] [ERR] [34] MediaBrowser.Providers.Music.AudioMetadataService: Error in "Probe Provider"
TagLib.CorruptFileException: MPEG audio header not found.
   at TagLib.Mpeg.AudioFile.ReadStart(Int64 start, ReadStyle propertiesStyle)
   at TagLib.NonContainer.File.Read(ReadStyle propertiesStyle)
   at TagLib.NonContainer.File..ctor(IFileAbstraction abstraction, ReadStyle propertiesStyle)
   at TagLib.Mpeg.AudioFile..ctor(IFileAbstraction abstraction, ReadStyle propertiesStyle)
   at InvokeStub_AudioFile..ctor(Object, Span`1)
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)   at TagLib.File.Create(IFileAbstraction abstraction, String mimetype, ReadStyle propertiesStyle)
   at TagLib.File.Create(String path, String mimetype, ReadStyle propertiesStyle)
   at TagLib.File.Create(String path)
   at MediaBrowser.Providers.MediaInfo.AudioFileProber.FetchDataFromTags(Audio audio, MediaInfo mediaInfo, MetadataRefreshOptions options, Boolean tryExtractEmbeddedLyrics)
   at MediaBrowser.Providers.MediaInfo.AudioFileProber.FetchAsync(Audio audio, MediaInfo mediaInfo, MetadataRefreshOptions options, CancellationToken cancellationToken)
   at MediaBrowser.Providers.MediaInfo.AudioFileProber.Probe[T](T item, MetadataRefreshOptions options, CancellationToken cancellationToken)
   at MediaBrowser.Providers.Manager.MetadataService`2.RunCustomProvider(ICustomMetadataProvider`1 provider, TItemType item, String logName, MetadataRefreshOptions options, RefreshResult refreshResult, CancellationToken cancellationToken)
[2024-05-25 12:25:53.472 +02:00] [INF] [34] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for "admin". EnableAudioPlaybackTranscoding: True
[2024-05-25 12:25:53.476 +02:00] [ERR] [34] Jellyfin.Api.Middleware.ExceptionMiddleware: Error processing request. URL "GET" "/Audio/fedd9be397fffd557951d1b7d735dac9/universal".
System.NullReferenceException: Object reference not set to an instance of an object.
   at MediaBrowser.Model.Dlna.StreamBuilder.GetAudioDirectPlayProfile(MediaSourceInfo item, MediaStream audioStream, MediaOptions options)
   at MediaBrowser.Model.Dlna.StreamBuilder.GetOptimalAudioStream(MediaSourceInfo item, MediaOptions options)
   at MediaBrowser.Model.Dlna.StreamBuilder.GetOptimalAudioStream(MediaOptions options)
   at Jellyfin.Api.Helpers.MediaInfoHelper.SetDeviceSpecificData(BaseItem item, MediaSourceInfo mediaSource, DeviceProfile profile, ClaimsPrincipal claimsPrincipal, Nullable`1 maxBitrate, Int64 startTimeTicks, String mediaSourceId, Nullable`1 audioStreamIndex, Nullable`1 subtitleStreamIndex, Nullable`1 maxAudioChannels, String playSessionId, Guid userId, Boolean enableDirectPlay, Boolean enableDirectStream, Boolean enableTranscoding, Boolean allowVideoStreamCopy, Boolean allowAudioStreamCopy, IPAddress ipAddress)
   at Jellyfin.Api.Controllers.UniversalAudioController.GetUniversalAudioStream(Guid itemId, String[] container, String mediaSourceId, String deviceId, Nullable`1 userId, String audioCodec, Nullable`1 maxAudioChannels, Nullable`1 transcodingAudioChannels, Nullable`1 maxStreamingBitrate, Nullable`1 audioBitRate, Nullable`1 startTimeTicks, String transcodingContainer, Nullable`1 transcodingProtocol, Nullable`1 maxAudioSampleRate, Nullable`1 maxAudioBitDepth, Nullable`1 enableRemoteMedia, Boolean breakOnNonKeyFrames, Boolean enableRedirection)
   at lambda_method1580(Closure, Object)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Jellyfin.Api.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager)
   at Jellyfin.Api.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager)
   at Jellyfin.Api.Middleware.IPBasedAccessValidationMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager)
   at Jellyfin.Api.Middleware.LanFilteringMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Api.Middleware.QueryStringDecodingMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.ReDoc.ReDocMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Api.Middleware.RobotsRedirectionMiddleware.Invoke(HttpContext httpContext)
   at Jellyfin.Api.Middleware.LegacyEmbyRouteRewriteMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext context)
   at Jellyfin.Api.Middleware.ResponseTimeMiddleware.Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager)
   at Jellyfin.Api.Middleware.ExceptionMiddleware.Invoke(HttpContext context)
[2024-05-25 12:25:53.811 +02:00] [INF] [34] Emby.Server.Implementations.Session.SessionManager: Playback stopped reported by app "Jellyfin Web" "10.9.2" playing "theme". Stopped at "0" ms
[2024-05-25 12:25:53.844 +02:00] [INF] [16] Jellyfin.Plugin.PlaybackReporting.EventMonitorEntryPoint: Playback stop did not have a tracker : "TW96aWxsYS81LjAgKE1hY2ludG9zaDsgSW50ZWwgTWFjIE9TIFggMTBfMTVfNykgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzEyMy4wLjAuMCBTYWZhcmkvNTM3LjM2fDE3MTI0Nzg0NjIyNTY1-9d9f30c13c71478a80554d2a02a98bdc-fedd9be397fffd557951d1b7d735dac9"

And this on the web browser console:

universal:1  GET http://192.168.5.5:8096/Audio/fedd9be397fffd557951d1b7d735dac9/universal?UserId=XXXX&DeviceId=XXXX&MaxStreamingBitrate=140000000&Container=opus%2Cwebm%7Copus%2Cmp3%2Caac%2Cm4a%7Caac%2Cm4b%7Caac%2Cflac%2Cwebma%2Cwebm%7Cwebma%2Cwav%2Cogg&TranscodingContainer=mp4&TranscodingProtocol=hls&AudioCodec=aac&api_key=XXXX&PlaySessionId=1716629769916&StartTimeTicks=0&EnableRedirection=true&EnableRemoteMedia=false 500 (Internal Server Error)
 Requesting url without automatic networking: http://192.168.5.5:8096/Sessions/Playing
 Requesting url without automatic networking: http://192.168.5.5:8096/Sessions/Playing/Progress
 [playbackmanager] onPlaybackError:  {type: 'MEDIA_NOT_SUPPORTED', streamInfo: {…}}

@chiva
Copy link

chiva commented May 25, 2024

The files are being downloaded in AAC format.
Here's the output from MediaInfo

General
Complete name                            : theme.mp3
Format                                   : dash
Codec ID                                 : dash (iso6/mp41)
File size                                : 3.98 MiB
Duration                                 : 4 min 17 s
Overall bit rate                         : 129 kb/s
Encoded date                             : 2024-03-14 06:17:01 UTC
Tagged date                              : 2024-03-14 06:17:01 UTC

Audio
ID                                       : 1
Format                                   : AAC LC
Format/Info                              : Advanced Audio Codec Low Complexity
Codec ID                                 : 2 / 40 / mp4a-40-2
Duration                                 : 4 min 17 s
Bit rate                                 : 128 kb/s
Channel(s)                               : 2 channels
Channel layout                           : L R
Sampling rate                            : 44.1 kHz
Frame rate                               : 43.066 FPS (1024 SPF)
Compression mode                         : Lossy
Stream size                              : 3.93 MiB (99%)
Title                                    : ISO Media file produced by Google Inc.
Language                                 : French
Encoded date                             : 2024-03-14 06:17:01 UTC
Tagged date                              : 2024-03-14 06:17:01 UTC

This is the output from a working theme.mp3 file

General
Complete name                            : theme.mp3
Format                                   : MPEG Audio
File size                                : 455 KiB
Duration                                 : 29 s 100 ms
Overall bit rate mode                    : Constant
Overall bit rate                         : 128 kb/s
Writing library                          : LAME3.98r

Audio
Format                                   : MPEG Audio
Format version                           : Version 1
Format profile                           : Layer 3
Format settings                          : Joint stereo / MS Stereo
Duration                                 : 29 s 100 ms
Bit rate mode                            : Constant
Bit rate                                 : 128 kb/s
Channel(s)                               : 2 channels
Sampling rate                            : 44.1 kHz
Frame rate                               : 38.281 FPS (1152 SPF)
Compression mode                         : Lossy
Stream size                              : 455 KiB (100%) / 455 KiB (100%) / 455 KiB (100%)
Writing library                          : LAME3.98r
Encoding settings                        : -m j -V 4 -q 3 -lowpass 17 -b 128


@ReenigneArcher
Copy link
Member

@chiva what version of Themerr-jellyfin were you using when the incorrect formats were downloaded? Any chance you once used the very first version of Themerr?

As far as I can see this shouldn't be possible:

.Where(s => s.Container == Container.Mp4)

It has been like this since #98 was merged, which was included in the v0.0.2 release (before we switched to calendar versioning).

@chiva
Copy link

chiva commented May 25, 2024

I'm running 2024.523.2124.32.
It's super strange, some files work, some doesn't, while they are all AAC encoded, even though named .mp3.

Comparing the files with ffprobe they are all exactly the same, just changing the length and bitrate.
But bitrate doesn't seem to be an issue, as the I've seen themes working with higher and lower bitrate than those that doesn't.

root@88b6568ac0e3:/# /usr/lib/jellyfin-ffmpeg/ffprobe -analyzeduration 200M -probesize 1G -i file:"/data/movies/Gone with the Wind (1939)/theme.mp3" -threads 0 -v warning -print_format json -show_streams -show_format
{
    "streams": [
        {
            "index": 0,
            "codec_name": "aac",
            "codec_long_name": "AAC (Advanced Audio Coding)",
            "profile": "LC",
            "codec_type": "audio",
            "codec_tag_string": "mp4a",
            "codec_tag": "0x6134706d",
            "sample_fmt": "fltp",
            "sample_rate": "44100",
            "channels": 2,
            "channel_layout": "stereo",
            "bits_per_sample": 0,
            "initial_padding": 0,
            "id": "0x1",
            "r_frame_rate": "0/0",
            "avg_frame_rate": "0/0",
            "time_base": "1/44100",
            "start_pts": 0,
            "start_time": "0.000000",
            "duration_ts": 11361280,
            "duration": "257.625397",
            "bit_rate": "4963",
            "extradata_size": 16,
            "disposition": {
                "default": 1,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0,
                "timed_thumbnails": 0,
                "captions": 0,
                "descriptions": 0,
                "metadata": 0,
                "dependent": 0,
                "still_image": 0
            },
            "tags": {
                "creation_time": "2024-03-14T06:17:01.000000Z",
                "language": "fra",
                "handler_name": "ISO Media file produced by Google Inc.",
                "vendor_id": "[0][0][0][0]"
            }
        }
    ],
    "format": {
        "filename": "file:/data/movies/Gone with the Wind (1939)/theme.mp3",
        "nb_streams": 1,
        "nb_programs": 0,
        "format_name": "mov,mp4,m4a,3gp,3g2,mj2",
        "format_long_name": "QuickTime / MOV",
        "start_time": "0.000000",
        "duration": "257.625397",
        "size": "4170066",
        "bit_rate": "129492",
        "probe_score": 100,
        "tags": {
            "major_brand": "dash",
            "minor_version": "0",
            "compatible_brands": "iso6mp41",
            "creation_time": "2024-03-14T06:17:01.000000Z"
        }
    }
}

Command returns fine, but this is the exact same command found in the logs that raises an exception:

[2024-05-25 12:25:52.804 +02:00] [INF] [35] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Starting "/usr/lib/jellyfin-ffmpeg/ffprobe" with args "-analyzeduration 200M -probesize 1G -i file:\"/data/movies/Gone with the Wind (1939)/theme.mp3\" -threads 0 -v warning -print_format json -show_streams -show_format"
[2024-05-25 12:25:53.065 +02:00] [ERR] [31] MediaBrowser.Providers.Music.AudioMetadataService: Error in "Probe Provider"
TagLib.CorruptFileException: MPEG audio header not found.
   at TagLib.Mpeg.AudioFile.ReadStart(Int64 start, ReadStyle propertiesStyle)
   at TagLib.NonContainer.File.Read(ReadStyle propertiesStyle)
   at TagLib.NonContainer.File..ctor(IFileAbstraction abstraction, ReadStyle propertiesStyle)
   at TagLib.Mpeg.AudioFile..ctor(IFileAbstraction abstraction, ReadStyle propertiesStyle)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)   at TagLib.File.Create(IFileAbstraction abstraction, String mimetype, ReadStyle propertiesStyle)
   at TagLib.File.Create(String path, String mimetype, ReadStyle propertiesStyle)
   at TagLib.File.Create(String path)
   at MediaBrowser.Providers.MediaInfo.AudioFileProber.FetchDataFromTags(Audio audio, MediaInfo mediaInfo, MetadataRefreshOptions options, Boolean tryExtractEmbeddedLyrics)
   at MediaBrowser.Providers.MediaInfo.AudioFileProber.FetchAsync(Audio audio, MediaInfo mediaInfo, MetadataRefreshOptions options, CancellationToken cancellationToken)
   at MediaBrowser.Providers.MediaInfo.AudioFileProber.Probe[T](T item, MetadataRefreshOptions options, CancellationToken cancellationToken)
   at MediaBrowser.Providers.Manager.MetadataService`2.RunCustomProvider(ICustomMetadataProvider`1 provider, TItemType item, String logName, MetadataRefreshOptions options, RefreshResult refreshResult, CancellationToken cancellationToken)

I've deleted all theme.mp3 and themerr.json files from my media folders, and redownloaded everything, but having the same issue on the same films.

@chiva
Copy link

chiva commented May 25, 2024

Btw, the theme.mp3 that was really mp3 encoded, was added to the library by Jellyfin Theme Songs Plugin.
I posted the output from MediaInfo just as a way to compare working vs non-working and that mp3 files do actually work.

AAC seems to also work, but seems to be a bit hit and miss at this moment, can't find any correlation.

@ReenigneArcher
Copy link
Member

Our plugin saves theme songs to theme.mp3 as that is the only path supported by Jellyfin (as far as I know). If they are being saved in the wrong container it's either a bug with https://github.com/Tyrrrz/YoutubeExplode or YouTube itself.

It's probably not wise to use both of these plugins together. The other one is using Plex's theme song database.

can't find any correlation

My guess is different headers in the files.

@chiva
Copy link

chiva commented May 25, 2024

Youtube doesn't have mp3 as a native available encoding on their service, so when requesting mp4 audio, it'll serve AAC.
Having AAC seems to be fine most of the time, as even though named as .mp3 Jellyfin is probably detecting the encoding by the header, and thus ignoring the inconsistent filename.

If we want to have real mp3 files, we need to reencode the file from AAC into mp3.
For that, we can use YoutubeExplode.Converter by doing the following in here:

public bool SaveMp3(string destination, string videoUrl)

using YoutubeExplode;
using YoutubeExplode.Converter;
[...]

        public bool SaveMp3(string destination, string videoUrl)
        {
            try
            {
                Task.Run(async () =>
                {
                    var youtube = new YoutubeClient();
                    await youtube.Videos.DownloadAsync(videoUrl, destination);
                });
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Unable to download {VideoUrl} to {Destination}", videoUrl, destination);
                return false;
            }

            return WaitForFile(destination, 30000);
        }

I've compiled a test version of the plugin with those changes, and adding the YoutubeExplode.Converter dependency, but having issues with Jellyfin loading that new dll:

[2024-05-25 18:24:04.357 +02:00] [INF] [1] Emby.Server.Implementations.Plugins.PluginManager: Loaded assembly "YoutubeExplode, Version=6.3.16.0, Culture=neutral, PublicKeyToken=null" from "/config/data/plugins/Themerr_2024.523.2124.32/YoutubeExplode.dll"
[2024-05-25 18:24:04.359 +02:00] [ERR] [1] Emby.Server.Implementations.Plugins.PluginManager: Failed to load assembly "/config/data/plugins/Themerr_2024.523.2124.32/YoutubeExplode.Converter.dll". This error occurs when a plugin references an incompatible version of one of the shared libraries. Disabling plugin
System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types.
Could not load file or assembly 'CliWrap, Version=3.6.6.0, Culture=neutral, PublicKeyToken=XXXX'. The system cannot find the file specified.

   at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
   at System.Reflection.RuntimeModule.GetTypes()
   at Emby.Server.Implementations.Plugins.PluginManager.LoadAssemblies()+MoveNext()
System.IO.FileNotFoundException: Could not load file or assembly 'CliWrap, Version=3.6.6.0, Culture=neutral, PublicKeyToken=XXXX'. The system cannot find the file specified.

Guess I'm missing the CliWrap dependency 🤔
First time playing with C# and Jellyfin development, so not familiar with all the edge cases.

I'm currently testing both plugins, as standing up my Jellyfin instance, so checking features and capabilities of all offerings 😄

@ReenigneArcher
Copy link
Member

Thanks for digging in to the issue.

This plugin is really the only experience I have with C# and Jellyfin as well. Jellyfin has a dev chat on their discord server though, you might get a quick answer there.

@ReenigneArcher
Copy link
Member

ReenigneArcher commented May 25, 2024

@chiva

That converter requires ffmpeg, does it automatically detect jellyfin's ffmpeg?

This test might also need to be adjusted here:

var validMp3Signatures = new Dictionary<string, int>
{
{ "66-74-79-70-64-61-73-68", 4 }, // Mp4 container?
{ "66-74-79-70-69-73-6F-6D", 4 }, // Mp4 container
{ "49-44-33", 0 }, // ID3
{ "FF-FB", 0 }, // MPEG-1 Layer 3
{ "FF-F3", 0 }, // MPEG-1 Layer 3
{ "FF-F2", 0 }, // MPEG-1 Layer 3
};

@chiva
Copy link

chiva commented May 25, 2024

Yup, needs ffmpeg, I think I can send a PR, will do some more testing

@chiva
Copy link

chiva commented Aug 9, 2024

Hey,

I've tried multiple times to setup a proper dev environment that allows to debug Jellyfin, using VS Code and Visual Studio both in Mac and Windows, but couldn't get the env setup properly.

Will post the idea here:

The video needs to be converted, and we can use the YouTubeClient.Videos.Explode lib to convert using ffmpeg to our desired output.

We can mostly copy the code from the jellyfin-plugin-tmdb-trailers plugin that does exactly this.
https://github.com/crobibero/jellyfin-plugin-tmdb-trailers/blob/7f86240ae0f76e09a58a08e2bcd4b223a0b6beeb/Jellyfin.Plugin.Tmdb.Trailers/TmdbManager.cs#L839-L843

            var mediaSource = await GetMediaSource(item.Id);
            if (mediaSource is null)
            {
                continue;
            }

            try
            {
                await youTubeClient.Videos.DownloadAsync(
                    mediaSource.TranscodingUrl,
                    destination,
                    cfg => cfg.SetFFmpegPath(_mediaEncoder.EncoderPath),
                    cancellationToken: cancellationToken);
            }
            catch (Exception e)
            {
                _logger.LogWarning(e, "Unable to cache {Path}", mediaSource.Path);
            }

Add the IMediaEncoder to fetch the ffmpeg binary path:

    private readonly IMediaEncoder _mediaEncoder;
    /// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>

We will also need to add the dependency into:

<PackageReference Include="YoutubeExplode.Converter" Version="6.3.16" />

and https://github.com/LizardByte/Themerr-jellyfin/blob/master/build.yaml

artifacts:
  - "Jellyfin.Plugin.Themerr.dll"
  - "YoutubeExplode.dll"
  - "YoutubeExplode.Converter.dll"

I tested it once, but didn't manage to make it work, I think it's because dependencies were not properly compiled and linked into the project.
But that should be it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants