def stop(): chromecast = pychromecast.Chromecast(ADRESSE_IP_CHROMECAST) controller = chromecast.media_controller controller.stop()
from pychromecast.controllers.youtube import YouTubeController from tkinter import * from tkinter import messagebox import lxml from lxml import etree import urllib.request import re import requests from youtube_search import YoutubeSearch import json from keyboard import is_pressed from tkinter.filedialog import askopenfile import pytube #---------------------------------------------------------- global active chromecasts = pychromecast.Chromecast('192.168.0.101') cast = chromecasts cast.wait() yt = YouTubeController() cast.register_handler(yt) names = [] ids = [] local_files = [] local_names = [] playlist_names = ["Playlist", "sejtsrt", "nqn", "sheufhi"] plists = { "Playlist": ["omg", "pesen"], "sejtsrt": ["haha", "juiusebhv", "njnskjvbj"] } queue = ['nqen', "sjkber", "uoseg", "uihe"]
def initUI(self): self.splash = SplashScreen(QPixmap(320, 240), self) self.icon = QIcon(self.resource_path("chromecast.png")) self.splash.setWindowIcon(self.icon) self.discover_loop() self.setWindowTitle(self.title) self.setWindowIcon(self.icon) self.setGeometry(0, 0, self.width, self.height) self.window = QWidget() self.main_layout = QVBoxLayout() self.create_devices_layout() self.create_control_layout() self.create_seek_layout() self.create_status_layout() self.skip_forward_button.setEnabled(False) self.skip_forward_button.clicked.connect(self.on_skip_click) self.start_timer.connect(self.on_start_timer) self.stop_timer.connect(self.on_stop_timer) self.add_device.connect(self.on_add_device) self.remove_device.connect(self.on_remove_device) self.stop_call.connect(self.on_stop_signal) self.play_next.connect(self.on_play_next) self.stopping_timer_cancel.connect(self.on_stopping_timer_cancel) self.start_singleshot_timer.connect(self.on_start_singleshot_timer) self.device_list = [] if self.num_devices > 1: text = "devices found" else: text = "device found" print(self.num_devices, text) i = 0 for d in self.devices: cast = pychromecast.Chromecast(d.ip_addr) cast.wait() device = Device(self, d, cast, i) cast.media_controller.register_status_listener(device.media_listener) cast.register_status_listener(device.status_listener) cast.register_connection_listener(device.connection_listener) device.disconnect_volume = round(cast.status.volume_level * 100) device.filename = d._cast.media_controller.title self.device_list.append(device) self.combo_box.addItem(d.name) if i == 0: device.set_dial_value() print(d.name) i = i + 1 self.combo_box.currentIndexChanged.connect(self.on_index_changed) self.main_layout.addLayout(self.devices_layout) self.main_layout.addLayout(self.control_layout) self.main_layout.addLayout(self.seek_layout) self.main_layout.addLayout(self.status_layout) self.main_layout.addStretch() self.widget = QWidget() self.widget.setLayout(self.main_layout) self.setCentralWidget(self.widget) fg = self.frameGeometry() fg.moveCenter(QDesktopWidget().availableGeometry().center()) self.move(fg.topLeft()) self.show() self.splash.finish() self.raise_() self.activateWindow()
def setup_cast(device_name, video_url=None, prep=None, controller=None, ytdl_options=None): """ Prepares selected chromecast and/or media file. :param device_name: Friendly name of chromecast device to use. :type device_name: str or NoneType :param video_url: If supplied, setup_cast will try to exctract a media url from this, for playback or queueing. :type video_url: str :param prep: If prep = "app", video_url, if supplied, is meant for playback. The relevant chromecast app is started during initialization of the CastController object. If prep = "control", video_url, if supplied, is meant for queueing. The state of the selected chromecast is determined during initialization of the CastController object. If prep = None, no preparation is done. Should only be used if the desired action can be carried out regardless of the state of the chromecast (like volume adjustment). :type prep: str :param controller: If supplied, the normal logic for determining the appropriate controller is bypassed, and the one specified here is returned instead. :type controller: str :param ytdl_options: Pairs of options to be passed to YoutubeDL. For the available options please refer to https://github.com/rg3/youtube-dl/blob/master/youtube_dl/YoutubeDL.py#L138-L317 :type ytdl_options: tuple :returns: controllers.DefaultCastController or controllers.YoutubeCastController, and stream_info.StreamInfo if video_url is supplied. """ cache = Cache() cached_ip, cached_port = cache.get_data(device_name) stream = None try: if not cached_ip: raise ValueError # tries = 1 is necessary in order to stop pychromecast engaging # in a retry behaviour when ip is correct, but port is wrong. cast = pychromecast.Chromecast(cached_ip, port=cached_port, tries=1) except (pychromecast.error.ChromecastConnectionError, ValueError): cast = get_chromecast(device_name) cache.set_data(cast.name, cast.host, cast.port) cast.wait() if video_url: model_name = DEVICES_WITH_TWO_MODEL_NAMES.get(cast.model_name, cast.model_name) cc_info = (cast.device.manufacturer, model_name) stream = StreamInfo(video_url, model=cc_info, host=cast.host, device_type=cast.cast_type, ytdl_options=ytdl_options) if controller: if controller == "default": app = DEFAULT_APP else: app = next(a for a in APP_INFO if a["app_name"] == controller) elif stream and prep == "app": if stream.is_local_file: app = DEFAULT_APP else: try: app = next(a for a in APP_INFO if a["app_name"] == stream.extractor) except StopIteration: app = DEFAULT_APP else: try: app = next(a for a in APP_INFO if a["app_id"] == cast.app_id) except StopIteration: app = DEFAULT_APP if app["app_name"] != "default" and cast.cast_type not in app[ "supported_device_types"]: msg = "The %s app is not available for this device." % app[ "app_name"].capitalize() if controller: raise CattCastError(msg) elif stream: warning(msg) app = DEFAULT_APP if app["app_name"] == "youtube": controller = YoutubeCastController(cast, app["app_name"], app["app_id"], prep=prep) # We also check for controller, in the unlikely event that youtube-dl # gets an extractor named "dashcast". elif app["app_name"] == "dashcast" and controller: controller = DashCastController(cast, app["app_name"], app["app_id"], prep=prep) else: controller = DefaultCastController(cast, app["app_name"], app["app_id"], prep=prep) return (controller, stream) if stream else controller
def Status(input_name=False): """ Fetch player status TODO: Figure out how to parse and return additional data here """ uri = "FOOBAR" name = "FOOBAR" show_all = False Log.Debug('Trying to get cast device status here') for key, value in Request.Headers.items(): Log.Debug("Header key %s is %s", key, value) if key in ("X-Plex-Clienturi", "Clienturi"): Log.Debug("We have a client URI") uri = value if key in ("X-Plex-Clientname", "Clientname"): Log.Debug("X-Plex-Clientname: " + value) name = value if input_name is not False: name = input_name if uri == name: show_all = True chromecasts = fetch_devices() devices = [] for chromecast in chromecasts: cast = False if show_all is not True: if chromecast['name'] == name: Log.Debug("Found a matching chromecast: " + name) cast = chromecast if chromecast['uri'] == uri: Log.Debug("Found a matching uri:" + uri) cast = chromecast else: cast = chromecast if cast is not False: devices.append(cast) do = "" if len(devices) != 0: for device in devices: Log.Debug("We have set a chromecast here.") uris = device['uri'].split(":") host = uris[0] port = uris[1] Log.Debug("Host and port are %s and %s", host, port) cast = pychromecast.Chromecast(host, int(port)) Log.Debug("Waiting for device") cast.wait(2) app_id = cast.app_id meta_dict = False if app_id == "9AC194DC": pc = PlexController(cast) cast.register_handler(pc) plex_status = pc.plex_status() raw_status = { 'state': plex_status['state'], 'volume': plex_status['volume'], 'muted': plex_status['muted'] } meta_dict = plex_status['meta'] else: raw_status = {"state": "idle"} Log.Debug("Did we get it?!?! %s", raw_status) if not cast.is_idle: Log.Debug("We have a non-idle cast") status = "Running" + cast.app_display_name() else: status = "Idle" do = StatusContainer( dict=raw_status ) if meta_dict is not False: mc = MetaContainer( dict=meta_dict ) do.add(mc) return do
def __init__(self, chromecast_ip): self.cast = pychromecast.Chromecast(chromecast_ip) self.cast.wait()
parser.add_argument('--status', help='Print status information.', nargs='?') parser.add_argument('--pause', help='Send the PAUSE command.') parser.add_argument('--play', help='Send the PLAY command.') parser.add_argument('--skip', help='Skips rest of the media.') parser.add_argument('--rewind', help='Starts playing the media from the beginning.') parser.add_argument('--codec', help='Codec, e.g. video/mp4') args = parser.parse_args() config = ConfigParser() config.read(expanduser('~/assistant-helper/smarthome.ini')) CHROMECAST_HOST = config.get('cast', 'chromecast_ip') if CHROMECAST_HOST: cast = pychromecast.Chromecast(CHROMECAST_HOST) else: chromecasts = pychromecast.get_chromecasts() cast = next(cc for cc in chromecasts if cc.device.friendly_name == "WohnzimmerTV") # Wait for cast device to be ready cast.wait() print("wait for chromecast") mc = cast.media_controller if args.url: if args.codec: codec = args.codec
def get_chromecast_player(host=None, name=None): # pragma: no cover """ Get a chromecast preferable using host direcly, if not we will use the name and mnds (slow), if that dont work we will grab the first one. """ try: import pychromecast except ImportError: LOG.warning('Failed to import pychromecast') return None, None # All isnt used atm, lets keep it and # ill fix it later then i create a pr # for plexapi or pychromecast. MESSAGE_TYPE = 'type' TYPE_PLAY = 'PLAY' TYPE_PAUSE = 'PAUSE' TYPE_STOP = 'STOP' TYPE_STEPFORWARD = 'STEPFORWARD' TYPE_STEPBACKWARD = 'STEPBACK' TYPE_PREVIOUS = 'PREVIOUS' TYPE_NEXT = 'NEXT' TYPE_LOAD = 'LOAD' TYPE_DETAILS = 'SHOWDETAILS' TYPE_SEEK = 'SEEK' TYPE_MEDIA_STATUS = 'MEDIA_STATUS' TYPE_GET_STATUS = 'GET_STATUS' TYPE_EDIT_TRACKS_INFO = 'EDIT_TRACKS_INFO' from pychromecast.controllers import BaseController class PlexController(BaseController): """ Controller to interact with Plex namespace. """ def __init__(self): super(PlexController, self).__init__('urn:x-cast:plex', '9AC194DC') self.app_id = '9AC194DC' self.namespace = 'urn:x-cast:plex' self.request_id = 0 self.play_media_event = threading.Event() def _send_cmd(self, msg, namespace=None, inc_session_id=False, callback_function=None, inc=True): """Wrapper the commands.""" self.logger.debug('Sending msg %r %s %s %s %s', msg, namespace, inc_session_id, callback_function, inc) if inc: self._inc_request() if namespace: old = self.namespace try: self.namespace = namespace self.send_message(msg, inc_session_id=inc_session_id, callback_function=callback_function) finally: self.namespace = old else: self.send_message(msg, inc_session_id=inc_session_id, callback_function=callback_function) def _inc_request(self): self.request_id += 1 return self.request_id def receive_message(self, message, data): """ Called when a messag from plex to our controller is received. I havnt seen any message for ut but lets keep for for now, the tests i have done is minimal. """ self.logger.debug('Plex media receive function called.') if data[MESSAGE_TYPE] == TYPE_MEDIA_STATUS: self.logger.debug('(PlexController) MESSAGE RECEIVED: ' + data) return True return False def stop(self): """Send stop command.""" self._send_cmd({MESSAGE_TYPE: TYPE_STOP}) def pause(self): """Send pause command.""" self._send_cmd({MESSAGE_TYPE: TYPE_PAUSE}) def play(self): """Send play command.""" self._send_cmd({MESSAGE_TYPE: TYPE_PLAY}) def previous(self): """Send previous command.""" self._send_cmd({MESSAGE_TYPE: TYPE_PREVIOUS}) def next(self): self._send_cmd({MESSAGE_TYPE: TYPE_NEXT}) def seek(self, position, resume_state='PLAYBACK_START'): """Send seek command""" self._send_cmd({ MESSAGE_TYPE: TYPE_SEEK, 'currentTime': position, 'resumeState': resume_state }) def rewind(self): """Rewind back to the start""" self.seek(0) def set_volume(self, percent): # Feels dirty.. self._socket_client.receiver_controller.set_volume( float(percent / 100)) def volume_up(self, delta=0.1): """ Increment volume by 0.1 (or delta) unless it is already maxed. Returns the new volume. """ if delta <= 0: raise ValueError( "volume delta must be greater than zero, not {}".format( delta)) return self.set_volume(self.status.volume_level + delta) def volume_down(self, delta=0.1): """ Decrement the volume by 0.1 (or delta) unless it is already 0. Returns the new volume. """ if delta <= 0: raise ValueError( "volume delta must be greater than zero, not {}".format( delta)) return self.set_volume(self.status.volume_level - delta) def mute(self, status=None): """ mute the sound. status is just a override. """ if status is not None: st = status else: st = not status.volume_muted self._socket_client.receiver_controller.set_volume_muted(st) def show_media(self, media): """Show the media on the screen, but don't start it.""" msg = media_to_chromecast_command(media, type=TYPE_DETAILS, requestid=self._inc_request()) def cb(): self._send_cmd(msg, inc_session_id=True, inc=False) self.launch(cb) def quit_app(self): """Quit the plex app""" self._socket_client.receiver_controller.stop_app() @property def status(self): # So to get this we could add a listener and update the data ourself # or get can just use socket_clients # status should get a own pr so we can grab the subtitle (episode title.) # Lets just patch this for now.. def episode_title(self): return self.media_metadata.get('subtitle') mc = self._socket_client.media_controller.status mc.episode_title = property(episode_title) return self._socket_client.media_controller.status def disable_subtitle(self): # Shit does not work. """Disable subtitle.""" self._send_cmd( { MESSAGE_TYPE: TYPE_EDIT_TRACKS_INFO, "activeTrackIds": [] }, namespace='urn:x-cast:com.google.cast.media') def _send_start_play(self, media): msg = media_to_chromecast_command(media, requestid=self._inc_request()) self._send_cmd(msg, namespace='urn:x-cast:com.google.cast.media', inc_session_id=True, inc=False) def block_until_playing(self, item, timeout=None): """Helper just incase this is running as a script.""" self.play_media_event.clear() self.play_media(item) self.play_media_event.wait(timeout) self.play_media_event.clear() def play_media(self, item): """Start playback in the chromecast using the selected media. """ self.play_media_event.clear() def app_launched_callback(): try: self._send_start_play(item) finally: self.play_media_event.set() self.launch(app_launched_callback) def join(self, timeout=None): self._socket_client.join(timeout=timeout) def disconnect(self, timeout=None, blocking=True): self._socket_client.disconnect() if blocking: self.join(timeout=timeout) cast = None try: cast = pychromecast.Chromecast(host=host) except pychromecast.ChromecastConnectionError: chromecasts = pychromecast.get_chromecasts() if len(chromecasts) == 1: cast = chromecasts[0] elif len(chromecasts) > 1: cast = next(cc for cc in chromecasts if cc.device.friendly_name == name) else: LOG.warning("Could'nt find any chromecast on you network") return None, None pc = PlexController() cast.register_handler(pc) return pc, cast
list = load_data(args.data) load_config(args.config) while True: ips = [] proc = subprocess.Popen(['fping', '-d', '-i 1', '-r 2', '-a', '-g', env_vars['subnet_addr']], stdout=subprocess.PIPE, stderr=open(os.devnull, 'w')) while True: line = proc.stdout.readline().decode('utf-8') if not line: break ips.append(line.strip()) for i in list: if i[0] in ips: i[1] = time.time() if not i[3]: # This is not async because your chromecast devace cant handle 2 Audiostreams print('[+]', i[0], 'is alive') cast = pychromecast.Chromecast(env_vars['chromecast_addr']) cast.wait() mc = cast.media_controller mc.play_media(i[2], 'audio/mp3') mc.stop() i[3] = True print('[*]', 'Audio sent') else: if time.time() - i[1] >= int(env_vars['timeout']) and i[3]: print('[-]', i[0], 'is not alive') i[3] = False
def __init__(self): subprocess.Popen(param.server_cmd) self._cast = pychromecast.Chromecast(param.chromecast_ip)
import time import sys import pychromecast parser = argparse.ArgumentParser( description="Example on how to use the Spotify Controller.") parser.add_argument('--show-debug', help='Enable debug log', action='store_true') parser.add_argument('--host', help='Chromecast host address', default="localhost") parser.add_argument('--volume', help='Volume', default=0.5) args = parser.parse_args() if args.show_debug: logging.basicConfig(level=logging.DEBUG) # Uncomment to enable http.client debug log #http_client.HTTPConnection.debuglevel = 1 try: cast = pychromecast.Chromecast(args.host) except pychromecast.error.ChromecastConnectionError: print('ERROR: Failed to connect to Chromecast at "{}"'.format(args.host)) sys.exit(1) # Wait for connection to the chromecast cast.wait() cast.set_volume(float(args.volume))
#!/usr/bin/python from __future__ import print_function import time import pychromecast home = pychromecast.Chromecast('192.168.1.103') home.media_controller.play_media("http://192.168.1.14/doorbell.mp3", 'audio/mpeg') home.wait()
def __init__(self, host): self.cast = pychromecast.Chromecast(host) self.youtube = youtube.YouTubeController() self.cast.register_handler(self.youtube)
def seek(): chromecast = pychromecast.Chromecast(ADRESSE_IP_CHROMECAST) time = (HEURE_REPRISE * 3600) + (MINUTE_REPRISE * 60) controller = chromecast.media_controller controller.seek(time)
def cast_youtube(videoID): cast = pychromecast.Chromecast('192.168.0.37') cast.wait() yt = YouTubeController() cast.register_handler(yt) yt.play_video(videoID)
def cli(ctx, host): assert host, 'autodiscovery not implemeted yet, use --host' ctx.obj = {'cc': pychromecast.Chromecast(host)} print 'connected to', ctx.obj['cc']
def volumio_agent(): global gv_server_ip api_session = requests.session() cast_device = None # initial state ctrl_create_count = 0 failed_status_update_count = 0 cc_host = "" cc_port = 0 # Cast state inits cast_status = 'none' cast_uri = 'none' cast_volume = 0 cast_confirmed = 0 while (1): # 1 sec delay per iteration time.sleep(1) # Get status from Volumio # Added exception protection to blanket # cover a failed API call or any of th given fields # not being found for whatever reason try: resp = api_session.get('http://localhost:3000/api/v1/getstate') json_resp = resp.json() status = json_resp['status'] uri = json_resp['uri'] artist = json_resp['title'] album = json_resp['album'] title = json_resp['title'] albumart = json_resp['albumart'] except: continue volumio_status_str = json.dumps(json_resp, indent=4) print("\n%s Volumio State:\n%s\n" % (time.asctime(), volumio_status_str)) # remove leading 'music-library' or 'mnt' if present # we're hosting from /mnt so we need remove the top-level # dir for prefix in ['music-library/', 'mnt/']: prefix_len = len(prefix) if uri.startswith(prefix): uri = uri[prefix_len:] volume = int( json_resp['volume']) / 100 # scale to 0.0 to 1.0 for Chromecast # Configured Chromecast host and port # This can update on the fly so we seek to # detect this (host, port) = get_chromecast_details() if (cc_host != host or cc_port != port): cc_host = host cc_port = port # Stop media player of existing device # if it exists if (cast_device is not None): cast_device.media_controller.stop() cast_status = status cast_device = None # Chromecast URLs for media and artwork chromecast_url, type = volumio_uri_to_url(gv_server_ip, uri) albumart_url = volumio_albumart_to_url(gv_server_ip, albumart) # Controller management # Handles first creation of the controller and # recreation of the controller after detection of stale connections # also only does this if we're in a play state if (status == 'play' and cast_device is None): print("%s Connecting to Chromecast %s:%d" % (time.asctime(), cc_host, cc_port)) cast_device = pychromecast.Chromecast(cc_host, cc_port) # Kill off any current app print("%s Waiting for device to get ready.." % (time.asctime())) if not cast_device.is_idle: print("Killing current running app") cast.quit_app() while not cast_device.is_idle: time.sleep(1) print("%s Connected to %s (%s) model:%s" % (time.asctime(), cast_device.name, cast_device.uri, cast_device.model_name)) ctrl_create_count += 1 # Cast state inits cast_status = 'none' cast_uri = 'none' cast_volume = 0 cast_confirmed = 0 # Skip remainder of loop if we have no device to # handle. This will happen if we are in an initial stopped or # paused state or ended up in these states for a long period if (cast_device is None): print("%s No active Chromecast device" % (time.asctime())) continue # Detection of Events from Volumio # All of these next code blocks are trying to compare # some property against a known cast equivalent to determine # a change has occured and action required # Volume change only while playing if (cast_volume != volume and cast_status == 'play'): print("Setting Chromecast Volume: %.2f" % (volume)) cast_device.set_volume(volume) cast_volume = volume # Pause if (cast_status != 'pause' and status == 'pause'): print("Pausing Chromecast") cast_device.media_controller.pause() cast_status = status # Resume play if (cast_status == 'pause' and status == 'play'): print("Unpause Chromecast") cast_device.media_controller.play() cast_status = status # Stop if (cast_status != 'stop' and status == 'stop'): # This can be an actual stop or a # switch to the next track # the uri field will tell us this if (uri == ''): # normal stop no next track set # We can also ditch the device print("Stop Chromecast") cast_device.media_controller.stop() cast_status = status cast_device = None elif (uri != cast_uri): # track switch print("Casting URL (paused):%s type:%s" % (chromecast_url.encode('utf-8'), type)) # Prep for playback but paused # autoplay = False cast_device.play_media(chromecast_url, content_type=type, title=title, thumb=albumart_url, autoplay=False) # Assume in paused state # Another 'play' event will trigger us # out of this assumed paused state cast_status = 'pause' cast_uri = uri cast_confirmed = 0 # Play a song or stream or next in playlist if ((cast_status != 'play' and status == 'play') or (status == 'play' and uri != cast_uri)): print("Casting URL:%s type:%s" % (chromecast_url.encode('utf-8'), type)) # Let the magic happen cast_device.play_media(chromecast_url, content_type=type, title=title, thumb=albumart_url, autoplay=True) # unset cast confirmation cast_confirmed = 0 # Note the various specifics of play cast_status = status cast_uri = uri # Status updates from Chromecast if (status != 'stop'): # We need an updated status from the Chromecast # This can fail sometimes when nothing is really wrong and # then other times when things are wrong :) # # So we give it a tolerance of 5 consecutive failures try: cast_device.media_controller.update_status() except: failed_status_update_count += 1 print("%s Failed to get chromecast status.. %d/5" % (time.asctime(), failed_status_update_count)) if (failed_status_update_count >= 5): print( "%s Detected broken controller after 5 failures to get status" % (time.asctime())) cast_device = None cast_status = 'none' cast_uri = 'none' cast_volume = 0 cast_confirmed = 0 failed_status_update_count = 0 continue # Reset failed status count failed_status_update_count = 0 cast_url = cast_device.media_controller.status.content_id cast_elapsed = int( cast_device.media_controller.status.current_time) # Length and progress calculation if cast_device.media_controller.status.duration is not None: duration = int(cast_device.media_controller.status.duration) progress = int(cast_elapsed / duration * 100) else: duration = 0 progress = 0 elapsed_mins = int(cast_elapsed / 60) elapsed_secs = cast_elapsed % 60 duration_mins = int(duration / 60) duration_secs = duration % 60 print( "%s Chromecast.. Instance:%d Confirmed:%d State:%s Elapsed: %d:%02d/%d:%02d [%02d%%]" % (time.asctime(), ctrl_create_count, cast_confirmed, status, elapsed_mins, elapsed_secs, duration_mins, duration_secs, progress)) # Confirm successful casting after observing 5 seconds play # Plays a role in better detecting idle state for next song if (status == 'play' and cast_elapsed > 5): cast_confirmed = 1 # Detect end of play on chromecast # and nudge next song in playlist # We combine detection of idle state # and a previously casr_confirmed. # Otherwise we will get false positives after # just starting playing and may skip tracks # before they actually start. if (status == 'play' and cast_confirmed == 1 and cast_device.media_controller.status.player_is_idle): print("%s Request Next song" % (time.asctime())) cast_confirmed = 0 resp = api_session.get( 'http://localhost:3000/api/v1/commands/?cmd=next') # sync local progress every 10 seconds # This is not exact and will likely keep volumio behind. # However we want to avoid volumio playback progress charging ahead # of the chromecast progress as it could change track before the # chromecast completes it playback. # We also limit this sync to confirmed casts and put a stop at 50% progress # as we'll be close enough by then. # We also ignore radio strems as sync does not apply to them if (status == 'play' and cast_confirmed == 1 and cast_elapsed % 10 == 0 and progress < 50 and not cast_uri.startswith('http')): print("%s Sync Chromecast elapsed %d secs to Volumio" % (time.asctime(), cast_elapsed)) resp = api_session.get( 'http://localhost:3000/api/v1/commands/?cmd=seek&position=%d' % (cast_elapsed))
def get_chromecast(self): return pychromecast.Chromecast(self.host, device=pychromecast.get_device_status( socket.gethostbyname(self.host)))
def mk_from_ip(ip): try: return ThingChromecast(pychromecast.Chromecast(ip)) except pychromecast.error.ChromecastConnectionError: return ThingChromecast(None, ip)
def RestartSpotify(q,uri,TrackId = None,ContextUri = None,seektime=0,ContextType = None,Offset = None): global _plugin try: #Get the latest played music from Spotify if not given as parameters TrackInfo = _plugin.SpotifyClient.current_user_recently_played(limit=1) if TrackId == None and ContextUri == None: if TrackInfo['items'][0]['context'] != None: ContextUri = TrackInfo['items'][0]['context']['uri'] ContextType = TrackInfo['items'][0]['context']['type'] Offset = {"uri": TrackInfo['items'][0]['track']['uri']} else: TrackId = [TrackInfo['items'][0]['track']['uri']] elif ContextUri != None: Offset = {"uri": TrackId} TrackId = None elif TrackId != None and ContextUri == None: TrackId = [TrackId] #Connect to chromecast ip = uri.split(":")[0] port = int(uri.split(":")[1]) cc = pychromecast.Chromecast(ip,port) cc.start() cc.wait() sp = SpotifyController(_plugin.SpotifyAccessToken, _plugin.SpotifyExpiryTime) cc.register_handler(sp) #Launch spotify app on chromecast and find device id device_id = None sp.launch_app() if _plugin.Debug == True: q.put("Spotify started.") devices_available = _plugin.SpotifyClient.devices() for device in devices_available['devices']: if device['name'] == cc.name: device_id = device['id'] break if ContextUri != None: if _plugin.Debug == True: q.put("Spotify user id is " + str(_plugin.SpotifyUserId) + " contexturi is " + str(ContextUri) + " Offset is " + str(Offset)) if ContextType == 'artist': Name = _plugin.SpotifyClient.artist(ContextUri)["name"] Offset = None elif ContextType == "album": Name = _plugin.SpotifyClient.album("spotify:album:3KHPqtzQKRPKup29xEQWtg")["name"] else: Name = _plugin.SpotifyClient.user_playlist(_plugin.SpotifyUserId,ContextUri,"name")["name"] if Offset != None: q.put("Restarted playback of " + str(ContextType) + " with the name '" + str(Name) + "' and track '" + TrackInfo['items'][0]['track']['name'] + "'" ) elif ContextUri != None: q.put("Restarted playback of " + str(ContextType) + " with the name '"+ str(Name) + "'") else: q.put('Restarted playback of track "' + TrackInfo['items'][0]['track']['name'] +'"' ) if _plugin.Debug == True: q.put("Spotify arguments are: uris "+str(TrackId) + " context uri " + str(ContextUri) + " offset " + str(Offset)) try: _plugin.SpotifyClient.start_playback(device_id=device_id, uris=TrackId, context_uri=ContextUri, offset=Offset) except: try: _plugin.SpotifyClient.start_playback(device_id=device_id, uris=TrackId, context_uri=ContextUri) except Exception as e: q.put('Error on line {}'.format(sys.exc_info()[-1].tb_lineno)+" Error is: " +str(e)) if seektime != 0: _plugin.SpotifyClient.seek_track(seektime) q.put("Searched in track to previous position") cc.disconnect() if _plugin.Debug == True: q.put("Restarting Spotify is done") except Exception as e: if "Could not connect to" in str(e): q.put("Could not start Spotify as the chrmecast is not connected.") else: q.put('Error on line {}'.format(sys.exc_info()[-1].tb_lineno)+" Error is: " +str(e))
import pychromecast from flask import Flask, request, send_from_directory, jsonify from gtts import gTTS SERVER_HOST = os.getenv("SERVER_HOST", "0.0.0.0") SERVER_PORT = int(os.getenv("SERVER_PORT", "5257")) GOOGLE_HOME_IP_ADDRESS = os.getenv("GOOGLE_HOME_IP_ADDRESS", "0.0.0.0") DEFAULT_LANG = os.getenv("DEFAULT_LANG", "ja") TMP_DIR = os.getenv("TMP_DIR", "/tmp/google-homed") NIGHT_HOURS = [ int(x) for x in os.getenv("NIGHT_HOURS", "1,2,3,4,5,6").split(",") ] app = Flask(__name__) device = pychromecast.Chromecast(GOOGLE_HOME_IP_ADDRESS) @app.route("/file/<path:filename>") def send_cache(filename): return send_from_directory(TMP_DIR, filename) @app.route("/speak", methods=["GET", "POST"]) def speak(): if is_night_mode_enabled(): return jsonify({ "success": False, "message": "Currently, night mode is enabled." })
print('Server started at %s:%s!' % (local_ip, self.server_address[1])) self.serve_forever() except KeyboardInterrupt: pass finally: self.server_close() # start server in background server = StoppableHTTPServer(('', PORT), http.server.SimpleHTTPRequestHandler) thread = threading.Thread(None, server.run) thread.start() # connect to Google Home ghome = pychromecast.Chromecast(ghome_ip) print(ghome) ghome.wait() # set volume level, no beep sound volume = ghome.status.volume_level ghome.set_volume(0) # create tts mp3 os.makedirs('cache', exist_ok=True) fname = 'cache/cache.mp3' tts = gTTS(say, lang=lang) tts.save(fname) # ready to serve the mp3 file from server
def Cmd(): """ Media control command(s). Plex-specific commands use the format: Required params: Uri Cmd Vol(If setting volume, otherwise, ignored) Where <COMMAND> is one of: PLAY (resume) PAUSE STOP STEPFORWARD STEPBACKWARD Need to test, not in PHP cast app) PREVIOUS NEXT MUTE UNMUTE VOLUME - also requires an int representing level from 0-100 """ Log.Debug('Recieved a call to control playback') params = sort_headers(['Uri', 'Cmd', 'Val'], False) status = "Missing paramaters" response = "Error" if params is not False: uri = params['Uri'].split(":") cast = pychromecast.Chromecast(uri[0], int(uri[1])) cast.wait() pc = PlexController(cast) Log.Debug("Handler namespace is %s" % pc.namespace) cast.register_handler(pc) Log.Debug("Handler namespace is %s" % pc.namespace) cmd = params['Cmd'] Log.Debug("Command is " + cmd) if cmd == "play": pc.play() if cmd == "pause": pc.pause() if cmd == "stop": pc.stop() if cmd == "next": pc.next() if (cmd == "offset") & ('Val' in params): pc.seek(params["Val"]) if cmd == "previous": pc.previous() if cmd == "volume.mute": pc.mute(True) if cmd == "volume.unmute": pc.mute(False) if (cmd == "volume") & ('Val' in params): pc.set_volume(params["Val"]) if cmd == "volume.down": pc.volume_down() if cmd == "volume.up": pc.volume_up() cast.disconnect() response = "Command successful" oc = ObjectContainer( title1=response, title2=status, no_cache=True, no_history=True) return oc
def setup_cast(device_name, video_url=None, prep=None, controller=None): """ Prepares selected chromecast and/or media file. :param device_name: Friendly name of chromecast device to use. :type device_name: str or NoneType :param video_url: If supplied, setup_cast will try to exctract a media url from this, for playback or queing. :type video_url: str :param prep: If prep = "app", video_url, if supplied, is meant for playback. The relevant chromecast app is started during initialization of the CastController object. If prep = "control", video_url, if supplied, is meant for queing. The state of the selected chromecast is determined during initialization of the CastController object. If prep = None, no preparation is done. Should only be used if the desired action can be carried out regardless of the state of the chromecast (like volume adjustment). :type prep: str :param controller: If supplied, the normal logic for determining the appropriate controller is bypassed, and the one specified here is returned instead. :type controller: str :returns: controllers.DefaultCastController or controllers.YoutubeCastController, and stream_info.StreamInfo if video_url is supplied. """ cache = Cache() cached_ip = cache.get_data(device_name) stream = None try: if not cached_ip: raise ValueError cast = pychromecast.Chromecast(cached_ip) except (pychromecast.error.ChromecastConnectionError, ValueError): cast = get_chromecast(device_name) cache.set_data(cast.name, cast.host) cast.wait() if video_url: cc_info = (cast.device.manufacturer, cast.model_name) stream = StreamInfo(video_url, model=cc_info, host=cast.host) if controller: if controller == "default": app = DEFAULT_APP else: app = next(a for a in APP_INFO if a["app_name"] == controller) elif stream and prep == "app": if stream.is_local_file: app = DEFAULT_APP else: try: app = next(a for a in APP_INFO if a["app_name"] == stream.extractor) except StopIteration: app = DEFAULT_APP else: try: app = next(a for a in APP_INFO if a["app_id"] == cast.app_id) except StopIteration: app = DEFAULT_APP if (not controller and app["app_name"] != "default" and cast.cast_type not in app["supported_device_types"]): if stream: warning("The %s app is not available for this device." % app["app_name"].capitalize()) app = DEFAULT_APP if app["app_name"] == "youtube": controller = YoutubeCastController(cast, app["app_name"], app["app_id"], prep=prep) else: controller = DefaultCastController(cast, app["app_name"], app["app_id"], prep=prep) return (controller, stream) if stream else controller
#!/usr/bin/python3 import pychromecast as c cc = c.Chromecast("192.168.1.108") cc.wait() cc.volume_down() cc.quit_app()
import hashlib ip='192.168.1.16' # ip='192.168.1.15' say='hey google play music' #********* retrieve local ip of my rpi3 import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) local_ip=s.getsockname()[0] s.close() #********************** fname=hashlib.md5(say.encode()).hexdigest()+".mp3"; #create md5 filename for caching castdevice = pychromecast.Chromecast(ip) castdevice.wait() vol_prec=castdevice.status.volume_level castdevice.set_volume(0.0) #set volume 0 for not hear the BEEEP fileDirectory = os.getcwd() + '/mp3_cache/' filePath = fileDirectory + fname try: os.mkdir(fileDirectory) except: pass if not os.path.isfile(filePath): tts = gTTS(say) tts.save(filePath)
triggerSwitch = False # if true, keyboard simulator works def remove_background(frame): fgmask = bgModel.apply(frame, learningRate=learningRate) kernel = np.ones((3, 3), np.uint8) fgmask = cv2.erode(fgmask, kernel, iterations=1) res = cv2.bitwise_and(frame, frame, mask=fgmask) return res ########################### cv2.namedWindow('Single-Threaded Detection', cv2.WINDOW_NORMAL) #obtain current status of devices foco_det = pychromecast.Chromecast(li) alarma_det = pychromecast.Chromecast(al) aire_det = pychromecast.Chromecast(ac) musica_det = pychromecast.Chromecast(pi) bool left bool fist bool okay bool palm while True: # Expand dimensions since the model expects images to have shape: [1, None, None, 3] ret, image_np = cap.read() # image_np = cv2.flip(image_np, 1)
# Parameters LOG_LEVEL = logging.DEBUG VT_APPKEY = os.environ['VT_APPKEY'] VT_DEFAULT_SPEAKER = 'hikari' GOOGLE_HOME_IP = '192.168.11.4' NGROK_ADDR_GET_URL = 'http://127.0.0.1:4040/api/tunnels' ngrokurl = None DYNAMODB_TABLE = 'MY_HOST' # request_parameters # request_type REQ_TYPE_INTENT_OSEWA_DETAIL = 'record_osewa_detail' REQ_TYPE_INTENT_OSEWA_SEARCH = 'search_osewa' device = pychromecast.Chromecast(GOOGLE_HOME_IP) print(device) if not device.is_idle: print("killing current running app on Google Home") device.quit_app() time.sleep(3) device.wait() def update_ngrok_url(url): t = str(datetime.datetime.now()) db = boto3.resource('dynamodb') table = db.Table('MY_HOST') # 最新レコード取得 print('get latest update record of ngrok..')
def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the cast platform.""" import pychromecast # Import CEC IGNORE attributes pychromecast.IGNORE_CEC += config.get(CONF_IGNORE_CEC, []) known_hosts = hass.data.get(KNOWN_HOSTS_KEY) if known_hosts is None: known_hosts = hass.data[KNOWN_HOSTS_KEY] = [] if discovery_info: host = (discovery_info.get('host'), discovery_info.get('port')) if host in known_hosts: return hosts = [host] elif CONF_HOST in config: host = (config.get(CONF_HOST), DEFAULT_PORT) if host in known_hosts: return hosts = [host] else: hosts = [ tuple(dev[:2]) for dev in pychromecast.discover_chromecasts() if tuple(dev[:2]) not in known_hosts ] casts = [] # get_chromecasts() returns Chromecast objects with the correct friendly # name for grouped devices all_chromecasts = pychromecast.get_chromecasts() for host in hosts: (_, port) = host found = [ device for device in all_chromecasts if (device.host, device.port) == host ] if found: try: casts.append(CastDevice(found[0])) known_hosts.append(host) except pychromecast.ChromecastConnectionError: pass # do not add groups using pychromecast.Chromecast as it leads to names # collision since pychromecast.Chromecast will get device name instead # of group name elif port == DEFAULT_PORT: try: # add the device anyway, get_chromecasts couldn't find it casts.append(CastDevice(pychromecast.Chromecast(*host))) known_hosts.append(host) except pychromecast.ChromecastConnectionError: pass add_devices(casts)
from __future__ import print_function import time import logging import pychromecast #Scott's edit #chromecasts = pychromecast.get_chromecasts() chromecasts = pychromecast.Chromecast('192.168.1.176') print(chromecasts) #[cc.device.friendly_name for cc in chromecasts] #['wolftube', 'Living Room', 'Den', 'Bedroom'] cast = chromecasts # Wait for cast device to be ready cast.wait() print(cast) #print(cast.device) #DeviceStatus(friendly_name='Living Room', model_name='Chromecast', manufacturer='Google Inc.', api_version=(1, 0), uuid=UUID('df6944da-f016-4cb8-97d0-3da2ccaa380b'), cast_type='cast') #print(cast.status) #CastStatus(is_active_input=True, is_stand_by=False, volume_level=1.0, volume_muted=False, app_id=u'CC1AD845', display_name=u'Default Media Receiver', namespaces=[u'urn:x-cast:com.google.cast.player.message', u'urn:x-cast:com.google.cast.media'], session_id=u'CCA39713-9A4F-34A6-A8BF-5D97BE7ECA5C', transport_id=u'web-9', status_text='') mc = cast.media_controller mc.play_media( 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', 'video/mp4') #mc.block_until_active() print(mc.status) #MediaStatus(current_time=42.458322, content_id=u'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', content_type=u'video/mp4', duration=596.474195, stream_type=u'BUFFERED', idle_reason=None, media_session_id=1, playback_rate=1, player_state=u'PLAYING', supported_media_commands=15, volume_level=1, volume_muted=False)