Last active
August 2, 2021 19:42
-
-
Save mzyy94/aa25615639fd3466d37bac7da204778e to your computer and use it in GitHub Desktop.
Discover DIAL device and request DIAL REST API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from urllib.request import * | |
import xml.etree.ElementTree as ET | |
headers = {'Origin': 'package:dial.py'} | |
class Dial: | |
appUrl = '' | |
appName = '' | |
ns = {'role': 'urn:dial-multiscreen-org:schemas:dial'} | |
def __init__(self, appUrl, appName): | |
self.appUrl = appUrl | |
self.appName = appName | |
def getInfo(self): | |
url = self.appUrl + self.appName | |
req = Request(url=url, headers=headers, method='GET') | |
data = {'url': req.full_url} | |
try: | |
with urlopen(req) as res: | |
body = res.read().decode() | |
service = ET.fromstring(body) | |
data['name'] = service.find('./role:name', self.ns).text | |
data['state'] = service.find('./role:state', self.ns).text | |
data['allowStop'] = service.find('./role:options[@allowStop]', self.ns).attrib['allowStop'] | |
data['resourceName'] = service.find("./role:link[@rel='run']", self.ns).attrib['href'] | |
except: | |
pass | |
return data | |
def launch(self): | |
info = self.getInfo() | |
if info['state'] == 'running': | |
return None | |
url = info['url'] | |
req = Request(url=url, headers=headers, method='POST') | |
try: | |
with urlopen(req): | |
return True | |
except: | |
return False | |
def stop(self): | |
info = self.getInfo() | |
if info['state'] != 'running': | |
return None | |
url = info['url'] + '/' + info['resourceName'] | |
req = Request(url=url, headers=headers, method='DELETE') | |
try: | |
with urlopen(req): | |
return True | |
except: | |
return False | |
def hide(self): | |
info = self.getInfo() | |
if info['state'] != 'running': | |
return None | |
url = info['url'] + '/' + info['resourceName'] + '/hide' | |
req = Request(url=url, headers=headers, method='POST') | |
try: | |
with urlopen(req): | |
return True | |
except: | |
return False | |
def main(): | |
import argparse | |
import sys | |
parser = argparse.ArgumentParser() | |
parser.add_argument('action', help='Action (state/launch/stop/hide)') | |
parser.add_argument('-u', '--url', required=True, help='Application URL') | |
parser.add_argument('-n', '--name', required=True, help='Application Name') | |
args = parser.parse_args() | |
ret = True | |
dial = Dial(args.url, args.name) | |
if args.action == 'state': | |
info = dial.getInfo() | |
print(info['state']) | |
elif args.action == 'launch': | |
ret = dial.launch() | |
elif args.action == 'stop': | |
ret = dial.stop() | |
elif args.action == 'hide': | |
ret = dial.hide() | |
else: | |
print('Invalid action: %s' % args.action) | |
parser.print_help() | |
ret = False | |
sys.exit(1 - int(ret or '0')) | |
if __name__ == '__main__': | |
# e.g. python3 dial.py -u http://192.168.181.222:56789/apps/ -n YouTube launch | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import socket | |
from random import randrange | |
body = """ | |
M-SEARCH * HTTP/1.1 | |
HOST: 239.255.255.250:1900 | |
MAN: "ssdp:discover" | |
MX: 1 | |
ST: urn:dial-multiscreen-org:service:dial:1 | |
""".replace('\n', '\r\n').encode('utf-8') | |
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
s.settimeout(5) | |
s.bind((socket.gethostname(), randrange(50000, 60000))) | |
s.sendto(body, ('239.255.255.250', 1900)) | |
while True: | |
try: | |
buf, _ = s.recvfrom(1024) | |
print(buf.decode('utf-8')) | |
except: | |
break | |
s.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
globalThis.cast = globalThis.cast || {}; | |
const nop = () => {}; | |
const errorLog = (text) => (err) => console.log(text, err); | |
const launchApp = function (dialAppName = "AmazonInstantVideo") { | |
const sessionRequest = new chrome.cast.SessionRequest( | |
chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID | |
); | |
sessionRequest.dialRequest = new chrome.cast.DialRequest(dialAppName); | |
chrome.cast.requestSession( | |
(session) => (cast.session = session), | |
errorLog("requestSession failed"), | |
sessionRequest | |
); | |
}; | |
const stopApp = function () { | |
if (cast.session) { | |
cast.session.stop(nop, errorLog("stop failed")); | |
const status = document.getElementById("dial-status"); | |
if (status) { | |
status.innerText = "Disconnected."; | |
} | |
} | |
}; | |
initializeCastApiLegacy = function () { | |
const sessionRequest = new chrome.cast.SessionRequest( | |
chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID | |
); | |
const apiConfig = new chrome.cast.ApiConfig(sessionRequest, nop, nop); | |
apiConfig.customDialLaunchCallback = async (dialInfo) => { | |
console.log("dialCallback", dialInfo.receiver.friendlyName, dialInfo); | |
const status = document.getElementById("dial-status"); | |
if (status) { | |
status.innerText = `Connected: ${dialInfo.receiver.friendlyName}[${dialInfo.receiver.ipAddress}]`; | |
} | |
}; | |
chrome.cast.initialize( | |
apiConfig, | |
() => console.log("Initialized."), | |
errorLog("initialize failed") | |
); | |
}; | |
window["__onGCastApiAvailable"] = function (loaded, _errorInfo) { | |
if (loaded) { | |
initializeCastApiLegacy(); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>LaunchDial</title> | |
<script src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js"></script> | |
<script src="launch_dial.js"></script> | |
</head> | |
<body> | |
<button onclick="launchApp('AmazonInstantVideo')">Launch Prime Video</button> | |
<button onclick="stopApp()">Stop</button> | |
<div id="dial-status">Waiting to connect.</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment