Skip to content

Commit

Permalink
feat(#41): Support play_media action + migrate to new action format
Browse files Browse the repository at this point in the history
  • Loading branch information
celian-garcia committed Oct 17, 2022
1 parent 97d7df6 commit fc1711f
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 18 deletions.
18 changes: 16 additions & 2 deletions experiment/chromecast.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,39 @@
import time
import pychromecast
from plexapi.server import PlexServer
from pychromecast.controllers.plex import PlexController

PLEX_URL = "http://192.168.1.11:32400"
PLEX_TOKEN = "mWXsudxa_fykCoMXJHx8"

plex_server = PlexServer(PLEX_URL, PLEX_TOKEN)
libraryItems = plex_server.library.search(
# libtype='movie', sort="addedAt:desc", limit=5
guid="plex://movie/5d7768278718ba001e311d57"
)

# List chromecasts on the network, but don't connect
services, browser = pychromecast.discovery.discover_chromecasts()
print([service.friendly_name for service in services])


# Discover and connect to chromecasts named Living Room
chromecasts, browser = pychromecast.get_listed_chromecasts(friendly_names=["Salon"])
# print(chromecasts)
# [cc.device.friendly_name for cc in chromecasts]
# ['Living Room']

cast = chromecasts[0]
plex_c = PlexController()
cast.register_handler(plex_c)
# Start worker thread and wait for cast device to be ready
cast.wait()
print(cast)

# plex_c.block_until_playing(libraryItems[0])

mc = cast.media_controller
# mc.play_media('http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', 'video/mp4')
# mc.block_until_active()
mc.block_until_active()
print(mc.status)
# MediaStatus(current_time=42.458322, content_id='http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4', content_type='video/mp4', duration=596.474195, stream_type='BUFFERED', idle_reason=None, media_session_id=1, playback_rate=1, player_state='PLAYING', supported_media_commands=15, volume_level=1, volume_muted=False)

Expand Down
30 changes: 22 additions & 8 deletions milo/cast/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
from typing import Dict

import pychromecast
from plexapi.server import PlexServer
from pychromecast.controllers.plex import PlexController


class Cast:
def __init__(self):
def __init__(self, plex_url: str, plex_token: str):
self.browser = None
self.casts: Dict[str, pychromecast.Chromecast] = {}
self.plex_ctrls: Dict[str, PlexController] = {}
self.plex_url = plex_url
self.plex_token = plex_token

def play(self, name: str):
if name in self.casts:
Expand All @@ -18,12 +23,14 @@ def pause(self, name: str):

def play_media(self, name: str, url: str):
if name in self.casts:
self.casts[name].media_controller.play_media(url)
self.plex_ctrls[name].block_until_playing(
PlexServer(self.plex_url, self.plex_token).library.search(guid=url)[0]
)

def names(self):
return self.casts.keys()

def star_discovery(self):
def start_discovery(self):
def cast_found(chromecast: pychromecast.Chromecast):
print("=> Discovered cast: " + chromecast.name)

Expand All @@ -34,15 +41,22 @@ def cast_found(chromecast: pychromecast.Chromecast):
# disconnect existing cast device if there is any
self.casts[name].disconnect(blocking=False)
self.casts[name] = chromecast
# # add status listener
self.plex_ctrls[name] = PlexController()
self.casts[name].register_handler(self.plex_ctrls[name])
# add status listener
# self.casts[name].register_connection_listener(self)
# self.casts[name].register_status_listener(self)
# # add media controller listener
# add media controller listener
# self.casts[name].media_controller.register_status_listener(self)
# # timeout 0.001 just waits for status to be ready
# # but we just need the thread to start by calling wait()
# self.casts[name].wait(0.001)
# timeout 0.001 just waits for status to be ready
# but we just need the thread to start by calling wait()
self.casts[name].wait(0.001)

print("Start discovery")
self.browser = pychromecast.get_chromecasts(
blocking=False, tries=None, retry_wait=5, timeout=5, callback=cast_found)

@staticmethod
def load_media_failed(item, error_code):
print(item)
print(error_code)
11 changes: 9 additions & 2 deletions milo/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class PocketSphinxArguments:
class Arguments:
verbose: bool
milobella_url: str
plex_url: str
plex_token: str
keyword: str
gpio_led: int
pocketsphinx: PocketSphinxArguments
Expand All @@ -46,15 +48,20 @@ def parse_arguments() -> Arguments:
parser = argparse.ArgumentParser()
parser.add_argument("--verbose", help="increase output verbosity", action="store_true")
parser.add_argument("--url", help="Milobella URL", default="https://milobella.com:10443")
parser.add_argument("--plex-url", help="Plex URL", default=None)
parser.add_argument("--plex-token", help="Plex Token", default=None)
parser.add_argument("--keyword", help="Wake up word", default="bella")
parser.add_argument("--pocket-sphinx-threshold", help="Pocket Sphinx threshold", default=1e-30, type=float)
parser.add_argument("--gpio-led", help="GPIO Led ID", default=-1, type=int)
parser.add_argument("--tracing-config", default=None, type=argparse.FileType('r'),
help="Tracing YAML configuration file")

args = parser.parse_args()
args_obj = Arguments()
args_obj.verbose = not not args.verbose
args_obj.milobella_url = args.url
args_obj.plex_url = args.plex_url
args_obj.plex_token = args.plex_token
args_obj.keyword = args.keyword
args_obj.gpio_led = args.gpio_led
psphinx_args = PocketSphinxArguments()
Expand Down Expand Up @@ -94,8 +101,8 @@ def main():
from milo.wuw.rpi_feedback import RPIWUWFeedback
wuw_feedback = RPIWUWFeedback(args.gpio_led)

cast = Cast()
cast.star_discovery()
cast = Cast(args.plex_url, args.plex_token)
cast.start_discovery()

# Initialize the milobella client
milobella = Milobella(args.milobella_url, cast)
Expand Down
8 changes: 4 additions & 4 deletions milo/milobella.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def milobella_request(self, question: str) -> (str, bool):
'text': question,
'device': {
'instruments': [
{'kind': 'chromecast', 'actions': ['play', 'pause'], 'name': name} for name in self._cast.names()
{'kind': 'chromecast', 'actions': ['play', 'pause', 'play_media'], 'name': name} for name in self._cast.names()
],
},
'context': self._current_context
Expand All @@ -46,7 +46,7 @@ def milobella_request(self, question: str) -> (str, bool):
if instrument_name is None:
print('instrument name not provided')
continue
if instrument_kind is not 'chromecast':
if instrument_kind != 'chromecast':
print(f'unsupported instrument kind {instrument_kind}')
continue
self._cast.play(instrument_name)
Expand All @@ -57,7 +57,7 @@ def milobella_request(self, question: str) -> (str, bool):
if instrument_name is None:
print('instrument name not provided')
continue
if instrument_kind is not 'chromecast':
if instrument_kind != 'chromecast':
print(f'unsupported instrument kind {instrument_kind}')
continue
self._cast.pause(instrument_name)
Expand All @@ -69,7 +69,7 @@ def milobella_request(self, question: str) -> (str, bool):
if instrument_name is None:
print('instrument name not provided')
continue
if instrument_kind is not 'chromecast':
if instrument_kind != 'chromecast':
print(f'unsupported instrument kind {instrument_kind}')
continue
if url is None:
Expand Down
9 changes: 7 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
requests~=2.24.0
pyaudio~=0.2.11
google.cloud.speech
google.cloud.texttospeech
bcolors==1.0.2
cachetools==4.1.1
certifi==2020.6.20
Expand All @@ -15,6 +13,10 @@ googleapis-common-protos==1.52.0
grpcio==1.30.0
gTTS==2.2.2
idna==2.10
plexapi~=4.13.0
google-api-python-client
gcloud
oauth2client
libcst==0.3.7
mypy-extensions==0.4.3
nose2==0.10.0
Expand Down Expand Up @@ -49,3 +51,6 @@ SpeechRecognition==3.8.1
typing-extensions==3.7.4.2
typing-inspect==0.6.0
urllib3==1.26.5

PyChromecast~=12.1.4
setuptools~=60.6.0

0 comments on commit fc1711f

Please sign in to comment.