Пример #1
0
def init_chromecast(options):
    global shared_options
    global shared_redis_connection
    global shared_chromecast
    global shared_chromecast_listener
    global shared_chromecast_media_listener
    try:
        try_to_connect_to_redis()
        shared_options = options
        shared_chromecast = False
        shared_chromecast = Chromecast(shared_options['chromecast_output_ip'])
        shared_chromecast.start()
        shared_chromecast.wait()
        shared_chromecast_listener = StatusListener(
            shared_chromecast.name, shared_chromecast,
            shared_options["chromecast_output_uuid"], shared_redis_connection)
        shared_chromecast.register_status_listener(shared_chromecast_listener)
        shared_chromecast_media_listener = StatusMediaListener(
            shared_chromecast.name, shared_chromecast,
            shared_options["chromecast_output_uuid"], shared_redis_connection)
        shared_chromecast.media_controller.register_status_listener(
            shared_chromecast_media_listener)
        #start_adhoc_listener()
        try:
            shared_chromecast.media_controller.stop()
        except Exception as e:
            print(e)
    except Exception as e:
        shared_chromecast = False
        return False
Пример #2
0
def play():
    try:
        output_chromecast_ip = sys.argv[1]
        uri_to_play = sys.argv[2]
        shuffle = sys.argv[3]
        if type(shuffle != bool):
            shuffle = string_to_bool(shuffle)
        redis_connection = try_to_connect_to_redis()
        spotify_token_info = RefreshSpotifyTokenIfNecessary(redis_connection)
        cast = Chromecast(output_chromecast_ip)
        cast.wait()
        client = spotipy.Spotify(auth=spotify_token_info["access_token"])
        sp = SpotifyController(spotify_token_info["access_token"],
                               spotify_token_info["seconds_left"])
        cast.register_handler(sp)
        sp.launch_app()
        if not sp.is_launched and not sp.credential_error:
            print('Failed to launch spotify controller due to timeout')
            sys.exit(1)
        if not sp.is_launched and sp.credential_error:
            print(
                'Failed to launch spotify controller due to credential error')
            sys.exit(1)

        devices_available = client.devices()
        spotify_device_id = None
        for device in devices_available['devices']:
            if device['id'] == sp.device:
                spotify_device_id = device['id']
                break
        if not spotify_device_id:
            print('No device with id "{}" known by Spotify'.format(sp.device))
            print('Known devices: {}'.format(devices_available['devices']))
            sys.exit(1)

        # # Start playback
        if uri_to_play.find('track') > 0:
            client.start_playback(device_id=spotify_device_id,
                                  uris=[uri_to_play])
        else:
            client.start_playback(device_id=spotify_device_id,
                                  context_uri=[uri_to_play])

        time.sleep(2)
        client.shuffle(shuffle)
        return True
    except Exception as e:
        print("Couldn't Load URI and Play Spotify")
        print(e)
        return False
Пример #3
0
def play_currated_uris(spotify_token_info, chromecast_output_ip, uris):
    try:
        cast = Chromecast(chromecast_output_ip)
        cast.wait()
        cast.media_controller.stop()
        #client = spotipy.Spotify( auth=spotify_token_info[ "access_token" ] )
        client = spotipy.Spotify(auth=spotify_token_info["access_token"])
        sp = SpotifyController(spotify_token_info["access_token"],
                               spotify_token_info["seconds_left"])
        cast.register_handler(sp)
        sp.launch_app()
        if not sp.is_launched and not sp.credential_error:
            print('Failed to launch spotify controller due to timeout')
            return False
        if not sp.is_launched and sp.credential_error:
            print(
                'Failed to launch spotify controller due to credential error')
            return False

        devices_available = client.devices()
        spotify_device_id = None
        for device in devices_available['devices']:
            if device['id'] == sp.device:
                spotify_device_id = device['id']
                break
        if not spotify_device_id:
            print('No device with id "{}" known by Spotify'.format(sp.device))
            print('Known devices: {}'.format(devices_available['devices']))
            return False

        client.start_playback(device_id=spotify_device_id, uris=uris)
        time.sleep(2)
        client.volume(99)
        time.sleep(2)
        client.volume(100)
        client.shuffle(False)
        return True
    except Exception as e:
        print("Couldn't Load Spotify Chromecast App")
        print(e)
        return False
Пример #4
0
	if "seconds_left" not in OurSpotifyTokenDB.self:
		GenerateSpotifyToken()
		return
	time_now = int( time.time() )
	OurSpotifyTokenDB.self[ "seconds_left" ] = OurSpotifyTokenDB.self[ "expire_time" ] - time_now
	if OurSpotifyTokenDB.self[ "seconds_left" ] < 300:
		print( "Spotify Token is About to Expire in " + str( OurSpotifyTokenDB.self[ "seconds_left" ] ) + " Seconds" )
		GenerateSpotifyToken()
	else:
		print( "Spotify Token is Still Valid for " + str( OurSpotifyTokenDB.self[ "seconds_left" ] ) + " Seconds" )

RefreshSpotifyTokenIfNecessary()

cast = Chromecast( OurPersonalDB.self[ "chromecast_ip" ] )
print('cast {}'.format(cast))
cast.wait()

spotify_device_id = None

# Create a spotify client
client = spotipy.Spotify( auth=OurSpotifyTokenDB.self[ "access_token" ] )
spotipy.trace = True
spotipy.trace_out = True

# Launch the spotify app on the cast we want to cast to
sp = SpotifyController( OurSpotifyTokenDB.self[ "access_token" ] , OurSpotifyTokenDB.self[ "seconds_left" ] )
cast.register_handler(sp)
sp.launch_app()

if not sp.is_launched and not sp.credential_error:
	print('Failed to launch spotify controller due to timeout')
Пример #5
0
class TwitchCastController(BaseController):
    """Controller used to send TwitchCast streams to a Chromecast."""
    def __init__(self,
                 chromecast_name: str = None,
                 chromecast_host: str = None) -> None:
        """Take care of some house keeping on init."""
        super(TwitchCastController,
              self).__init__('urn:x-cast:com.google.cast.media', 'DAC1CD8C')
        self._cast = None  # type: Chromecast
        self._chromecast_host = chromecast_host
        self._chromecast_name = chromecast_name
        self._expected_app_id = 'DAC1CD8C'
        self._setup_valid = False
        self._headers = {
            'User-Agent':
            "Home-Assistant-TwitchCast-Service {}".format(__version__)
        }
        self._location = "https://hls-us-west.nightdev.com"

    def _setup(self) -> bool:
        self._setup_valid = self._setup_chromecast()
        if self._setup_valid:
            _LOGGER.info("setup completed successfully")
        else:
            _LOGGER.error("setup failed")
            if not self._cast:
                _LOGGER.error("no cast device")
            return False
        return True

    def _setup_chromecast(self) -> bool:
        if self._chromecast_host:
            try:
                self._cast = Chromecast(host=self._chromecast_host)
                self._cast.register_handler(self)
                self._cast.wait()
                return True
            except pychromecast.error.ChromecastConnectionError:
                _LOGGER.error("cannot find {}".format(self._chromecast_host))
        elif self._chromecast_name:
            try:
                self._cast = next(
                    cc for cc in get_chromecasts()
                    if cc.device.friendly_name == self._chromecast_name)
                self._cast.register_handler(self)
                self._cast.wait()
                return True
            except StopIteration:
                _LOGGER.error("cannot find {}".format(self._chromecast_name))
        else:
            _LOGGER.error("no chromecast host or name defined.")
        return False

    @property
    def cast(self) -> Chromecast:
        """Get chromecast object or set one up if needed."""
        if not self._setup_valid:
            self._setup()
        return self._cast

    def _get_content_id(self, channel: str) -> str:
        _LOGGER.debug("getting content_id for {}".format(channel))
        r = requests.get(
            'https://nightdev.com/api/1/twitchcast/token?channel={}'.format(
                requests.utils.quote(channel)),
            headers=self._headers)
        token, sig = "", ""
        if r.status_code == 200:
            try:
                parsed_text = json.loads(r.text)
                token = parsed_text['token']
                sig = parsed_text['sig']
            except (ValueError, KeyError):
                _LOGGER.error(
                    "error parsing token and sig for {}".format(channel))
                return ""
        else:
            _LOGGER.error("status {} during token and sig for {}".format(
                r.status_code, channel))
        playlist = []  # type: List[dict]
        if token and sig:
            url = '{}/get/playlist?channel={}&token={}&sig={}&callback=?'.\
                format(
                    self._location,
                    requests.utils.quote(channel),
                    requests.utils.quote(token),
                    requests.utils.quote(sig))
            r = requests.get(url, headers=self._headers)
            if r.status_code == 200:
                try:
                    playlist = json.loads(r.text[2:-2])['playlist']
                except ValueError:
                    _LOGGER.error(
                        "error parsing playlist for {}".format(channel))
                    return ""
            else:
                _LOGGER.error("status {} during playlist for {}".format(
                    r.status_code, channel))
        else:
            return ""
        if playlist:
            return playlist[0]['url']
        else:
            return ""

    def _check_app_id(self, timeout: int = 10) -> bool:
        if not self.cast:
            return False
        if self.cast.app_id != self._expected_app_id:
            self.launch()
        for t in range(timeout * 5):
            if self.cast.app_id != self._expected_app_id:
                time.sleep(t / 5)
            else:
                return True
        return False

    def _stream_channel_callback(self, channel: str, layout: str,
                                 content_id: str) -> None:
        msg = {
            'type': 'LOAD',
            'media': {
                'contentId': content_id,
                'contentType': 'video/mp4',
                'streamType': 'LIVE',
                'metadata': self.channel_details(channel)
            },
            'mediaSessionId': None,
            'customData': {
                'channel': channel,
                'layout': layout,
            },
        }
        _LOGGER.debug("sending chromecast message {}".format(msg))
        self.send_message(msg)

    def channel_details(self, channel: str) -> dict:
        """Get stream title & details from Twitch Kraken API."""
        _LOGGER.debug("getting steam details for {}".format(channel))
        metadata = {
            'metadataType': 1,
            'title': channel,
            'subtitle': channel,
            'images': []
        }
        r = requests.get('https://api.twitch.tv/kraken/streams/{}?client_id'
                         '=apbhlybpld3ybc6grv5c118xqpoz01c'.format(
                             requests.utils.quote(channel)),
                         headers=self._headers)
        if r.status_code == 200:
            try:
                parsed_text = json.loads(r.text)['stream']['channel']
                metadata['title'] = parsed_text['display_name']
                metadata['subtitle'] = parsed_text['status']
                metadata['images'].append({
                    'url': parsed_text['logo'],
                    'width': 0,
                    'height': 0,
                })
            except (ValueError, KeyError):
                _LOGGER.error(
                    "error parsing channel details for {}".format(channel))
        else:
            _LOGGER.error("status {} during token and sig for {}".format(
                r.status_code, channel))
        return metadata

    def stream_channel(self, channel: str, layout: str) -> None:
        """Stream a channel for a given layout on the Chromecast."""
        _LOGGER.debug("trying to stream {} - {}".format(channel, layout))
        content_id = self._get_content_id(channel)
        self._launched = False
        if content_id:
            _LOGGER.debug("launching {} - {}".format(channel, layout))
            if self._check_app_id():
                self.launch(
                    callback_function=partial(self._stream_channel_callback,
                                              channel=channel,
                                              layout=layout,
                                              content_id=content_id))
            else:
                _LOGGER.error("timed out waiting on chromecast")
        else:
            _LOGGER.error("couldn't get content_id for {}".format(channel))
