2025-02-24, 06:34 PM
I have a 10.10.6 jellyfin instance hosted on my home server through docker-compose. It is exposed thorough NAT in my router and I've added a subdomain dns entry for it. It works as expected and I can reach it on my phone without being on my local wifi.
The docker compose uses the jellyfin/jellyfin image, but ingress is through the linuxserver/swag image, so ssl terminates in swag's reverse proxy (with a letsencrypt cert) and actual jellyfin only ever sees http traffic.
It works fine, except for trying to play videos through chromecast. I have a gen3 chromecast and I can connect to it and load the jellyfin chromecast app on it, making it display the jellyfin logo and the "ready to connect" text. But pressing play on any video gives no response. The chromecast does not react, and the jellyfin ui does not change. I've tried both on my android app or through the web-ui, and both give the same result.
An example using the web-ui:
In chrome devtools console it shows me this (<some information redacted>)
But then nothing.
The reverse proxy nginx logs say: (.203 is my laptop, .209 is the chromecast)
and then nothing.
the jellyfin server debug log does not look like it contains anything very relevant, but here it is for reference
My chromecast does show up in the menu, and i can connect to it and see the "ready to cast" message on my tv in both my phone and from a chrome browser - so i dont think this is a https, cert, or dns issue which is most of the issues that show when you google "jellyfin chromecast" because if it was, how could the jellyfin app load at all?
Things I've looked at/tried:
Now I'm looking for hints on where to find more information
Is there a log somewhere that can give me more information on what the issue is?
Is there a log in the chromecast itself that can give me more info?
Is there a way for me to spy on the traffic between the chromecast and my browser?
The docker compose uses the jellyfin/jellyfin image, but ingress is through the linuxserver/swag image, so ssl terminates in swag's reverse proxy (with a letsencrypt cert) and actual jellyfin only ever sees http traffic.
It works fine, except for trying to play videos through chromecast. I have a gen3 chromecast and I can connect to it and load the jellyfin chromecast app on it, making it display the jellyfin logo and the "ready to connect" text. But pressing play on any video gives no response. The chromecast does not react, and the jellyfin ui does not change. I've tried both on my android app or through the web-ui, and both give the same result.
An example using the web-ui:
- In chrome, i go to my server, and navigate to a movie.
- I click the "cast to device" button in the jellyfin topbar menu.
- I select my device, the chromecast shows the black screen with the ready to cast text.
- I click play. Then nothing happens.
In chrome devtools console it shows me this (<some information redacted>)
Code:
[chromecastPlayer] launching app...
chromecastPlayer-plugin.cebc42b20d4e3d95409b.chunk.js:1 [chromecastPlayer] session success: e8ea6578-bade-474a-96d4-0479119525b2
chromecastPlayer-plugin.cebc42b20d4e3d95409b.chunk.js:1 [chromecastPlayer] connect
chromecastPlayer-plugin.cebc42b20d4e3d95409b.chunk.js:1 [chromecastPlayer] message{Identify; https://<jellyfin.domain.com>:8096 -> https://<jellyfin.domain.com>:8096}
main.jellyfin.bundle.js?396e11c26ee7da0b4726:2 Active player: {"name":"Google Cast","id":"Google Cast","playerName":"Google Cast","playableMediaTypes":["Audio","Video"],"isLocalPlayer":false,"appName":"Google Cast","deviceName":null,"deviceType":"cast","supportedCommands":["VolumeUp","VolumeDown","Mute","Unmute","ToggleMute","SetVolume","SetAudioStreamIndex","SetSubtitleStreamIndex","DisplayContent","SetRepeatMode","SetShuffleQueue","EndSession","PlayMediaSource","PlayTrailers"]}
chromecastPlayer-plugin.cebc42b20d4e3d95409b.chunk.js:1 [chromecastPlayer] sessionUpdateListener: already alive
chromecastPlayer-plugin.cebc42b20d4e3d95409b.chunk.js:1 Message was sent to receiver ok.
chromecastPlayer-plugin.cebc42b20d4e3d95409b.chunk.js:1 [chromecastPlayer] volumechange
chromecastPlayer-plugin.cebc42b20d4e3d95409b.chunk.js:1 [chromecastPlayer] message{PlayNow; https://<jellyfin.domain.com>:8096 -> https://<jellyfin.domain.com>:8096}
chromecastPlayer-plugin.cebc42b20d4e3d95409b.chunk.js:1 Message was sent to receiver ok.
node_modules.jellyfin-apiclient.bundle.js?396e11c26ee7da0b4726:2 Sending web socket message: KeepAlive
node_modules.jellyfin-apiclient.bundle.js?396e11c26ee7da0b4726:2 Received KeepAlive from server.
But then nothing.
The reverse proxy nginx logs say: (.203 is my laptop, .209 is the chromecast)
Code:
10.1.1.203 - - [24/Feb/2025:17:14:55 +0100] "GET /Sessions?ControllableByUserId=73a2701772f3492ab1602dd32526ba3d HTTP/2.0" 200 5744 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
10.1.1.209 - - [24/Feb/2025:17:15:01 +0100] "OPTIONS /Sessions/Capabilities/Full HTTP/2.0" 204 0 "https://apps.jellyfin.org/" "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/Chromecast"
10.1.1.209 - - [24/Feb/2025:17:15:01 +0100] "GET /Items?maxOfficialRating=PG-13&limit=1&recursive=true&includeItemTypes=Movie&includeItemTypes=Series&imageTypes=Backdrop&sortBy=Random HTTP/2.0" 200 783 "https://apps.jellyfin.org/" "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/Chromecast"
10.1.1.209 - - [24/Feb/2025:17:15:04 +0100] "GET /Items/e69749f5a75423a6e3d6dc7f9e72fe6a HTTP/2.0" 200 5071 "https://apps.jellyfin.org/" "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/Chromecast"
10.1.1.209 - - [24/Feb/2025:17:15:31 +0100] "GET /Items?maxOfficialRating=PG-13&limit=1&recursive=true&includeItemTypes=Movie&includeItemTypes=Series&imageTypes=Backdrop&sortBy=Random HTTP/2.0" 200 813 "https://apps.jellyfin.org/" "Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/Chromecast"
and then nothing.
the jellyfin server debug log does not look like it contains anything very relevant, but here it is for reference
Code:
[2025-02-24 16:14:55.415 +00:00] [DBG] [47] Jellyfin.Api.Auth.CustomAuthenticationHandler: AuthenticationScheme: "CustomAuthentication" was successfully authenticated.
[2025-02-24 16:14:55.415 +00:00] [DBG] [47] Jellyfin.Api.Auth.CustomAuthenticationHandler: AuthenticationScheme: "CustomAuthentication" was successfully authenticated.
[2025-02-24 16:14:55.982 +00:00] [DBG] [46] Emby.Server.Implementations.Session.SessionWebSocketListener: Watching 1 WebSockets.
[2025-02-24 16:15:01.435 +00:00] [DBG] [47] Jellyfin.Api.Auth.CustomAuthenticationHandler: AuthenticationScheme: "CustomAuthentication" was successfully authenticated.
[2025-02-24 16:15:01.435 +00:00] [DBG] [47] Jellyfin.Api.Auth.CustomAuthenticationHandler: AuthenticationScheme: "CustomAuthentication" was successfully authenticated.
[2025-02-24 16:15:01.488 +00:00] [DBG] [47] Emby.Server.Implementations.Data.SqliteItemRepository: "GetItemList" query time (slow): 51.246ms. Query: "select type,data,EndDate,ChannelId,CommunityRating,CustomRating,IndexNumber,IsLocked,PreferredMetadataLanguage,PreferredMetadataCountryCode,Width,Height,DateLastRefreshed,Name,Path,PremiereDate,Overview,ParentIndexNumber,ProductionYear,OfficialRating,ForcedSortName,RunTimeTicks,Size,DateCreated,DateModified,guid,Genres,ParentId,Audio,IsInMixedFolder,DateLastSaved,LockedFields,Studios,Tags,OriginalTitle,PrimaryVersionId,DateLastMediaAdded,Album,LUFS,NormalizationGain,CriticRating,IsVirtualItem,SeriesName,PresentationUniqueKey,InheritedParentalRatingValue,ExternalSeriesId,Tagline,ProviderIds,Images,ProductionLocations,ExtraIds,TotalBitrate,ExtraType,ExternalId,SeriesPresentationUniqueKey,OwnerId from TypedBaseItems A where type=@type AND Guid in (select itemId from AncestorIds where AncestorId=@AncestorId)"
[2025-02-24 16:15:01.510 +00:00] [DBG] [47] Emby.Server.Implementations.Data.SqliteItemRepository: "GetItems.ItemQuery" query time (slow): 20.3222ms. Query: "select type,data,EndDate,ChannelId,CommunityRating,IndexNumber,Width,Height,Name,Path,PremiereDate,ParentIndexNumber,ProductionYear,OfficialRating,RunTimeTicks,Size,DateModified,guid,ParentId,Audio,IsInMixedFolder,PrimaryVersionId,Album,LUFS,NormalizationGain,CriticRating,IsVirtualItem,SeriesName,ProviderIds,Images,TotalBitrate,ExtraType,ExternalId,OwnerId from TypedBaseItems A where type in ('MediaBrowser.Controller.Entities.Movies.Movie','MediaBrowser.Controller.Entities.TV.Series') AND Images like '%Backdrop%' AND (InheritedParentalRatingValue is null OR InheritedParentalRatingValue <= @MaxParentalRating) AND TopParentId in ('8679d10569ec12981200c4116da3e90b','ba9c5cad4ccd875366bf54fd50e04928','2d551e01c982022aa11808f729195ebd','061aa138ec032f6a317b1d1aeda2167c','29077c2c552360b36edf0bcd24952b07','5fea1f72ae5d80bfbb3836e5f778a071') Group by PresentationUniqueKey ORDER BY RANDOM() ASC LIMIT 1"
[2025-02-24 16:15:04.781 +00:00] [DBG] [47] Jellyfin.Api.Auth.CustomAuthenticationHandler: AuthenticationScheme: "CustomAuthentication" was successfully authenticated.
[2025-02-24 16:15:04.781 +00:00] [DBG] [47] Jellyfin.Api.Auth.CustomAuthenticationHandler: AuthenticationScheme: "CustomAuthentication" was successfully authenticated.
[2025-02-24 16:15:07.984 +00:00] [DBG] [47] Emby.Server.Implementations.Session.SessionWebSocketListener: Watching 1 WebSockets.
[2025-02-24 16:15:13.992 +00:00] [DBG] [49] Emby.Server.Implementations.HttpServer.WebSocketConnection: WS "172.20.0.2" received message: InboundWebSocketMessage`1 { Data: null, MessageType: KeepAlive, ServerId: null }
[2025-02-24 16:15:16.530 +00:00] [DBG] [49] Jellyfin.Api.Auth.CustomAuthenticationHandler: AuthenticationScheme: "CustomAuthentication" was not authenticated.
[2025-02-24 16:15:19.983 +00:00] [DBG] [47] Emby.Server.Implementations.Session.SessionWebSocketListener: Watching 1 WebSockets.
[2025-02-24 16:15:31.315 +00:00] [DBG] [3] Jellyfin.Api.Auth.CustomAuthenticationHandler: AuthenticationScheme: "CustomAuthentication" was successfully authenticated.
[2025-02-24 16:15:31.315 +00:00] [DBG] [3] Jellyfin.Api.Auth.CustomAuthenticationHandler: AuthenticationScheme: "CustomAuthentication" was successfully authenticated.
[2025-02-24 16:15:31.316 +00:00] [DBG] [3] MediaBrowser.Controller.Entities.BaseItem: "Movies" has no parental rating set.
[2025-02-24 16:15:31.357 +00:00] [DBG] [3] Emby.Server.Implementations.Data.SqliteItemRepository: "GetItemList" query time (slow): 40.8597ms. Query: "select type,data,EndDate,ChannelId,CommunityRating,CustomRating,IndexNumber,IsLocked,PreferredMetadataLanguage,PreferredMetadataCountryCode,Width,Height,DateLastRefreshed,Name,Path,PremiereDate,Overview,ParentIndexNumber,ProductionYear,OfficialRating,ForcedSortName,RunTimeTicks,Size,DateCreated,DateModified,guid,Genres,ParentId,Audio,IsInMixedFolder,DateLastSaved,LockedFields,Studios,Tags,OriginalTitle,PrimaryVersionId,DateLastMediaAdded,Album,LUFS,NormalizationGain,CriticRating,IsVirtualItem,SeriesName,PresentationUniqueKey,InheritedParentalRatingValue,ExternalSeriesId,Tagline,ProviderIds,Images,ProductionLocations,ExtraIds,TotalBitrate,ExtraType,ExternalId,SeriesPresentationUniqueKey,OwnerId from TypedBaseItems A where type=@type AND Guid in (select itemId from AncestorIds where AncestorId=@AncestorId)"
[2025-02-24 16:15:31.368 +00:00] [DBG] [3] Emby.Server.Implementations.Data.SqliteItemRepository: "GetItems.ItemQuery" query time (slow): 10.3443ms. Query: "select type,data,EndDate,ChannelId,CommunityRating,IndexNumber,Width,Height,Name,Path,PremiereDate,ParentIndexNumber,ProductionYear,OfficialRating,RunTimeTicks,Size,DateModified,guid,ParentId,Audio,IsInMixedFolder,PrimaryVersionId,Album,LUFS,NormalizationGain,CriticRating,IsVirtualItem,SeriesName,ProviderIds,Images,TotalBitrate,ExtraType,ExternalId,OwnerId from TypedBaseItems A where type in ('MediaBrowser.Controller.Entities.Movies.Movie','MediaBrowser.Controller.Entities.TV.Series') AND Images like '%Backdrop%' AND (InheritedParentalRatingValue is null OR InheritedParentalRatingValue <= @MaxParentalRating) AND TopParentId in ('8679d10569ec12981200c4116da3e90b','ba9c5cad4ccd875366bf54fd50e04928','2d551e01c982022aa11808f729195ebd','061aa138ec032f6a317b1d1aeda2167c','29077c2c552360b36edf0bcd24952b07','5fea1f72ae5d80bfbb3836e5f778a071') Group by PresentationUniqueKey ORDER BY RANDOM() ASC LIMIT 1"
[2025-02-24 16:15:31.981 +00:00] [DBG] [47] Emby.Server.Implementations.Session.SessionWebSocketListener: Watching 1 WebSockets.
[2025-02-24 16:15:43.980 +00:00] [DBG] [47] Emby.Server.Implementations.Session.SessionWebSocketListener: Watching 1 WebSockets.
[2025-02-24 16:15:43.994 +00:00] [DBG] [3] Emby.Server.Implementations.HttpServer.WebSocketConnection: WS "172.20.0.2" received message: InboundWebSocketMessage`1 { Data: null, MessageType: KeepAlive, ServerId: null }
[2025-02-24 16:15:46.620 +00:00] [DBG] [3] Jellyfin.Api.Auth.CustomAuthenticationHandler: AuthenticationScheme: "CustomAuthentication" was not authenticated.
[2025-02-24 16:15:55.983 +00:00] [DBG] [47] Emby.Server.Implementations.Session.SessionWebSocketListener: Watching 1 WebSockets.
My chromecast does show up in the menu, and i can connect to it and see the "ready to cast" message on my tv in both my phone and from a chrome browser - so i dont think this is a https, cert, or dns issue which is most of the issues that show when you google "jellyfin chromecast" because if it was, how could the jellyfin app load at all?
Things I've looked at/tried:
- changing from stable to unstable cast version and back again
- limiting Google Cast Streaming Quality and Maximum Allowed Video Transcoding Resolution to 1.5 Mbps and 360p
- https://casttool.appspot.com/cactool/ I tried entering a receiver app id i found by spying on the post request from changing cast version in settings. It also causes a "ready to cast" screen but anything else i try to do just gives me an APP_ERROR response.
- wireshark with an sslkeylogfile to look at traffic between chrome and the chromecast - but i dont think chrome includes the chromecast tls stuff in the keylogfile because wireshark decrypts the other traffic but not the chromecast traffic.
- i can screen cast and cast a single chrome tab, so the chromecast and laptop combo work fine when no jellyfin is involved.
Now I'm looking for hints on where to find more information
Is there a log somewhere that can give me more information on what the issue is?
Is there a log in the chromecast itself that can give me more info?
Is there a way for me to spy on the traffic between the chromecast and my browser?