def Play(): """ Endpoint to play media. """ Log.Debug('Recieved a call to play media.') params = ['Clienturi', 'Contentid', 'Contenttype', 'Serverid', 'Serveruri', 'Username', 'Transienttoken', 'Queueid', 'Version'] values = sort_headers(params, False) status = "Missing required headers" msg = status if values is not False: Log.Debug("Holy crap, we have all the headers we need.") client_uri = values['Clienturi'].split(":") host = client_uri[0] port = int(client_uri[1]) pc = False servers = fetch_servers() for server in servers: if server['id'] == values['Serverid']: Log.Debug("Found a matching server!") values['Serveruri'] = server['uri'] values['Version'] = server['version'] msg = "No message received" try: cast = pychromecast.Chromecast(host, port) cast.wait() values['Type'] = cast.cast_type pc = PlexController(cast) cast.register_handler(pc) pc.play_media(values, log_data) except pychromecast.LaunchError, pychromecast.PyChromecastError: Log.Debug('Error connecting to host.') status = "Error" finally:
def _play_media(hass: HomeAssistant, chromecast: Chromecast, media_type: str, media_id: str) -> None: """Play media.""" result = process_plex_payload(hass, media_type, media_id) controller = PlexController() chromecast.register_handler(controller) offset_in_s = result.offset / 1000 controller.play_media(result.media, offset=offset_in_s)
def cast_media_to(cast, media): try: cast.wait() pc = PlexController() cast.register_handler(pc) pc.play_media(media) except Exception as e: logging.error(e)
def _play_media(hass: HomeAssistant, chromecast: Chromecast, media_type: str, media_id: str) -> None: """Play media.""" media_id = media_id[len(PLEX_URI_SCHEME):] media = lookup_plex_media(hass, media_type, media_id) if media is None: return controller = PlexController() chromecast.register_handler(controller) controller.play_media(media)
def play_media(self, media_type, media_id, **kwargs): """Play media from a URL.""" extra = kwargs.get(ATTR_MEDIA_EXTRA, {}) metadata = extra.get("metadata") # We do not want this to be forwarded to a group if media_type == CAST_DOMAIN: try: app_data = json.loads(media_id) if metadata is not None: app_data["metadata"] = extra.get("metadata") except json.JSONDecodeError: _LOGGER.error("Invalid JSON in media_content_id") raise # Special handling for passed `app_id` parameter. This will only launch # an arbitrary cast app, generally for UX. if "app_id" in app_data: app_id = app_data.pop("app_id") _LOGGER.info("Starting Cast app by ID %s", app_id) self._chromecast.start_app(app_id) if app_data: _LOGGER.warning( "Extra keys %s were ignored. Please use app_name to cast media", app_data.keys(), ) return app_name = app_data.pop("app_name") try: quick_play(self._chromecast, app_name, app_data) except NotImplementedError: _LOGGER.error("App %s not supported", app_name) # Handle plex elif media_id and media_id.startswith(PLEX_URI_SCHEME): media_id = media_id[len(PLEX_URI_SCHEME):] media, _ = lookup_plex_media(self.hass, media_type, media_id) if media is None: return controller = PlexController() self._chromecast.register_handler(controller) controller.play_media(media) else: app_data = { "media_id": media_id, "media_type": media_type, **extra } quick_play(self._chromecast, "default_media_receiver", app_data)
def remote_control(hass, zeroconf, control, device, jump_amount): plex_c = PlexController() if control == "jump_forward": jump(hass, device, jump_amount[0]) elif control == "jump_back": jump(hass, device, -jump_amount[1]) elif control == "next_track" and device["device_type"] == "cast": cast_next_prev(hass, zeroconf, plex_c, device, "next") elif control == "previous_track" and device["device_type"] == "cast": cast_next_prev(hass, zeroconf, plex_c, device, "previous") else: media_service(hass, device["entity_id"], f"media_{control}")
def _setup_controllers(self): self.ctls = Controllers( YouTubeController(), DashCastController(), PlexController(), SuplaController(), # BbcIplayerController(), # BbcSoundsController(), # BubbleUPNPController(), # YleAreenaController(), # PlexApiController(), # HomeAssistantController(), ) for ctl in self.ctls: if ctl: self._register(ctl)
def handle_input(call): command_string = call.data.get("command").strip().lower() if not command_string: _LOGGER.warning(localize["no_call"]) return chromecasts = get_chromecasts() for chromecast in chromecasts: PA.devices[chromecast.device.friendly_name] = chromecast PA.clients = PA.server.clients() PA.client_names = [client.title for client in PA.clients] PA.client_ids = [client.machineIdentifier for client in PA.clients] if localize["controls"]["update_sensor"] in command_string: update_sensor() return cast = None alias = ["", 0] client = False speech_error = False command = process_speech(command_string, localize, default_cast, PA) if not command["control"]: _LOGGER.debug({i: command[i] for i in command if i != 'library'}) if PA.lib["updated"] < PA.plex.search(sort="addedAt:desc", limit=1)[0].addedAt: PA.lib = get_libraries(PA.plex) PA.device_names = list(PA.devices.keys()) devices = PA.device_names + PA.client_names + PA.client_ids device = fuzzy(command["device"] or default_cast, devices) if aliases: alias = fuzzy(command["device"] or default_cast, PA.alias_names) if alias[1] < 60 and device[1] < 60: _LOGGER.warning("{0} {1}: \"{2}\"".format( localize["cast_device"].capitalize(), localize["not_found"], command["device"].title())) _LOGGER.debug("Device Score: %s", device[1]) _LOGGER.debug("Devices: %s", str(devices)) if aliases: _LOGGER.debug("Alias Score: %s", alias[1]) _LOGGER.debug("Aliases: %s", str(PA.alias_names)) return name = aliases[alias[0]] if alias[1] > device[1] else device[0] cast = PA.devices[name] if name in PA.device_names else name client = isinstance(cast, str) if client: client_device = next( c for c in PA.clients if c.title == cast or c.machineIdentifier == cast) cast = client_device if command["control"]: control = command["control"] if client: cast.proxyThroughServer() plex_c = PA.server.client(cast.title) else: plex_c = PlexController() cast.wait() cast.register_handler(plex_c) if control == "play": plex_c.play() elif control == "pause": plex_c.pause() elif control == "stop": plex_c.stop() elif control == "jump_forward": plex_c.stepForward() elif control == "jump_back": plex_c.stepBack() return try: result = find_media(command, command["media"], PA.lib) media = video_selection(command, result["media"], result["library"]) except Exception: error = media_error(command, localize) if tts_error: tts = gTTS(error, lang=lang) tts.save(directory + 'error.mp3') speech_error = True _LOGGER.warning(error) if speech_error and not client: cast.wait() med_con = cast.media_controller mp3 = get_url(hass) + "/local/plex_assist_tts/error.mp3" med_con.play_media(mp3, 'audio/mpeg') med_con.block_until_active() return _LOGGER.debug("Media: %s", str(media)) if client: _LOGGER.debug("Client: %s", cast) cast.proxyThroughServer() plex_c = cast plex_c.playMedia(media) else: _LOGGER.debug("Cast: %s", cast.name) delay = 6 if call.data.get("cast_delay") or call.data.get("cast_delay") == 0: delay = call.data.get("cast_delay") elif cast.name in cast_delay.keys(): delay = cast_delay[cast.name] plex_c = PlexController() plex_c.namespace = 'urn:x-cast:com.google.cast.media' cast.register_handler(plex_c) cast.wait() play_media(float(delay), cast, plex_c, media) update_sensor()
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 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
media = plex_server.createPlayQueue(libraryItems) # Set starting position to the 3rd item if startItem demo. startItem = libraryItems[2] if args.startitem else None # Print info media_info(media, media.items) start_item_info(libraryItems[2]) elif args.demo == "playlist": # Convert list into a playlist for media. media = plex_server.createPlaylist("pychromecast test playlist", libraryItems) # Set starting position to the 4th item if startItem demo. startItem = libraryItems[3] if args.startitem else None # Print info media_info(media, media.items()) start_item_info(libraryItems[2]) plex_c = PlexController() cast.register_handler(plex_c) cast.wait() # Plays the media item, list, playlist, or playqueue. # If startItem = None it is ignored and playback starts at first item, # otherwise playback starts at the position of the media item given. plex_c.block_until_playing(media, startItem=startItem) if getattr(media, "TYPE", None) == "playlist": media.delete() # Shut down discovery browser.stop_discovery()
def handle_input(call): if not call.data.get("command").strip(): _LOGGER.warning(localize["no_call"]) return command_string = call.data.get("command").strip().lower() _LOGGER.debug("Command: %s", command_string) PA.client_update = True get_chromecasts(blocking=False, callback=cc_callback, zeroconf_instance=zc) if localize["controls"]["update_sensor"] in command_string: update_sensor(hass) return cast = None alias = ["", 0] client = False speech_error = False command = process_speech(command_string, localize, default_cast, PA) PA.device_names = list(PA.devices.keys()) if not command["control"]: _LOGGER.debug({i: command[i] for i in command if i != "library"}) if PA.lib["updated"] < PA.plex.search(sort="addedAt:desc", limit=1)[0].addedAt: PA.lib = get_libraries(PA.plex) devices = PA.device_names + PA.client_names + PA.client_ids device = fuzzy(command["device"] or default_cast, devices) if aliases: alias = fuzzy(command["device"] or default_cast, PA.alias_names) if alias[1] < 60 and device[1] < 60: _LOGGER.warning('{0} {1}: "{2}"'.format( localize["cast_device"].capitalize(), localize["not_found"], command["device"].title(), )) _LOGGER.debug("Device Score: %s", device[1]) _LOGGER.debug("Devices: %s", str(devices)) if aliases: _LOGGER.debug("Alias Score: %s", alias[1]) _LOGGER.debug("Aliases: %s", str(PA.alias_names)) return name = aliases[alias[0]] if alias[1] > device[1] else device[0] cast = PA.devices[name] if name in PA.device_names else name client = isinstance(cast, str) if client: client_device = next( c for c in PA.clients if c.title == cast or c.machineIdentifier == cast) cast = client_device if command["control"]: control = command["control"] if client: try: if "127.0.0.1" in cast.url("/"): cast.proxyThroughServer() except plexapi.exceptions.BadRequest: cast.proxyThroughServer() plex_c = cast else: plex_c = PlexController() cast.wait() cast.register_handler(plex_c) if control == "play": plex_c.play() elif control == "pause": plex_c.pause() elif control == "stop": plex_c.stop() elif control == "jump_forward": plex_c.stepForward() elif control == "jump_back": plex_c.stepBack() return try: result = find_media(command, command["media"], PA.lib) media = video_selection(command, result["media"], result["library"]) except Exception: error = media_error(command, localize) if tts_error: tts = gTTS(error, lang=lang) tts.save(directory + "error.mp3") speech_error = True if speech_error and not client: cast.wait() med_con = cast.media_controller mp3 = get_url(hass) + "/local/plex_assist_tts/error.mp3" med_con.play_media(mp3, "audio/mpeg") med_con.block_until_active() return _LOGGER.debug("Media: %s", str(media)) if client: _LOGGER.debug("Client: %s", cast) try: if "127.0.0.1" in cast.url("/"): cast.proxyThroughServer() except plexapi.exceptions.BadRequest: cast.proxyThroughServer() plex_c = cast plex_c.playMedia(media) else: _LOGGER.debug("Cast: %s", cast.name) plex_c = PlexController() cast.register_handler(plex_c) cast.wait() plex_c.block_until_playing(media) update_sensor(hass)
def handle_input(call): """Handle the service call.""" if not call.data.get("command").strip(): _LOGGER.warning(localize["no_call"]) return cast = None client = False speech_error = False get_chromecasts(blocking=False, callback=cc_callback) for client in PA.server.clients(): if client.title not in PA.client_names: PA.client_names.append(client.title) command = process_speech( call.data.get("command").lower(), localize, default_cast, PA ) if not command["control"]: _LOGGER.debug({i: command[i] for i in command if i != 'library'}) if PA.lib["updated"] < PA.plex.search(sort="addedAt:desc")[0].addedAt: PA.lib = get_libraries(PA.plex) try: devices = PA.device_names + PA.client_names device = fuzzy(command["device"] or default_cast, devices) alias = fuzzy(command["device"] or default_cast, PA.alias_names) name = aliases[alias[0]] if alias[1] > device[1] else device[0] cast = PA.devices[name] if name in PA.device_names else name except Exception: error = "{0} {1}.".format(localize["cast_device"].capitalize(), localize["not_found"]) _LOGGER.warning(error) return client = isinstance(cast, str) if command["control"]: control = command["control"] if client: PA.server.client(cast).proxyThroughServer() plex_c = PA.server.client(cast) else: plex_c = PlexController() cast.wait() cast.register_handler(plex_c) if control == "play": plex_c.play() elif control == "pause": plex_c.pause() elif control == "stop": plex_c.stop() elif control == "jump_forward": plex_c.stepForward() elif control == "jump_back": plex_c.stepBack() return try: result = find_media(command, command["media"], PA.lib) media = video_selection(command, result["media"], result["library"]) except Exception: error = media_error(command, localize) if tts_error: tts = gTTS(error, lang=lang) tts.save(directory + 'error.mp3') speech_error = True _LOGGER.warning(error) if speech_error and not client: cast.wait() med_con = cast.media_controller mp3 = hass.config.api.base_url + "/local/plex_assist_tts/error.mp3" med_con.play_media(mp3, 'audio/mpeg') med_con.block_until_active() return _LOGGER.debug("Media: %s", str(media)) if client: _LOGGER.debug("Client: %s", cast) PA.server.client(cast).proxyThroughServer() plex_c = PA.server.client(cast) plex_c.playMedia(media) else: _LOGGER.debug("Cast: %s", cast.name) plex_c = PlexController() cast.wait() cast.register_handler(plex_c) play_media(cast, plex_c, media)