jellyfin-plugin-tvheadend icon indicating copy to clipboard operation
jellyfin-plugin-tvheadend copied to clipboard

No channel logos and picons

Open Shadowghost opened this issue 4 years ago • 34 comments

I have a working tvheadend server which provides picons and channel logos (works fine over it's webUI and on Kodi) but Jellyfin doesn't show any of them on the webUI - episode images are displayed properly (should movie posters be scraped from an external source and be displayed?). I only tested on current nightly since I don't want to mess up my setup right now by downgrading. Tell me what logs you need and I'll gladly provide them :)

Shadowghost avatar Feb 01 '20 18:02 Shadowghost

We’re pretty sure this code doesn’t import the images because the original creator didn’t care to do so (I could be wrong).

This would need to be added in as an enhancement.

anthonylavado avatar Feb 07 '20 04:02 anthonylavado

Actually it seems this is an issue that has been solved in a later version of the original plugin of Emby. As per this thread:

https://emby.media/community/index.php?/topic/55451-tvheadend-no-channel-icons-after-upgrades/

The problem stems from the fact TVheadend server does not return a MIME type when the icons are served locally (to the TVheadend server ) via the local file system, which is quite typical in TVheadend setups. Many other TVheadend clients (Kodi, Android apps, etc.) do not suffer from this issue because they have probably implemented a sort of hack, like the one the Emby programmers have implemented in later versions (that is, "stuffing" a MIME type just by looking at the request paths).

See this thread:

https://emby.media/community/index.php?/topic/20107-tvheadend-plugin-for-emby-beta-1/page-36#entry574403

Wrong-Code avatar May 09 '20 16:05 Wrong-Code

Sorry, I stand corrected and I have trusted too much old information which, while sharing the same issue, has quite surely nothing to do with the Jellyfin case.

I've spent some time on the plugin code, I've built a version with some more logging and apparently the problem may be in the code from Jellyfin, not the plugin. The missing logo issue occurs when the TVheadend server is accessed using a named user with a password, a case for which there is already provision in the plugin, AND when accessing the TVheadend server without a username/password (i.e. anonymous) is not permitted. As soon as an anonymous access is again permitted on the TVheadend server (user and password set to '*'), the channels' icons are displayed correctly. Of course leaving the anonymous access active is not an ideal setup.

As far as I've understood, the GetChannelsAsync method in the TVheadend plugin correctly compiles the list of channels, including the URLs to their respective logos each having the correct username/password embedded. I have confirmed that using one of those URLs in a browser the TVheadend server returns the proper logo image. So, somewhere in the code of the main Jellyfin this username/password pair seems to get lost, thus anonymizing the URL issued to the TVheadend server, hence the "Unauthorized" answer it returns when the anonymous access to the service is not permitted.

Unfortunately I have no knowledge of the main Jellyfin code, so I am not able right now to fix the code. I apologize for the confusion stemming from my previous comment.

Wrong-Code avatar May 10 '20 15:05 Wrong-Code

I have the same problem with the missing channel icons (using jellyfin + tvheadend), but even if the anonymous account is enabled in tvheadend. Have you done something specific with the anonymous account? BTW, this issue seems to be related to https://github.com/jellyfin/jellyfin/issues/2063

stueble avatar Jun 02 '20 16:06 stueble

Nope, I just enabled it to browse and view the channels on the Tvheadend server, nothing really special. Ah, yes, there is one thing that you should check: enabling the (p)icons cache on the Tvheadend server created a total mess with the icons, to the point that even the Kodi PVR extension went mad. Unfortunately it seems that some Tvheadend clients have a local cache by themselves, so if you are in doubt: disable the icon caching on the server side, and remove any (p)icon cached on the client side.

Edit: yes, as I wrote the issue seems to be in the main calling code, not in the extension.

Wrong-Code avatar Jun 02 '20 21:06 Wrong-Code

