Open iBicha opened 5 months ago
One last thing I want to mention, is that Roku platform is pretty limited, and that's why I've gone through this route. I haven't worked on Android TV, but there might be better ways to do things.
I'm glad that I have helped. Interesting info, friend. Thanks for sharing.
Regards, Yuriy
On Sat, Feb 10, 2024, 18:45 Brahim Hadriche @.***> wrote:
Hey! I'm the author of Playlet https://github.com/iBicha/playlet, a YouTube app for Roku TV.
I recently embarked on the journey to support casting from the YouTube app using lounge.
Some projects, like https://github.com/henriquekano/youtube-lounge-api, https://github.com/yuliskov/MediaServiceCore, and (especially) https://github.com/patrickkfkan/yt-cast-receiver helped me understand the protocol better, so I wanted to say thanks, and also share a bit of my findings in case it is useful.
As I tried to understand the DIAL spec, which is the "Link using Wifi" option, I found it was mostly working like this: Chain of events
- Devices (mobile) broadcast an SSDP https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol message M-SEARCH
M-SEARCH * HTTP/1.1 HOST: 239.255.255.250:1900 MAN: "ssdp:discover" MX: 5 ST: urn:dial-multiscreen-org:service:dial:1
- And devices (TVs) capable of accepting casting would respond with something like
Cache-Control: max-age=3600 ST: urn:dial-multiscreen-org:service:dial:1 USN: ID::urn:dial-multiscreen-org:service:dial:1 Ext: Server: Roku/12.5.5 UPnP/1.0 Roku/12.5.5 LOCATION: http://IP:8060/dial/dd.xml WAKEUP: MAC=MAC;Timeout=10
Notice the LOCATION header. This would be a link to an xml file containing the device description.
- The device (mobile) makes an http GET request to the LOCATION. My TV's response looks something like this
<?xml version="1.0"?>
1 0 urn:roku-com:device:player:1-0 TV XXX xxx.com Roku Streaming Player Network Media XXX XXX http://www.roku.com/ XXXXXXX uuid:XXXXXXXXXX image/png 360 219 8 device-image.png urn:roku-com:service:ecp:1 urn:roku-com:serviceId:ecp1-0 ecp_SCPD.xml urn:dial-multiscreen-org:service:dial:1 urn:dial-multiscreen-org:serviceId:dial1-0 dial_SCPD.xml Notice how the service list contains urn:dial-multiscreen-org:service:dial:1, which is saying the device is capable of DIAL. Good. In the response headers for hitting the device description http://IP:8060/dial/dd.xml, there's one important header to capture:
Application-Url: http://IP:8060/dial
Because it is the URL used to check if a specific DIAL compatible app is installed or not.
- The device (mobile) makes a GET request to Application-Url + /YouTube (case sensitive). In this case that would be http://IP:8060/dial/YouTube. The response would be something like this:
<?xml version="1.0" encoding="UTF-8" ?> <service xmlns="urn:dial-multiscreen-org:schemas:dial" dialVer="2.1">
YouTube stopped If the mobile device gets a valid response, then it will see the device over wifi and offer to connect to it (it will show up as the friendlyName from the device description file.) Note: on my Roku, the request will be blocked, unless the Origin header is set to https://www.youtube.com
The response from http://IP:8060/dial/YouTube Might be in different state, and the mobile devices react differently based on the presence of the additionalData field.
- In the case the xml does not contain additionalData (so similar to the content from step 4)
- The mobile device would send a POST request to http://IP:8060/dial/YouTube, which includes theme and pairingCode url encoded in the body. The pairing code can be registered using https://www.youtube.com/api/lounge/pairing/register_pairing_code and then the mobile phone would join the lounge once the code is registered.
- In the case the xml contains additionalData, e.g. :
Example copied from https://github.com/henriquekano/youtube-lounge-api/wiki/Discovery
YouTube running Sony PS4 Pro qweqweqwe ?? ssssssssss xxxxxxxx 1500000 Then the phone will not send a pairing code, and will just join the lounge, since it has everything it needs already.
- In the case the xml contains additionalData, but not containing a loungeToken, e.g :
<?xml version="1.0" encoding="UTF-8" ?> <service xmlns="urn:dial-multiscreen-org:schemas:dial" dialVer="2.1">
YouTube stopped xxxxxxx XXX XXXX XXXXXXXXXXXXXX XXXXXXXXXXX Now this is the part I haven't explored yet - but I'm guessing a passiveSessionId is some form of new feature allowing the session to be passive until a device connects to it.
- One last thing, when
is returned, the mobile device (actually I tested this with Chrome browser) will a send a DELETE request to close the app. Just a small detail. Implementation
So the device is responsible for responding to the M-SEARCH requests, and for providing a device description xml file. So by definition, only one app can have the identifier YouTube for DIAL. This is why when the YouTube mobile app casts to a device, the official YouTube tv app will launch. This is why I went a different route.
1.
A DIAL server I have a udp connection listening for broadcast messages. When it sees an M-SEARCH, it responds just like the device does (see step 2 in the first section), but I set the LOCATION here to point to a file that I'm serving on a local web server running on the app. 2.
Serving device description Using a local server, I'm service a "virtual device description" xml file, and also serve an xml file for the/dial/YouTube file. For the device description, I set the friendlyName to "Playlet on" + tvName so that users can Identify the app they want to cast to.
So far I'm have a working implementation (just a PoC that needs cleanup) here iBicha/playlet#276 https://github.com/iBicha/playlet/pull/276 that does what I'm describing. I thought the approach could be used to add DIAL support to SmartTube. Most people never link using TV code, since it is more convenient for the auto discovery over WIFI to just work.
That's it. I just wanted to overshare since information about this stuff is pretty scarce, and it's hard to find.
Cheers!
— Reply to this email directly, view it on GitHub https://github.com/yuliskov/MediaServiceCore/issues/10, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABM7Z6D65WCHHE7ZI5ODVT3YS6P3JAVCNFSM6AAAAABDC2WTWOVHI2DSMVQWIX3LMV43ASLTON2WKOZSGEZDQNRQGY4TSOI . You are receiving this because you are subscribed to this thread.Message ID: @.***>
Hey! I'm the author of Playlet, a YouTube app for Roku TV.
I recently embarked on the journey to support casting from the YouTube app using lounge.
Some projects, like https://github.com/henriquekano/youtube-lounge-api, https://github.com/yuliskov/MediaServiceCore, and (especially) https://github.com/patrickkfkan/yt-cast-receiver helped me understand the protocol better, so I wanted to say thanks, and also share a bit of my findings in case it is useful.
As I tried to understand the DIAL spec, which is the "Link using Wifi" option, I found it was mostly working like this:
Chain of events
Devices (mobile) broadcast an SSDP message
M-SEARCH
And devices (TVs) capable of accepting casting would respond with something like
Notice the
LOCATION
header. This would be a link to an xml file containing the device description.The device (mobile) makes an http
GET
request to theLOCATION
. My TV's response looks something like thisNotice how the service list contains
urn:dial-multiscreen-org:service:dial:1
, which is saying the device is capable of DIAL. Good. In the response headers for hitting the device descriptionhttp://IP:8060/dial/dd.xml
, there's one important header to capture:Because it is the URL used to check if a specific DIAL compatible app is installed or not.
The device (mobile) makes a
GET
request toApplication-Url
+/YouTube
(case sensitive). In this case that would behttp://IP:8060/dial/YouTube
. The response would be something like this:If the mobile device gets a valid response, then it will see the device over wifi and offer to connect to it (it will show up as the
friendlyName
from the device description file.) Note: on my Roku, the request will be blocked, unless theOrigin
header is set tohttps://www.youtube.com
The response from
http://IP:8060/dial/YouTube
Might be in different state, and the mobile devices react differently based on the presence of theadditionalData
field.additionalData
(so similar to the content from step 4)POST
request tohttp://IP:8060/dial/YouTube
, which includestheme
andpairingCode
url encoded in the body. The pairing code can be registered usinghttps://www.youtube.com/api/lounge/pairing/register_pairing_code
and then the mobile phone would join the lounge once the code is registered.additionalData
, e.g. :Then the phone will not send a pairing code, and will just join the lounge, since it has everything it needs already.
additionalData
, but not containing aloungeToken
, e.g :Now this is the part I haven't explored yet - but I'm guessing a
passiveSessionId
is some form of new feature allowing the session to be passive until a device connects to it.<options allowStop="true" />
is returned, the mobile device (actually I tested this with Chrome browser) will a send aDELETE
request to close the app. Just a small detail.Implementation
So the device is responsible for responding to the
M-SEARCH
requests, and for providing a device description xml file. So by definition, only one app can have the identifierYouTube
for DIAL. This is why when the YouTube mobile app casts to a device, the official YouTube tv app will launch. This is why I went a different route.A DIAL server I have a udp connection listening for broadcast messages. When it sees an
M-SEARCH
, it responds just like the device does (see step 2 in the first section), but I set theLOCATION
here to point to a file that I'm serving on a local web server running on the app.Serving device description Using a local server, I'm serving a "virtual device description" xml file, and also serve an xml file for the
/dial/YouTube
file. For the device description, I set thefriendlyName
to"Playlet on" + tvName
so that users can Identify the app they want to cast to.So far I'm have a working implementation (just a PoC that needs cleanup) here https://github.com/iBicha/playlet/pull/276 that does what I'm describing. I thought the approach could be used to add DIAL support to SmartTube. Most people never link using TV code, since it is more convenient for the auto discovery over WIFI to just work.
That's it. I just wanted to overshare since information about this stuff is pretty scarce, and it's hard to find.
Cheers!