jellyfin / jellyfin

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

Chromecast not working #1396

Closed brianjmurrell closed 3 years ago

brianjmurrell commented 5 years ago

Describe the bug Trying to play to Chromecast from Android results in nothing actually happening.

To Reproduce

  1. Click Chromecast icon, choose a Chromecast to cast to
  2. Click on media file

Expected behaviour Should play the media to the Chromecast. It doesn't. The mobile app screen doesn't change when play icon is pressed other than a translucent blue circle drawn around the play icon.

Logs There are none. There is nothing added to the log when the media item's play icon is pressed.

System (please complete the following information):

brianjmurrell commented 5 years ago

On Chrome on Linux, the Chromecast button doesn't even see my Chromecasts. I am able to cast any arbitrary tab in Chrome and Netflix in the same Chrome is able to see my Chromecasts, so this seems to be another bug of the Jellyfin Chromecast.

anthonylavado commented 5 years ago

@brianjmurrell Chrome on a desktop will not allow a page to cast unless it is secured (HTTPS/SSL). Netflix does have SSL, so that works. Tab casting also works, because it’s not the website, but the application.

Do you have HTTPS set up for Jellyfin?

anthonylavado commented 5 years ago

I should note - the App should work whether or not you have HTTPS, I’m just trying to determine if there is an actual web/server error, or if this issue belongs with the Android app.

brianjmurrell commented 5 years ago

@brianjmurrell Chrome on a desktop will not allow a page to cast unless it is secured (HTTPS/SSL).

Ooops. Yes. I was not on the HTTPS port. Using the HTTPS port from my Linux/Chrome I see the same "nothing happens when you try to play to Chromecast" behaviour. It's as if I just didn't even click the Play icon.

brianjmurrell commented 5 years ago

To be clear, I am not using any dedicated Android app but just using the web-app in a Chrome tab. TBH, I don't really see the point of a dedicated app when the web-app works just as well and (almost?) identically to a dedicated app.

anthonylavado commented 5 years ago

TBH, I don't really see the point of a dedicated app when the web-app works just as well and (almost?) identically to a dedicated app.

There is working going on now to add better video players to the Android app, so soon it will be able to handle more formats than just the web app alone can. More format support means less transcoding, means easier experience :-)

...Using the HTTPS port from my Linux/Chrome I see the same "nothing happens when you try to play to Chromecast" behaviour. It's as if I just didn't even click the Play icon.

Try having the DevTools open during this, and see if there are any errors that appear in the console. That should give us a start to help track it down :-)

brianjmurrell commented 5 years ago

Nothing new appears in either the Network tab nor the Console tab when I press Play. If I don't have Chromecast enabled, it plays in the browser fine.

anthonylavado commented 5 years ago

Hrm... Try this in order:

You should see the following messages after everything loads up on screen:

Screen Shot 2019-05-21 at 11 16 35 PM
bensweet86 commented 5 years ago

I've been playing around with this too - same issue with http/https initially. I run a reverse proxy for https and if the ssl certificate was missing / invalid the web ui would connect to the chromecast but refused to cast with random or no messages. As soon as there was a valid SSL certificate casting worked fine.

brianjmurrell commented 5 years ago

@anthonylavado So, doing as you requested, I do see the lines you refer to. I then go on to play a media file and this is added to the messages:

image

But nothing correspondingly is added to the jellyfin log to indicate that it's gotten the request or is fulfilling it.

anthonylavado commented 5 years ago

Okay, so the other lines are mainly when the user clicks away, and then back on the web app, so those are normal.

So it’s definitely seeing the Chromecast is available...

I don’t think we covered this earlier, but does the Chromecast show the Jellyfin “Ready to cast” page when you connect to it?

brianjmurrell commented 5 years ago

does the Chromecast show the Jellyfin “Ready to cast” page when you connect to it?

Yes, and a clock on the top right at some point, while on the Jellyfin "Ready to cast" page.

maxaudron commented 5 years ago

im seing the same happening for me. Both webapp and android app connect to the chromecast and it shows the jellyfin page but im then not able to play anything. the jellyfin server is secured by https.

anthonylavado commented 5 years ago

Sorry folks, I have no idea where to proceed further from here. Paging @jellyfin/support for any ideas.

maxaudron commented 5 years ago

For me it was not automaticly detecting the correct WAN IP by itself as it is behind a reverse proxy. After setting them myself in the advanced settings it now works.

sparky8251 commented 5 years ago

Does the solution maxaudron found work for you @brianjmurrell ? This is a bizarre issue and one we are having trouble finding solid info on.

brianjmurrell commented 5 years ago

My Jellyfin is not behind a reverse proxy and I am accessing it from the local network it's on. Is the WAN address even relevant here?

In the dashboard it has http://_my_domain_:8096 for the WAN address. _mydomain does not resolve to an IP address.

sparky8251 commented 5 years ago

It's possible that could be breaking it. Incorrect WAN detection broke the Kodi addon before. It shouldn't care about the WAN IP but it did...

Make sure its resolvable, even if only internally (like set it to a local IP address) and see if it helps. If it is WAN detection, that means we have 2 clients we need to fix to rip that section out of the web ui like we've been meaning to.

brianjmurrell commented 5 years ago

Where is it getting that value (of the WAN address) from? Why is it using my domain and the LAN address is using an IP address?

What if I don't want to have my domain resolve to an IP address to force clients to use host+domain name nomenclature?

sparky8251 commented 5 years ago

As far as I know, there should never be a domain name in that field. I didn't even know it was possible.

It gets the value in that field from ipv4.icanhazip.com, and that should only return IPs. That said, I think maxaudron found some way to set it manually based on his comments here. Worst case, you might be able to set it by hand in one of the xml files JF uses to store conf data. Just try to avoid loading pages in the web UI, I think every page loaded writes a new value to that file... You can check by curling the /emby/system/info/public API I believe. That returns the current set value.

Frankly, this is just troubleshooting/working around an issue for now. the end result should be a proper client that doesn't need to know what the WAN address is, IP, domain, or other. Just want to see if we can track down the cause of your suffering specifically, then we can work on fixing it right.

flatline-studios commented 5 years ago

I'm facing this exact issue.

Using the Android app, just a blue highlight colour on the button, and nothing else happens.

I'm not using SSL on the server or a reverse-proxy, and am just using the linuxserver.io docker image.

My actual, internal IP address (shown with ip a) is 192.168.0.34.

Jellyfin shows: My LAN address is 172.19.x.x : 8096 - Which is the docker containers IP address I believe. My WAN address is < SNIP > : 8096 - Which is correct (but I'm not sharing my server with the internet, it's only local)

Looking at the logs, when I push the play button after connecting to my Chromecast, it says:

`[2019-06-27 17:39:18.403 +01:00] [INF] Profile: "Unknown Profile", Path: "/data/tvshows/< SNIP >.mkv", isEligibleForDirectPlay: True, isEligibleForDirectStream: True

And nothing else... Not sure if it's relevant or not... Just seemed weird it say's Unknown Profile.

maxaudron commented 5 years ago

you can set the wan ip in the advanced settings page.

brianjmurrell commented 5 years ago

@maxaudron Where? I don't see anywhere on the Advanced page to set the WAN IP.

flatline-studios commented 5 years ago

Nope, can't see it there.

http://prntscr.com/o7vcz0

Is what shows.... Which one are you suggesting should be updated?

EDIT: Looking at the Emby/MediaBrowser github wiki:

https://github.com/MediaBrowser/Wiki/wiki/Hosting-Settings

It looks like there is a section to enter a WAN address, but in my version of Jellyfin - 10.3.5 - the options are pretty different.

maxaudron commented 5 years ago

A bit lower the Public ip ports and the external domain in a sense sets the WAN IP.
These options could probably be named a bit more consistent and clearly.

Screenshot from 2019-06-28 19-19-48

brianjmurrell commented 5 years ago

External domain? That is nowhere near intuitive. That field reads like it is to match the name of the site with an SSL certificate so if you were to put an IP address in there you'd expect to get SSL errors.

flatline-studios commented 5 years ago

Mine doesn't have that there... The screenshot I posted is all the options available under Advanced -> Hosting.

flatline-studios commented 5 years ago

I'm assuming my issue stems from the LAN address being the docker containers IP address, as opposed to the machines IP address, so it's on a different subnet and is therefore unresolvable from my phone.

I'll try switching the container to a host based network (which isn't a permanent or ideal solution), and see if it works... If it does, it'll probably be ideal if the "LAN address" displayed on the administration dashboard could be editable. I took a quick look at the source, but couldn't find a suitable place to insert the IP address, however, I'm not at all familiar with the code base, and there's a lot of it!

SenorSmartyPants commented 5 years ago

I'm having the same issues with an almost identical setup as flatline-studios.

I'm running the JF official docker images. Using host networking already. Local IP shows docker network IP 172,18.0.1 . JF is not accessible from the internet.

JF Android can see my chromecast, and I can get the CC app displaying on the TV. But nothing plays.

maxaudron commented 5 years ago

Docker host networking should not be needed. A simple port bind is enough. AFAIK whatever "Local IP" is reported anywhere does not matter for apps like chromecast etc.

It simply is the IP jellyfin is bound to. Which in docker means the containers IP.

Chromecast's and the like query jellyfin for it's address and will always use the WAN Address as reported by jellyfin and visible in the dashboard.
So to get these to work in a docker context where due to host binding, reverse proxies or whatever it can't query the correct IP, set it to whatever IP jellyfin is reachable at.

For a purely local setup this means the Local IP of the physical host jellyfin is bound to.
If jellyfin is reachable from external address of course set it to that.

Whatever this is an IP or a domain does only matter if you use SSL as there it needs the domain to validate the certificate.

@SenorSmartyPants @flatline-studios please try this and report back

brianjmurrell commented 5 years ago

This has nothing to do with docker networking. I have this issue and run jellyfin on the host O/S. No docker involved in any way, shape or form.

maxaudron commented 5 years ago

I just used docker as an example. The WAN IP could be set wrong for a myriad of reasons. Be it docker, the world ending or god himself.
Point is: does the WAN IP in the dashboard report something that is reachable? Good. If not set it to something reachable.

SenorSmartyPants commented 5 years ago

@maxaudron I set my "external domain" to my LAN IP for JF. Chromecast now connects and plays.

flatline-studios commented 5 years ago

@SenorSmartyPants - OMG! That solved it!

Something for the todo list maybe:

Even better would be if a watchdog service can check to see if the currently listed WAN address is accessible, and if it's not (as was my issue), then display a warning label with some more info.

brianjmurrell commented 5 years ago

does the WAN IP in the dashboard

What WAN IP? There is no WAN IP address field in my settings. All I have is External domain (a domain is NOT an IP address!) which the help text indicates has to do with SSL certificates and connecting remotely.

But in fact my Jellyfin server has no WAN IP. It's not accessible remotely (whatever that ambiguous term is supposed to mean) or connected, forwarded, tunnelled or otherwise exposed to any WAN in any way and is available solely in the LAN, albeit on an SSL port with an SSL certificate to keep Chromecast happy with the SSL certificate using my External domain name.

So frankly, I don't want any sort of WAN IP address in that field.

How exactly is this related to Chromecasting? Doesn't the chromecast jellyfin app loaded on the chromecast take care of figuring out everything it needs to figure out on it's own without me having to put things into Jellyfin that really shouldn't be there? I don't have to do this for Netflix.

And what happens if one's WAN IP address changes frequently? Is one supposed to go update Jellyfin every time that happens?

EraYaN commented 5 years ago

Netflix is hosted online (and thus has IPs routable on the public internet) and are you telling me that you see these two things as one and the same? And you want to achieve the same without a publicly routable IPv4 address on your Jellyfin instance? Since well there is a contradiction on there somewhere. Chromecast just really wants a publicly hosted everything, add to that a bunch of arcane javascript magic, well it stops working.

And on the dashboard (That is the first page that openes when you click Server Dashboard) it will list your WAN ip (or at least the IP the reflection service that is used responds with). It's not a setting.

flatline-studios commented 5 years ago

External Domain = WAN Address --- This should be written in gigantic letters somewhere. Even under the "Help" button next to it, there's no mention on how to change it.

Change one, and it's reflected in the other... The issue arises from Chromecast being a rubbish device I guess. Wish I never bought it all those years ago... @EraYaN 's point (Chromecast just really wants a publicly hosted everything) is proven even more by the fact that if you connect it to a router that doesn't have internet access, the Chromecast simply won't work, for anything, even local streaming.

I agree that some of the naming and descriptions seem to be a bit off, but that's not really true. It's Chromecast's fault for being awkward. It's looking for a WAN address on the network (be it actually private or public), and unless it's given correctly (as the WAN address / External Domain), then it's not going to connect to the socket correctly.

cvium commented 5 years ago

Just to clear up any misconceptions, the server address used by the Chromecast for Jellyfin is decided by the following function https://github.com/jellyfin/jellyfin-web/blob/master/src/components/chromecast/chromecasthelpers.js#L174-L203. It has nothing to do with CC itself.

The Chromecast is a dumb device with limited memory, that fetches its app list from the internet, where the url for any app is whatever the publisher (in this case the Jellyfin org) put into Google Cast SDK Developer Console. That also means it requires an internet connection. I'm unsure whether it still requires internet connection after the initial setup.

As an example, Emby's app is hosted http://mediabrowser.github.io/Emby.Chromecast/

brianjmurrell commented 5 years ago

So, if External domain really is supposed to be the WAN IP, am I expected to notice and update that field every time my ISP changes my IP address?

And what if I actually don't to Allow remote connections to [my] Jellyfin Server? It seems I need to enable this even when I don't want to just to have working Chromecast?

oddstr13 commented 5 years ago

So, if External domain really is supposed to be the WAN IP, am I expected to notice and update that field every time my ISP changes my IP address?

No. The intended use is to set up Dynamic DNS, and to provide a SSL certificate that is valid for this domain name. image

I do not have a Chromecast, so I don't know how it interacts with self-signed certificates. Browsers tend to throw a ugly warning for self-signed certificates, but this is only a security issue if you don't expect it.

And what if I actually don't to Allow remote connections to [my] Jellyfin Server? It seems I need to enable this even when I don't want to just to have working Chromecast?

Disable UPnP port forwarding, and don't forward the port. You can set up DNS records only visible on your LAN. You may be able to do this in your router directly, depending on software support. In OpenWRT's LuCi, you can find this under Network -> Hostnames. image

Then set up a self-signed certificate for this domain and install it in Jellyfin. image If Chromecast works with self-signed certificates, you should now be good to go.

If Chromecast does NOT work with self-signed certificates, you can set up a Let's Encrypt certificate and use Split-horizon DNS to have a proper domain name resolve to your connection, while it points to the Jellyfin server locally. Then have Certbot handle the http connection from the internet to be able to set up certificates, and use those generated certificates locally with Jellyfin. I won't go into detail of how to set this up, as it is a little involved. But once set up properly, with automatic renewals, it should just work from there on out.

Mountaineer1024 commented 5 years ago

You can set up DNS records only visible on your LAN.

Actually chromecasts do not respect your internal DNS offered by DHCP, they only use 8.8.8.8 (Googles DNS).

Even if you've got internet access, if you block 8.8.8.8, your chromecast won't function.

I've setup jellyfin on my server using a letsencrypt cert which works perfectly for external chromecasts, but not for the chromecast on my lan, I assume because jellyfin server is saying "oh, this is on the LAN, send the chromecast instructions to use 10.0.0.3 not jellyfin.myexternaldomain.com" and my chromecast just sits there with the jellyfin logo onscreen.

anthonylavado commented 5 years ago

Some more reference here, posting for posterity: https://emby.media/community/index.php?/topic/56771-chromecast-address/page-1

Mountaineer1024 commented 5 years ago

I've just realised I was hitting bug #1148, because I disabled hardware acceleration and media is now playing on my chromecast.

I don't understand how this was working for external chromecasts but not my lan one, but I do not believe I have changed anything else settings wise.

bengalih commented 5 years ago

TL;DR - Moving from Plex to JF due to Plex issues, but found it difficult to use Chromecast with Emby. Even working through the issues, found that Chromecast won't work at all with SSL enabled on JF.

Skip to "ISSUES" below if you don't want the background.

I just wanted to chime in with my experience setting up and tinkering with JF for the past couple days. I have been all around the forums and bug reports and this bug seems most germane to post my experiences in. Let me preface this by saying this isn't a condemnation of JF or any of the development decisions made thus far, although I do disagree a bit with some of the statements made within this thread. As will be seen I have kind of a perfect storm of limitations that is preventing JF from functioning optimally for me, but I don't think I am alone here. I am hoping an explanation of my woes (and my current solutions) will both help others who visit this thread as well as give the developers additional motivation for perhaps providing more flexibility in the future.

Quick background on my setup: I was (am) a Plex user (on Windows Server), casting video to Roku devices and audio (and video audio streams) to Google Mini (Nest) devices. Things were working pretty optimally until Google decided to start pushing out beta ("preview") firmware to customers that were not even enrolled in the Preview Program. This firmware broke my Google Minis (first 2 and then 3 of them). I am not alone in this, and Plex has been slow to respond to fixing this issue. For anyone interested, the thread on that is here. In any event, I basically couldn't use Plex at all with my Google devices, so I came to JF looking for a temporary solution as well as to try it out for a possible long term switch.

I'm pleased to say that I do have some of my cast functionality back, but it hasn't been intuitive and is a bit cumbersome to work with. Additionally, I don't believe I can get all the functionality I want without installing some additional services (more on that below).

ISSUES: I encountered many of the issues discussed in this bug report, so let me detail how my path has unfolded.

1) Set up JF and was able to see and chromecast to my Google Devices. However I realized that I was only able to do this when accessing http://localhost:8096 on the system JF was on and on one Android Phone running Chrome 61.0.3163.98. It would not function on my Android devices or PCs running Chrome 76.0.3809.132.

2) Research showed that the reason for this was a change to Chrome (somewhere between 72 and 73 I think?) that would not allow Chromecasting from non-secure (SSL) sites.

3) No big deal - I would go ahead and enable SSL on my JF install. I was able to reuse the self-signed cert I created for Plex and so this only took a couple of minutes. After doing this I was able to see the Chromecast option from all my browsers. I thought I had solved the issues.

4) Realized later in the day when I actually tried to cast that casting was not working at all. Additional research has shown that apparently Google devices will refuse to accept an SSL connection that is using a self-signed certificate. This basically is a catch-22 situation when using Chrome to cast to Google devices, as you need to secure the site for Chrome to cast, but the Google device won't accept the cast if it is secured with a self-signed. (Point of interest: The Google Devices don't require the site casting to be SSL - that is a Chrome requirement. But, if they are SSL it must not be self-signed). Specifically, what happens when you try to cast is absolutely nothing. It is as if you click on the play button and nothing happens. In some cases I would also get an pop-up error from JF saying MessageChromecastConnectionError.

5) Unfortunately, I am unable to apply a 3rd party certificate to my site. This is where my specific situation comes into play. I cannot use Let's Encrypt because my ISP (Cox Communications) blocks incoming port 80 and thus I am unable to apply for a certificate. While I have a registered domain name (mydomain.com) I use my DNS provider to redirect requests for hosts on that domain to a dynamic DNS service (mydomain.ddns.net:PORT). This way I am able to easily access my services by using something like "http://jellyfin.mydomain.com" and have those DNS URL redirected to "https://mydomain.ddns.net:8920". Because I am forced to use DDNS (no static IP available), I am unable to purchase a 3rd party certificate from any of the leading cert authorities as they will not issue to the ddns hosts. I or course also cannot use the DNS option of Let's Encrypt since I don't manage that DNS.

6) This means that the only way I am able to Chromecast via Chrome is by accessing the http://localhost:8096 address. This is only because Chrome has a built-in exception for localhost and doesn't really have to do with anything else involving the infrastructure of the setup.

ADDITIONAL SOLUTIONS This is to describe some other ways to make casting available for others experiencing this issue. For me it is cumbersome to remote into my JF server only to open Chrome as localhost to cast. I would much rather do this from my laptop browser or from my Android phone.

netsh interface portproxy add v4tov4 listenport=8096 listenaddress=127.0.0.1 connectport=8096 connectaddress=10.10.10.102

You can view and delete setup forwards like this:

netsh interface portproxy show all
netsh interface portproxy delete v4tov4 listenport=8096 listenaddress=127.0.0.1

With the above I am able to use Chrome on a remote windows PC and "trick" Chrome into believing it is accessing localhost and thus bypass the non-secure cast subscriptions.

I used a similar idea with SSH tunnels on my phone back through my router to the local server before I realized the JF Android app would work. Technically you could do the same on a PC using ssh/Putty tunnels though I believe the netsh commands are less cumbersome as it keeps all the port forwards local and direct.

At this point I am able to cast to my local Google Devices from all of my phone/PC interfaces. However I have found that in order for this to work I cannot have SSL enabled at all on my JF server. This means that if I have the "Secure connection mode" set to anything but "Disabled", casting refuses to work. Specifically I can still the option to Chromecast, but the server won't do anything when I try (as described above). This is true even when I am accessing the JF server over it's non-secure connection.

This removes all possible remote functionality for me, as it would not be recommended to access the server via forwards over http only. I wanted to provide access to my server remotely to allow some family members the "download" option, but now I have found that even having SSL enabled totally breaks my local casting even when using http locally. I believe this is a separate bug and I plan to file it immediately after this one. Will reference when done. ADDED here

Hope some of my experience at least helps others in a similar predicament understand the limitations. If I've got something wrong or the dev team has anything to add, I would definitely appreciate it!.

EraYaN commented 5 years ago

You should be able to setup a reverse proxy so you own domain directly accesses your Jellyfin instance (so no redirect), this would allow you to get a DNS LE certificate. And you can also let Jellyfin be without SSL.

bengalih commented 5 years ago

You should be able to setup a reverse proxy so you own domain directly accesses your Jellyfin instance (so no redirect), this would allow you to get a DNS LE certificate. And you can also let Jellyfin be without SSL.

I realize my post was a bit lengthy, but perhaps you missed some of what I wrote? :)

1) My ISP blocks port 80 so I don't see how it is at all possible for me to obtain an LE certificate. If I am wrong here let me know but everything I have seen about their process requires me being able to accept their verification over port 80.

2) I don't see how running a reverse proxy would allow my own domain to directly access jellyfin. The issue is still that of DNS (i.e. being able to locate my IP address) and that happens externally to my whole configuration. Again, perhaps you can explain why you think this would solve any issue?

cvium commented 5 years ago

Dynu supports TXT records https://community.letsencrypt.org/t/failed-authorization-procedure-the-server-could-not-connect-to-the-client-to-verify-the-domain/60656/4

If you have a proper domain, the procedure is the same more or less.

anthonylavado commented 5 years ago

@bengalih Specifically they mean the domain you mention here:

I have a registered domain name (mydomain.com) I use my DNS provider to redirect requests for hosts on that domain to a dynamic DNS service...

Another DDNS provider that could be used the same way is DuckDNS. It’s very widely used by many people with Home Assistant for the same reason.

cvium commented 5 years ago

Most domain providers also support ddns, so the redirect isn't necessary.

bengalih commented 5 years ago

Most domain providers also support ddns, so the redirect isn't necessary.

So I think you just made my life a lot easier! I use NameCheap and I never realized before I could do DDNS with them. I have gone ahead and registered myhost.mydomain.com as a dynamic host with them. I am still using URL redirects within Namecheap, but now instead of:

jellyfin.mydomain.com --> mydomain.ddns.net:1111 I simply do: jellyfin.mydomain.com --> server.mydomain.com:1111

I believe I can now do the following:

1) Since I now use solely mydomain.com and have control of my DNS via Namecheap, I should have no issue getting a LE cert using the DNS option, right?

2) If I setup a reverse proxy (considering nginx running on my asuswrt-merlin as I am a Windows user and don't want to setup another linux box). I should also be able to accept all requests over a single port and have nginx direct appropriately? So for instance:

https://jellyfin.mydomain.com > goes to NGINX server over port 443, which translates it internally to > 192.168.100.100:8096

whereas a different hostname can be mapped differently via nginx like:

https://myservice.mydomain.com > goes to NGINX server over port 443, which translates it internally to > 192.168.100.100:9001

Is this how the reverse proxy usually identifies, based on incoming hostname?

I am wondering though, once the reverse proxy is configured for external SSL, it appears in JF I set the secured options to "secured by reverse proxy." Doing this appears to only advertise a WAN address on the Dashboard page. I would like to know internally within JF how are requests handled differently both on the WAN/LAN then simply setting the secured options to disabled.