Disabling the icon cache does unfortunately not help. However, the channel icon/picon settings in my configuration are completely untouched, i.e., I have not configured any channel icon or picon locally. Instead, the EPG is providing the channel icon data which is a link to the website of the EPG source. TVHeadend uses these http-Links without any problems, for both channel icons and EPG screenshots. I don't know whether TVHeadend forwards these links to jellyfin or whether it downloads the icons and then sends them to jellyfin. Any idea how it works?

stueble avatar Jun 03 '20 11:06 stueble

I checked what tvheadend returns when using the json-API, both with cache enabled and disabled. The returned URL correctly shows the channel icon, even with a machine that has no authentication information for tvheadend. Thus, I assume that my configuration has another error. BTW, in the jellyfin log I get the error "Emby.Server.Implementations.HttpServer.HttpListenerHost: Error processing request. URL: "http://IP:PORT/Items/20f785dccdae7a66dfe57537e1b8063c/Images/Primary?maxWidth=720&tag=543b6ca4c9f21c87d81daf7a932499c0&quality=90" System.UriFormatException: Invalid URI: The hostname could not be parsed."

stueble avatar Jun 03 '20 15:06 stueble

I just started looking into the code, so maybe its nothing. But I noticed that in the TVHeadend plugin, there are two methods to get the icon Url: getChannelImageUrl(), which adds username+password to the URL when using TVHeadend image cache, and GetChannelImage(), which does not. If GetChannelImage() would use GetChannelImageUrl() instead of building the URL itself, the problem with the required anonymous access to TVHeadend may be gone?

Unfortunately, this does not fix my problem, since I have an anonymous account, but its still not working. I am currently fighting with the debug output. I get (with version 5.0.0) less output than it should (according to the code in master).

stueble avatar Jun 07 '20 00:06 stueble

Hi, I have the same problem. Both internally and via proxy server settings from externally via a DynDNS address Jellyfin denies access to the channel Picons. Use the TVHeadend plugin with user plus password. On the server itself TVHeadend the picons are local on the server and are displayed correctly. What exactly is the problem? Should an anonymous user without password be created in TVHeadend? Here is the error message and the current settings of the server TVHeadend. With Proxy I have already deactivated the hook, also no success.

Thanks img_060_jellyfin_error img_059_jellyfin_error

Answer: GEThttps://dynadresse.ddnss.com:Port/Items/2c460aa4f732e9da406c51edfc8cf2d0/Images/Primary?maxWidth=480&tag=543b6ca4c9f21c87d81daf7a932499c0&quality=90 [HTTP/1.1 500 Internal Server Error 38ms]

Error processing request

topa-LE avatar Nov 08 '20 10:11 topa-LE

I have the same problem in v10.7.0 RC2. The logfile says this:

[2021-01-03 12:25:32.649 +01:00] [ERR] Error processing request. URL "GET" "/Items/afc050d9852b7308dce063fd3e0c3a16/Images/Primary".
System.NullReferenceException: Object reference not set to an instance of an object.
   at MediaBrowser.Providers.Manager.ProviderManager.SaveImage(BaseItem item, String url, ImageType type, Nullable`1 imageIndex, CancellationToken cancellationToken)
   at Emby.Server.Implementations.Library.LibraryManager.ConvertImageToLocal(BaseItem item, ItemImageInfo image, Int32 imageIndex)
   at Jellyfin.Api.Controllers.ImageController.GetImageResult(BaseItem item, Guid itemId, Nullable`1 index, Nullable`1 height, Nullable`1 maxHeight, Nullable`1 maxWidth, Nullable`1 quality, Nullable`1 width, Nullable`1 addPlayedIndicator, Nullable`1 percentPlayed, Nullable`1 unplayedCount, Nullable`1 blur, String backgroundColor, String foregroundLayer, ItemImageInfo imageInfo, Boolean cropWhitespace, IReadOnlyCollection`1 supportedFormats, Nullable`1 cacheDuration, IDictionary`2 headers, Boolean isHeadRequest)
   at Jellyfin.Api.Controllers.ImageController.GetImageInternal(Guid itemId, ImageType imageType, Nullable`1 imageIndex, String tag, Nullable`1 format, Nullable`1 maxWidth, Nullable`1 maxHeight, Nullable`1 percentPlayed, Nullable`1 unplayedCount, Nullable`1 width, Nullable`1 height, Nullable`1 quality, Nullable`1 cropWhitespace, Nullable`1 addPlayedIndicator, Nullable`1 blur, String backgroundColor, String foregroundLayer, BaseItem item, Boolean isHeadRequest, ItemImageInfo imageInfo)
   at Jellyfin.Api.Controllers.ImageController.GetItemImage(Guid itemId, ImageType imageType, Nullable`1 maxWidth, Nullable`1 maxHeight, Nullable`1 width, Nullable`1 height, Nullable`1 quality, String tag, Nullable`1 cropWhitespace, Nullable`1 format, Nullable`1 addPlayedIndicator, Nullable`1 percentPlayed, Nullable`1 unplayedCount, Nullable`1 blur, String backgroundColor, String foregroundLayer, Nullable`1 imageIndex)
   at lambda_method823(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(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|24_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|19_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.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Jellyfin.Server.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager)
   at Jellyfin.Server.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager)
   at Jellyfin.Server.Middleware.IpBasedAccessValidationMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager)
   at Jellyfin.Server.Middleware.LanFilteringMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   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.Server.Middleware.RobotsRedirectionMiddleware.Invoke(HttpContext httpContext)
   at Jellyfin.Server.Middleware.LegacyEmbyRouteRewriteMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.Invoke(HttpContext context)
   at Jellyfin.Server.Middleware.ResponseTimeMiddleware.Invoke(HttpContext context)
   at Jellyfin.Server.Middleware.ExceptionMiddleware.Invoke(HttpContext context)

WilcoVertegaal avatar Jan 03 '21 11:01 WilcoVertegaal

I re-installed the picons in TVHeadend, but they still do not show up. Different log file output though:

[2021-01-03 17:05:27.509 +01:00] [WRN] Slow HTTP Response from "http://192.168.0.192:8096/Items/b5e1a12fdd16f5b5559b347c4c8b7b2b/Images/Primary?maxHeight=220&tag=543b6ca4c9f21c87d81daf7a932499c0&quality=90" to "192.168.0.24" in 0:00:01.1598262 with Status Code 500
[2021-01-03 17:05:27.843 +01:00] [ERR] Error processing request. URL "GET" "/Items/874ad3677d9783f4b349c1d0ec1454c5/Images/Primary".
System.InvalidOperationException: Operation is not valid due to the current state of the object.
   at Emby.Server.Implementations.Library.LibraryManager.ConvertImageToLocal(BaseItem item, ItemImageInfo image, Int32 imageIndex)
   at Jellyfin.Api.Controllers.ImageController.GetImageResult(BaseItem item, Guid itemId, Nullable`1 index, Nullable`1 height, Nullable`1 maxHeight, Nullable`1 maxWidth, Nullable`1 quality, Nullable`1 width, Nullable`1 addPlayedIndicator, Nullable`1 percentPlayed, Nullable`1 unplayedCount, Nullable`1 blur, String backgroundColor, String foregroundLayer, ItemImageInfo imageInfo, Boolean cropWhitespace, IReadOnlyCollection`1 supportedFormats, Nullable`1 cacheDuration, IDictionary`2 headers, Boolean isHeadRequest)
   at Jellyfin.Api.Controllers.ImageController.GetImageInternal(Guid itemId, ImageType imageType, Nullable`1 imageIndex, String tag, Nullable`1 format, Nullable`1 maxWidth, Nullable`1 maxHeight, Nullable`1 percentPlayed, Nullable`1 unplayedCount, Nullable`1 width, Nullable`1 height, Nullable`1 quality, Nullable`1 cropWhitespace, Nullable`1 addPlayedIndicator, Nullable`1 blur, String backgroundColor, String foregroundLayer, BaseItem item, Boolean isHeadRequest, ItemImageInfo imageInfo)
   at Jellyfin.Api.Controllers.ImageController.GetItemImage(Guid itemId, ImageType imageType, Nullable`1 maxWidth, Nullable`1 maxHeight, Nullable`1 width, Nullable`1 height, Nullable`1 quality, String tag, Nullable`1 cropWhitespace, Nullable`1 format, Nullable`1 addPlayedIndicator, Nullable`1 percentPlayed, Nullable`1 unplayedCount, Nullable`1 blur, String backgroundColor, String foregroundLayer, Nullable`1 imageIndex)
   at lambda_method933(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(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|24_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|19_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.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Jellyfin.Server.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager)
   at Jellyfin.Server.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager)```

WilcoVertegaal avatar Jan 03 '21 16:01 WilcoVertegaal

The picons once worked. I've recently reset my database and they are not loaded again. For picons to work I needed make a wildcard user (username="*"), which has access to the web interface. This workaround doesn't seem to work anymore.

Oh, I also remember a bug that tvheadend (sometimes?) doesn't mark the images as actual images, meaning they have no file extension and also no mime type.

ggogel avatar Feb 14 '21 13:02 ggogel

I have the same problem. I use the jellyfin and also tvheadend via a docker container. Attached send in some information about the container:

IP range: 192.168.0.0/24 Jellyfin version: 10.7.6 TVHeadEnd version: 4.3-1975

For example, Jellyfin tries to open this URL to open the logo of the channel Eurosport: http://192.168.0.13:8096/Items/78c5915a076c9957967a6dfe7c6e9cea/Images/Primary?maxWidth=3840&tag=543b6ca4c9f21c87d81daf7a932499c0&quality=90

I have already created a user *, however this did not lead to success.

Under TVHeadEnd I also disabled the icon cache, this also did not lead to success.

In TVHeadEnd the icon is entered as follows: file:///picons/eurosport1.png

dontobi avatar Aug 21 '21 12:08 dontobi

Just got my tvheadend setup with Jellfin and have stumbled on to this issue as well. Icons show in Kodi and in the TVHeadEnd web gui, just not in Jellyfin.

cooljimy84 avatar Sep 02 '21 08:09 cooljimy84

May be fixed by https://github.com/jellyfin/jellyfin/pull/5996

Shadowghost avatar Sep 02 '21 22:09 Shadowghost

I'm running 10.7.6 (should contain the fix) and the issue is still there for me.

WilcoVertegaal avatar Sep 03 '21 12:09 WilcoVertegaal

10.7.6 does not contain the fix.

crobibero avatar Sep 03 '21 12:09 crobibero

I just changed my Docker container from linuxserver/jellyfin:latest (v10.7.6) to linuxserver/jellyfin:nightly (v10.8.0) and I don't see the channel logos there either. I think in this version the patch should be applied. Or not?

dontobi avatar Sep 03 '21 12:09 dontobi

The fix should be there, did you do a full live tv refresh after upgrading?

crobibero avatar Sep 03 '21 12:09 crobibero

Yes, I have performed a full Live TV refresh. Attached are a few Screenshots.

Screenshot_2021-09-03-15-08-53-482_org.jellyfin.mobile.jpg Screenshot_2021-09-03-15-09-15-602_org.jellyfin.mobile.jpg Screenshot_2021-09-03-15-09-28-796_org.jellyfin.mobile.jpg Screenshot_2021-09-03-15-11-41-855_org.jellyfin.mobile.jpg

dontobi avatar Sep 03 '21 13:09 dontobi

it might be related to https://github.com/jellyfin/jellyfin/issues/2548

crobibero avatar Sep 03 '21 13:09 crobibero

I just tested it on master. Browser console throws 500 (Internal Server Error). It seems like we still have MIME type errors according to the Jellyfin logs:

Sep 03 18:27:08 GhostBox jellyfin[21082]: [18:27:08] [ERR] Error processing request. URL GET /Items/be5d88e573f061aa8a881d2396c69e80/Images/Primary.
Sep 03 18:27:08 GhostBox jellyfin[21082]: System.Net.Http.HttpRequestException: Invalid image received.
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at MediaBrowser.Providers.Manager.ProviderManager.SaveImage(BaseItem item, String url, ImageType type, Nullable`1 imageIndex, CancellationToken cancellationToken)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Emby.Server.Implementations.Library.LibraryManager.ConvertImageToLocal(BaseItem item, ItemImageInfo image, Int32 imageIndex)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Jellyfin.Api.Controllers.ImageController.GetImageResult(BaseItem item, Guid itemId, Nullable`1 index, Nullable`1 width, Nullable`1 height, Nullable`1 maxWidth, Nullable`1 maxHeight, Nullable`1 fillWidth, Nullable`1 fillHeight, Nullable`1 quality, Nullable`1 addPlayedIndicator, Nullable`1 percentPlayed, Nullable`1 unplayedCount, Nullable`1 blur, String backgroundColor, String foregroundLayer, ItemImageInfo imageInfo, IReadOnlyCollection`1 supportedFormats, Nullable`1 cacheDuration, IDictionary`2 headers, Boolean isHeadRequest)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Jellyfin.Api.Controllers.ImageController.GetImageInternal(Guid itemId, ImageType imageType, Nullable`1 imageIndex, String tag, Nullable`1 format, Nullable`1 maxWidth, Nullable`1 maxHeight, Nullable`1 percentPlayed, Nullable`1 unplayedCount, Nullable`1 width, Nullable`1 height, Nullable`1 quality, Nullable`1 fillWidth, Nullable`1 fillHeight, Nullable`1 addPlayedIndicator, Nullable`1 blur, String backgroundColor, String foregroundLayer, BaseItem item, Boolean isHeadRequest, ItemImageInfo imageInfo)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Jellyfin.Api.Controllers.ImageController.GetItemImage(Guid itemId, ImageType imageType, Nullable`1 maxWidth, Nullable`1 maxHeight, Nullable`1 width, Nullable`1 height, Nullable`1 quality, Nullable`1 fillWidth, Nullable`1 fillHeight, String tag, Nullable`1 cropWhitespace, Nullable`1 format, Nullable`1 addPlayedIndicator, Nullable`1 percentPlayed, Nullable`1 unplayedCount, Nullable`1 blur, String backgroundColor, String foregroundLayer, Nullable`1 imageIndex)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at lambda_method693(Closure , Object )
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Jellyfin.Server.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Jellyfin.Server.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Jellyfin.Server.Middleware.IpBasedAccessValidationMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Jellyfin.Server.Middleware.LanFilteringMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Jellyfin.Server.Middleware.QueryStringDecodingMiddleware.Invoke(HttpContext httpContext)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Swashbuckle.AspNetCore.ReDoc.ReDocMiddleware.Invoke(HttpContext httpContext)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Jellyfin.Server.Middleware.RobotsRedirectionMiddleware.Invoke(HttpContext httpContext)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Jellyfin.Server.Middleware.LegacyEmbyRouteRewriteMiddleware.Invoke(HttpContext httpContext)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.Invoke(HttpContext context)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Jellyfin.Server.Middleware.ResponseTimeMiddleware.Invoke(HttpContext context)
Sep 03 18:27:08 GhostBox jellyfin[21082]:    at Jellyfin.Server.Middleware.ExceptionMiddleware.Invoke(HttpContext context)

Shadowghost avatar Sep 03 '21 16:09 Shadowghost

Like I already wrote a couple of months ago, the issue is that tvheadend doesn't respond with any MIME type. This issue already came up with emby years ago. Back then I implemented a quite hacky workaround, which tried to determine the MIME type based on the file header in cases where no type was given. It worked though. Sadly, this PR never made it in, since emby devs didn't accept any third-party PRs anymore, because of their "policy change" regarding open-source.

Anyways, I think jellyfin is expecting an image here, but is simply receiving a generic data object without MIME type, which causes the "invalid image received" exception. Secondly, the image URLs given by the tvheadend API do not contain any file ending, which also excludes this approach from determining the type.

ggogel avatar Sep 03 '21 17:09 ggogel

OK so this should really be solved in TVHeadend. If it would set a MIME type correctly then Jellyfin would show the icons correctly. Right?

Can someone point me to what call exactly is made to TVHeadend to retrieve the icons? I looked in the code briefly but it's far from clear to me. Alternatively, is there a way to show the calls to TVHeadend in the logfiles?

WilcoVertegaal avatar Sep 11 '21 09:09 WilcoVertegaal

Looking at this myself I'm seeing something different : It looks like jellyfin is querying the wrong URLs. I've created a user with no password (restricted to jellyfin's IP), and confirmed that requests from jellyfin with no authentication can complete. I've also disabled the image cache. I've also confirmed that what the json API is returning is valid. For example : "icon_public_url":"imagecache/46", and that works fine in browser.

But then for some reason jellyfin requests are not to these IDs, I can see tvheadend returning 404 errors on these : 2021-10-05 17:18:18.763 http: 172.17.0.7: HTTP/1.1 GET (1) /imagecache/26596 -- 404

No idea where that 26596 comes from, that does not appear at all in the tvheadend api's json. How do you figure out what jellyfin is storing, which of the db files keeps the image URL ?

Ulrar avatar Oct 05 '21 16:10 Ulrar

I wonder if anyone already has a solution or workaround on this problem. I came from a Plex setup where the connectivity with TvHeadend (using tvhProxy) was a nightmare! Meanwhile I found that Jellyfin with this plugin works like a charm. But the lack of channel logos remain for me unsolved what is a pity! Any help? Thanks

hsmptg avatar Apr 28 '22 08:04 hsmptg

That's subjective, I can't get mine to work without nightly freezes, and the inability to disable hardware transcoding for live tv makes a lot of the SD channel unwatchable on my instance, sadly.

But to answer the question then no, my work around before I gave up on this plugin was to manually download all the icons and add them one by one to the channels in jellyfin, tedious but works.

Ulrar avatar Apr 28 '22 08:04 Ulrar

Thank you @Ulrar for your rapid answer! But when you say "before I gave up on this plugin" you mean you also gave up of using TvHeadend with Jellyfin or you adopt another solution? I presume using back Plex is also a dead end, right?

hsmptg avatar Apr 28 '22 08:04 hsmptg

I just don't have my TV channels in Jellyfin anymore. There's some kind of issue that makes MP2 streams not transcode properly on Comet Lake CPUs, which isn't jellyfin's fault but I do wish there was a way to disable hardware transcoding for these. On top of that it would regularly freeze during the nightly guide refresh, getting stuck indefinitely around 80%. The big issue is as long as the refresh is running, the LiveTV row on the frontpage wouldn't load, which would block loading of the following rows making the UI unusable. And cancelling the refresh wouldn't work, I had to restart jellyfin almost every day to clear it.

Anyway I gave up on that plugin and I just installed Kodi on everyone's TV / Tablet / Whatever, using the jellyfin plugin for movies and shows and the tvh PVR plugin for live TV, works perfectly.

That said if it's working for you then great :). You can just take an hour and upload the icons manually and you'll be set.

Ulrar avatar Apr 28 '22 09:04 Ulrar

My current setup use TvHeadend with Kodi clients! The problem with that (and that I was trying to solve using Plex or Jellyfin) is:

  • I can not easily transcode the streams (specially if I want to do it using hardware)
  • there are no Kodi clients for IOS (unless the device is jailbroken)

But to be honest my tests with Jellyfin are very preliminary. My initial reaction was positive but I need to put the system working for a longer period to see if the freezes you describe occur. By the way in my setup I am running Jellyfin in a Docker container running inside a Proxmox VM. And my TvHeadend is streaming DVB-S2 channels from a TBS6909 card.

hsmptg avatar Apr 28 '22 09:04 hsmptg