MarcoLucidi01 / ytcast

cast YouTube videos to your smart TV from command-line
MIT License
750 stars 24 forks source link

Casting doesn't work on my TD SYSTEMS Android TV #4

Open jcromero opened 2 years ago

jcromero commented 2 years ago

Casting doesn't work on my TD SYSTEMS TV. I have YouTube app installed, but I get:

○ → ytcast -verbose -d "TD SYSTEMS Android TV" https://www.youtube.com/watch?v=dQw4w9WgXcQ
00:01:08 ytcast.go:86: ytcast v1.1.0
00:01:08 ytcast.go:205: mkdir -p /home/jcromero/.cache/ytcast
00:01:08 ytcast.go:214: loading cache /home/jcromero/.cache/ytcast/ytcast.json
00:01:08 dial.go:156: GET http://192.168.1.129:8008/apps/
00:01:08 dial.go:156: GET http://192.168.1.129:8008/apps/YouTube
00:01:08 ytcast.go:234: saving cache /home/jcromero/.cache/ytcast/ytcast.json
00:01:08 ytcast.go:89: "TD SYSTEMS Android TV": GetAppInfo: "YouTube": GET http://192.168.1.129:8008/apps/YouTube: 404 Not Found: bad HTTP response status
ytcast: "TD SYSTEMS Android TV": GetAppInfo: "YouTube": GET http://192.168.1.129:8008/apps/YouTube: 404 Not Found: bad HTTP response status
MarcoLucidi01 commented 2 years ago

thank you for reporting this!

from the log it seems that your device supports the DIAL protocol, but it's not willing to start (or even return information about) the YouTube app.

jcromero commented 2 years ago
  • if you run for example curl -X POST 'http://192.168.1.129:8008/apps/YouTube' -H 'Origin: https://www.youtube.com' does the YouTube app start on the TV?

No, it doesn't.

  • have you tried running ytcast with the YouTube on TV app already started?

Yes, I tried, but it doesn't work either.

  • are you able to cast videos from youtube.com with chrome or with the YouTube smartphone app?

Yes, I am. Using my smartphone app. It works correctly.

jcromero commented 2 years ago

If that can help:

○ → ytcast -verbose -s -t 10s
15:59:48 ytcast.go:86: ytcast v1.1.0
15:59:48 ytcast.go:205: mkdir -p /home/jcromero/.cache/ytcast
15:59:48 ytcast.go:214: loading cache /home/jcromero/.cache/ytcast/ytcast.json
15:59:48 ssdp.go:70: M-SEARCH udp 239.255.255.250:1900 ST "urn:dial-multiscreen-org:service:dial:1" MX 3 timeout 10s
15:59:48 ssdp.go:93: discovered service http://192.168.1.129:8008/ssdp/device-desc.xml
15:59:48 ssdp.go:93: discovered service http://192.168.1.129:56790/dd.xml
15:59:48 dial.go:156: GET http://192.168.1.129:8008/ssdp/device-desc.xml
15:59:48 dial.go:156: GET http://192.168.1.129:56790/dd.xml
15:59:48 dial.go:127: discovered DIAL device "Mediatek_MTXXXX"
15:59:49 dial.go:127: discovered DIAL device "TD SYSTEMS Android TV"
15:59:58 ssdp.go:85: read udp4 0.0.0.0:55701: i/o timeout
00000000 192.168.1.129   "Mediatek_MTXXXX"
e2b81b9d 192.168.1.129   "TD SYSTEMS Android TV"
15:59:58 ytcast.go:234: saving cache /home/jcromero/.cache/ytcast/ytcast.json

I don't know why ytcast find two "devices" (with the same IP, by the way). I have only one TV

MarcoLucidi01 commented 2 years ago

I don't know why ytcast find two "devices" (with the same IP, by the way). I have only one TV

it seems that your tv has 2 DIAL/UPnP servers running eheh one at port 8008 and one at port 56790.

00000000 192.168.1.129 "Mediatek_MTXXXX"

this line looks weird, the first field should be the initial part of an uuid that uniquely identifies a service and ytcast uses that as identifier for devices, but 00000000 seems to be the nil uuid, so I don't know, maybe this Mediatek_MTXXXX is a test/debug server or something. does it show up in the YouTube smartphone app? (i suppose not).

anyway, I was thinking that Android TV may be peaky about request headers and returns 404 if it doesn't like the ones sent by ytcast. my Fire TV does a similar thing, it returns 403 if I don't set Origin. at the moment ytcast sends:

Origin: https://www.youtube.com
User-Agent: Go-http-client/1.1

I wrote a fake DIAL server just to see the raw requests sent by the YouTube smartphone app and Chrome/Chromium. we can try with curl and see if this is the issue, for example Chrome sends these:

Origin: package:Google-Chrome.98.Windows
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36

Chromium sends a different Origin, but the User-Agent is the same as Chrome:

Origin: package:Chromium.98.Windows
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36

the YouTube smartphone app (on Android) sends these:

Origin: package:com.google.android.youtube
User-Agent: com.google.android.youtube/17.05.35(Linux; U; Android 11; SM-T515 Build/RP1A.200720.012) gzip

can you try with curl and see if you can get a 200 OK response? e.g.:

$ curl -i http://192.168.1.129:8008/apps/YouTube -H 'Origin: package:Google-Chrome.98.Windows' -H 'User-Agent: Mozilla/5.0 (Windows NT 10 .0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36'

if you manage to get an xml response similar to this:

HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Date: Mon, 14 Feb 2022 21:17:04 GMT
Access-Control-Allow-Origin: package:Google-Chrome.98.Windows
Vary: Origin
Connection: keep-alive
Content-Length: 198

<?xml version="1.0" encoding="UTF-8"?>
<service xmlns="urn:dial-multiscreen-org:schemas:dial" dialVer="2.2.1">
<name>YouTube</name>
<options allowStop="true"/>
<state>stopped</state>
</service>

we may have solved the issue!

jcromero commented 2 years ago

This is what I get:

○ → curl -i http://192.168.1.129:8008/apps/YouTube -H 'Origin: package:Google-Chrome.98.Windows' -H 'User-Agent: Mozilla/5.0 (Windows NT 10 .0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36'
HTTP/1.1 403 Forbidden
Access-Control-Allow-Methods:GET, POST, DELETE, OPTIONS
Access-Control-Allow-Origin:package:Google-Chrome.98.Windows
Content-Length:0

I have also tried with the Android User-Agent, but it is the same.

MarcoLucidi01 commented 2 years ago

403 Forbidden

ok, this is a tiny step forward from 404.

I have also tried with the Android User-Agent, but it is the same.

just to confirm, did you include the Android Origin header also?

this is the full Android request I was able to "intercept" on my fake server, but I doubt the headers besides Origin and User-Agent will make any difference:

GET /apps/YouTube HTTP/1.1
Host: 192.168.1.101:8080
Accept-Encoding: gzip, deflate
Connection: keep-alive
Origin: package:com.google.android.youtube
User-Agent: com.google.android.youtube/17.05.35(Linux; U; Android 11; SM-T515 Build/RP1A.200720.012) gzip

I don't know why Android TV is responding 403, I found basically no documentation on DIAL integration with Android TV and unfortunately I don't have a device to tinker with.


as workaround you may consider using the -pair option, see workarounds.

jcromero commented 2 years ago

Yes, I included the Android Origin header.

The rest of the headers doesn't make any difference, either.

Nevertheless, I have been able to pair with the -pair parameter, but it is cumbersome to launch the Youtube App prior to do the casting

randerzander commented 8 months ago

I have a similar issue on my nvidia shield. With the youtube app open, I can neither cast nor use the -pair command successfully

# list devices
./ytcast -l
da35af87 192.168.1.147   "SHIELD"                       cached

# try to cast hello world
./ytcast --verbose -d SHIELD https://www.youtube.com/watch?v=Yw6u6YkTgQ4 --verbose
10:42:55 ytcast.go:94: ytcast v1.4.0
10:42:55 ytcast.go:254: mkdir -p /home/dev/.cache/ytcast
10:42:55 ytcast.go:263: loading cache /home/dev/.cache/ytcast/ytcast.json
10:42:55 dial.go:188: GET http://192.168.1.147:8008/apps/
10:42:55 dial.go:188: GET http://192.168.1.147:8008/apps/YouTube
10:42:55 ytcast.go:283: saving cache /home/dev/.cache/ytcast/ytcast.json
10:42:55 ytcast.go:97: "SHIELD": GetAppInfo: "YouTube": GET http://192.168.1.147:8008/apps/YouTube: 404 Not Found: bad HTTP response status
ytcast: "SHIELD": GetAppInfo: "YouTube": GET http://192.168.1.147:8008/apps/YouTube: 404 Not Found: bad HTTP response status

# attempting to pair
./ytcast --pair SHIELD --verbose
10:40:19 ytcast.go:94: ytcast v1.4.0
10:40:19 ytcast.go:254: mkdir -p /home/dev/.cache/ytcast
10:40:19 ytcast.go:263: loading cache /home/dev/.cache/ytcast/ytcast.json
10:40:19 ytcast.go:319: connecting to device via YouTube Lounge and pairing code
10:40:19 remote.go:384: GET https://www.youtube.com/api/lounge/pairing/get_screen
10:40:19 ytcast.go:283: saving cache /home/dev/.cache/ytcast/ytcast.json
10:40:19 ytcast.go:97: ConnectWithCode: GET https://www.youtube.com/api/lounge/pairing/get_screen: 404 Not Found: bad HTTP response status
ytcast: ConnectWithCode: GET https://www.youtube.com/api/lounge/pairing/get_screen: 404 Not Found: bad HTTP response status
MarcoLucidi01 commented 8 months ago

hi @randerzander, unfortunately i don't have an android tv device to properly debug the DIAL problem.

as for the --pair flag, it should "just work". from the log i see that you are passing the device name, but you should instead pass the "connecting code" that the tv app generates when you navigate to the Settings > Link with TV code menu (see this).