Пример #6
0
def main():
    import getopt
    import os
    import sys

    try:
        opts, args = getopt.getopt(
            sys.argv[1:], "vhH:l:",
            ["version", "help", "ip-addresses=", "language="])
    except getopt.GetoptError:
        print(__usage__)
        sys.exit(2)

    lang = os.getenv("GNOTIFY_LANG", "")
    ips = [ip for ip in os.getenv("GNOTIFY_IPS", "").split(',') if ip]
    tts = " ".join(args)

    for opt, arg in opts:
        if opt in ("-h", "--help"):
            print(__usage__)
            sys.exit(2)
        elif opt in ("-v", "--version"):
            print("Version: {}".format(__version__))
            sys.exit(2)
        elif opt in ("-l", "--language"):
            lang = arg
        elif opt in ("-H", "--ip-addresses"):
            ips = [ip for ip in arg.split(',') if ip]

    import re

    errors = []

    if len(ips) == 0:
        errors.append(
            'Please enter one or more ip addresses separated by commas as an option.'
        )

    if str(lang) == "":
        errors.append('Please enter a language code (ISO 639-1) as an option.')
    elif not re.match(r"^\w{2}$", lang):
        errors.append(
            'Please enter a valid language code (ISO 639-1) as an option.')

    if not tts or str(tts) == "":
        errors.append('Please enter a text-to-speech as arguments.')
    elif len(tts) > 5000:
        errors.append('The requested text-to-speech is too long (> 5000).')

    if errors:
        print(__usage__ + '\n')
        print('\n'.join(errors))
        sys.exit(2)

    import time
    from pychromecast import Chromecast
    from pychromecast.error import ChromecastConnectionError
    from socketserver import ThreadingTCPServer
    from http.server import SimpleHTTPRequestHandler
    from threading import Thread
    from cachier import cachier

    @cachier()
    def get_tts_mp3(tl, q):

        from urllib.error import HTTPError
        from urllib.parse import urlencode
        from urllib.request import Request
        from urllib.request import urlopen

        request = Request("{}?{}".format(
            "https://translate.google.com/translate_tts",
            urlencode({
                "ie": "UTF-8",
                "q": q,
                "tl": tl,
                "client": "tw-ob"
            })))
        request.add_header("Referer", "http://translate.google.com/")
        request.add_header("User-Agent", "stagefright/1.2 (Linux;Android 5.0)")

        try:
            response = urlopen(request)
        except HTTPError:
            print("Google Translate error")
            sys.exit(2)

        return response.read()

    class FileHTTPRequestHandler(SimpleHTTPRequestHandler):
        def do_GET(self):
            self.send_response(200)
            self.end_headers()
            self.wfile.write(get_tts_mp3(lang, tts))

        def log_message(self, format, *args):
            return

    for ip in ips:
        try:
            cast = Chromecast(ip)
        except ChromecastConnectionError as e:
            print(e)
            sys.exit(2)

        server_ip = cast.socket_client.socket.getsockname()[0]
        server = ThreadingTCPServer((server_ip, 0), FileHTTPRequestHandler)
        server_port = str(server.server_address[1])

        thread = Thread(target=server.serve_forever)
        thread.daemon = True
        thread.start()

        cast.wait()

        mc = cast.media_controller
        mc.play_media("http://{}:{}".format(server_ip, server_port),
                      "audio/mpeg")

        time.sleep(.5)

        while mc.status.player_state != "IDLE":
            try:
                time.sleep(0.05)
            except KeyboardInterrupt:
                mc.stop()
                break

        server.shutdown()
        server.server_close()