Skip to content

Instantly share code, notes, and snippets.

@hansmbakker
Created June 5, 2015 22:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hansmbakker/8624c5412897bfa0b083 to your computer and use it in GitHub Desktop.
Save hansmbakker/8624c5412897bfa0b083 to your computer and use it in GitHub Desktop.
"""
Example that shows how the new Python 2 socket client can be used.
"""
from __future__ import print_function
import time
import sys
import logging
import pychromecast
import pychromecast.controllers.youtube as youtube
import pychromecast.controllers.syno_audio as audiocontroller
#if '--show-debug' in sys.argv:
logging.basicConfig(level=logging.DEBUG)
cast = pychromecast.get_chromecast()
dsaudio = audiocontroller.DSAudioController()
cast.register_handler(dsaudio)
print()
print(cast.device)
time.sleep(1)
print()
print(cast.status)
print()
print("Media status", cast.media_controller.status)
print()
#first make sure that we are allowed to talk
dsaudio.send_identify()
time.sleep(5)
print("Sending pause command")
dsaudio.pause()
time.sleep(10)
print("Sending play command")
dsaudio.play()
"""
Controller to interface with the DS Audio-app at https://dsaudio-chromecast.synology.com/dsaudio.html
"""
from . import BaseController
import json
MESSAGE_TYPE = 'type'
MESSAGE_DATA = 'data'
MESSAGE_COMMAND = 'command'
TYPE_PLAY_INDEX = "play"
TYPE_PAUSE = "pause"
TYPE_STOP = "stop"
TYPE_PLAY = "resume"
TYPE_NEXT = "next"
TYPE_PREV = "prev"
TYPE_SEEK = "seek"
TYPE_REPEAT = "set_repeat"
TYPE_SHUFFLE = "set_shuffle"
class DSAudioController(BaseController):
""" Controller to interact with Google media namespace. """
def __init__(self):
super(DSAudioController, self).__init__(
"urn:x-cast:com.synology.dsaudio", "ED01B6D7")
def send_identify(self):
""" Send login request to receiver, otherwise it won't talk to us """
self.send_message({"command": "identify"})
def stop(self):
""" Send stop command. """
self.send_message({MESSAGE_COMMAND: TYPE_STOP})
def pause(self):
""" Send pause command. """
self.send_message({MESSAGE_COMMAND: TYPE_PAUSE})
def play(self):
""" Send play command. """
self.send_message({MESSAGE_COMMAND: TYPE_PLAY})
def play_index(self, song_index):
msg = {
MESSAGE_COMMAND: TYPE_PLAY_INDEX,
MESSAGE_DATA: {
"playing_index": song_index
}
}
self.send_message(msg)
def next(self):
""" Send pause command. """
self.send_message({MESSAGE_COMMAND: TYPE_NEXT})
def prev(self):
""" Send play command. """
self.send_message({MESSAGE_COMMAND: TYPE_PREV})
def seek(self, position):
msg = {
MESSAGE_COMMAND: TYPE_SEEK,
MESSAGE_DATA: {
"position": position
}
}
self.send_message(msg)
def repeat(self, repeatMode):
msg = {
MESSAGE_COMMAND: TYPE_REPEAT,
MESSAGE_DATA: {
"mode": repeatMode
}
}
self.send_message(msg)
def shuffle(self, enableShuffle):
msg = {
MESSAGE_COMMAND: TYPE_SHUFFLE,
MESSAGE_DATA: {
"enabled": enableShuffle
}
}
self.send_message(msg)
# message handling
def _json_from_message(self, message):
""" Parses a PB2 message into JSON format. """
return json.loads(message.payload_utf8)
def receive_message(self, message, data):
print(self._json_from_message(message))
message_type = data[MESSAGE_TYPE]
if message_type == "challenge":
self._handle_challenge(data)
return True
elif message_type == "status":
self._process_status(data)
return True
else:
return False
def _handle_challenge(self, data):
challenge = data.get('data')['seed']
msg = {
"command": "identify",
"data": {
"auth_key": challenge
}
}
self.send_message(msg)
def _process_status(self, status):
""" Process latest status update. """
self.position = status.get('position') # in seconds
self.buffered = status.get('buffered') # in seconds
self.playing_index = status.get('playing_index') # item in the list of songs in the album
self.song = status.get('song') # song object
# 'song':{
# 'album':'538 Dance Smash Hits 2004, Volume 4: Autumn',
# 'type':'file',
# 'album_artist':'Various Artists',
# 'genre':'House/Euro House/Progressive Trance/Trance',
# 'artist':'Marly',
# 'composer':'',
# 'duration':199.7406,
# 'title':'You Never Know',
# 'cover_url':'[url_to_cover_image]',
# 'song_url':'[url_to_cover_image]',
# 'extra':{
# 'song_id':'music_4376',
# 'ds_id':'1370LSN001554'
# }
# },
self.repeat_mode = status.get('repeat_mode') # 'none','one','all',
self.shuffle_enabled = status.get('shuffle_enabled') # true, false
self.playing_status = status.get('status') # "playing";"pause";"stopped";
self.seekable = status.get('seekable') # in seconds
@balloob
Copy link

balloob commented Jun 9, 2015

You could override the channel_connected method to automatically send the identify command when connected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment