jellyfin / jellyfin

The Free Software Media System
https://jellyfin.org
GNU General Public License v2.0
35.14k stars 3.19k forks source link

[Issue]: Computing blurhash fails for paths containing a | character #10375

Open antlarr opened 1 year ago

antlarr commented 1 year ago

Please describe your bug

I installed a few days ago the Jellyfin 10.8.11 docker image and added my music collection, which is completely tagged with Picard with MusicBrainz tags. I also have a cover.jpg file in each album directory.

After Jellyfin finished updating the library, I noticed some error messages in the logs like this:

[2023-10-08 08:22:50.017 +00:00] [ERR] [27] Emby.Server.Implementations.Library.LibraryManager: Cannot compute blurhash for " bar/cover.jpg"
System.NullReferenceException: Object reference not set to an instance of an object.
   at BlurHashSharp.SkiaSharp.BlurHashEncoder.Encode(Int32 xComponent, Int32 yComponent, String filename, Int32 maxWidth, Int32 maxHeight)
   at Jellyfin.Drawing.Skia.SkiaEncoder.GetImageBlurHash(Int32 xComp, Int32 yComp, String path)
   at Emby.Drawing.ImageProcessor.GetImageBlurHash(String path, ImageDimensions imageDimensions)
   at Emby.Server.Implementations.Library.LibraryManager.UpdateImagesAsync(BaseItem item, Boolean forceUpdate)

I checked for which file these errors were happening and in all cases there was a '|' character just before the path Jellyfin is using. For example, in the error message above the path was something like /media/foo | bar/cover.jpg (redacted, of course :) ).

Also, there's a second type of exceptions thrown that seem to be related to that

[2023-10-08 06:39:59.126 +00:00] [ERR] [73] MediaBrowser.Providers.Folders.FolderMetadataService: Error in "Dynamic Image Provider"                                                
System.IO.DirectoryNotFoundException: Could not find a part of the path '/ someotherbar/cover.jpg'.                                                                   
   at Interop.CheckIo(Error error, String path, Boolean isDirectory, Func`2 errorRewriter)                                                                                         
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)                                                                                    
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)            
   at System.IO.FileSystem.CopyFile(String sourceFullPath, String destFullPath, Boolean overwrite)                                                                                 
   at Emby.Server.Implementations.Images.BaseDynamicImageProvider`1.CreateSingleImage(IEnumerable`1 itemsWithImages, String outputPathWithoutExtension, ImageType imageType)       
   at Emby.Server.Implementations.Images.BaseDynamicImageProvider`1.FetchToFileInternal(BaseItem item, IReadOnlyList`1 itemsWithImages, ImageType imageType, CancellationToken cancellationToken)
   at Emby.Server.Implementations.Images.BaseDynamicImageProvider`1.FetchAsync(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)

In this case, the path that should have been used is: /media/someotherfoo | someotherbar/cover.jpg. But note that this time the path used is not starting right after the next character after '|' but it's replacing the '|' character with a '/' and starting from there. Also, all paths containing '|' seem to show an error like the first one, but I only noticed some of them in the second form.

Jellyfin Version

10.8.z

if other:

No response

Environment

- Virtualization: Docker image jellyfin/jellyfin:10.8.11
- Clients: Browser, Android
- FFmpeg Version: 5.1.3-Jellyfin
- Plugins:AudioDB, Cover Art Archive, MusicBrainz, OMDb, Playback Reporting, Studio Images, TMDb
- Reverse Proxy: none
- Base URL: none
- Networking: Host
- Storage: local (docker volume mounted on /media)

Jellyfin logs

[2023-10-08 08:22:50.017 +00:00] [ERR] [27] Emby.Server.Implementations.Library.LibraryManager: Cannot compute blurhash for " bar/cover.jpg"
System.NullReferenceException: Object reference not set to an instance of an object.
   at BlurHashSharp.SkiaSharp.BlurHashEncoder.Encode(Int32 xComponent, Int32 yComponent, String filename, Int32 maxWidth, Int32 maxHeight)
   at Jellyfin.Drawing.Skia.SkiaEncoder.GetImageBlurHash(Int32 xComp, Int32 yComp, String path)
   at Emby.Drawing.ImageProcessor.GetImageBlurHash(String path, ImageDimensions imageDimensions)
   at Emby.Server.Implementations.Library.LibraryManager.UpdateImagesAsync(BaseItem item, Boolean forceUpdate)

----

[2023-10-08 06:39:59.126 +00:00] [ERR] [73] MediaBrowser.Providers.Folders.FolderMetadataService: Error in "Dynamic Image Provider"                                                
System.IO.DirectoryNotFoundException: Could not find a part of the path '/ someotherbar/cover.jpg'.                                                                   
   at Interop.CheckIo(Error error, String path, Boolean isDirectory, Func`2 errorRewriter)                                                                                         
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)                                                                                    
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)            
   at System.IO.FileSystem.CopyFile(String sourceFullPath, String destFullPath, Boolean overwrite)                                                                                 
   at Emby.Server.Implementations.Images.BaseDynamicImageProvider`1.CreateSingleImage(IEnumerable`1 itemsWithImages, String outputPathWithoutExtension, ImageType imageType)       
   at Emby.Server.Implementations.Images.BaseDynamicImageProvider`1.FetchToFileInternal(BaseItem item, IReadOnlyList`1 itemsWithImages, ImageType imageType, CancellationToken cancellationToken)
   at Emby.Server.Implementations.Images.BaseDynamicImageProvider`1.FetchAsync(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)

FFmpeg logs

No response

Please attach any browser or client logs here

No response

Please attach any screenshots here

No response

Code of Conduct

Bond-009 commented 1 year ago

I'm closing this as a duplicate of #3756 We use both * and | as delimiters in the DB and I'm assuming that's the underlying issue

antlarr commented 1 year ago

I'm closing this as a duplicate of #3756 We use both * and | as delimiters in the DB and I'm assuming that's the underlying issue

I have files and directories that contain * and the cover images within those don't give any error in the log. Do you want me to do some checks instead of assuming that's the issue? Just in case it helps, I'm familiar with sqlite, so I wouldn't mind looking in the DB if needed.

Bond-009 commented 1 year ago

That sounds good, could you test master so we are sure we aren't chasing old bugs?

antlarr commented 1 year ago

I installed the jellyfin/jellyfin:20231013.5-unstable docker image, updated the library and those messages appeared again in the log, so the issue is still there.

Bond-009 commented 1 year ago

And you don't experience issues with images containing * in the filename?

antlarr commented 1 year ago

There's no log mention of any error related to * in paths. I have a path like /media/someartist/2012 - foo*bar/ with songs and a cover.jpg file inside and there's no error related to that in the logs (I also grepped for "foo" and for "bar" just in case the message had a splitted path like the | case). There's still an issue and it's that in the albumartist page for that artist the album is using an image that must have been obtained from some place online because I don't have that image on disk. Still when I go to the album page, the cover.jpg file from disk is used as album cover. I tried to find out where was that image obtained from and I found it was the first fanart image from theaudiodb for that artist (cut as a square aspect ratio from the image center).

Also, in a different case in which the * character is in the artist directory level (like: /media/some*artist/2001 - album/), the albumartist page shows the default album cover (the one used when an album doesn't have any cover art) but opening the album shows the cover.jpg file inside the album directory correctly. In this case, btw, the albumartist doesn't have any fanart in theaudiodb.

Btw, I looked for the cases of '|' used in the path ( like /media/artist/some|album) and the cover image is shown correctly both in the album pages and in the albumartist pages even if the error from the first comment above is shown in the logs. I'm curious now, what are blurhashes used for?

Bond-009 commented 1 year ago

Blurhashes are placeholders used while the images are loading. I'll reopen this as it doesn't look 100% the same as the issue with *