示例#1
0
class YoutubeCastController(CastController, MediaControllerMixin, PlaybackBaseMixin):
    def __init__(self, cast, app, prep=None):
        self._controller = YouTubeController()
        super(YoutubeCastController, self).__init__(cast, app, prep=prep)
        self.info_type = "id"
        self.save_capability = "partial"
        self.playlist_capability = "complete"

    def play_media_id(self, video_id):
        self._controller.play_video(video_id)

    def play_playlist(self, playlist_id, video_id):
        self.clear()
        self._controller.play_video(video_id, playlist_id)

    def add(self, video_id):
        # You can't add videos to the queue while the app is buffering.
        self.wait_for(["BUFFERING"], invert=True)
        self._controller.add_to_queue(video_id)

    def add_next(self, video_id):
        self.wait_for(["BUFFERING"], invert=True)
        self._controller.play_next(video_id)

    def remove(self, video_id):
        self.wait_for(["BUFFERING"], invert=True)
        self._controller.remove_video(video_id)

    def clear(self):
        self._controller.clear_playlist()

    def restore(self, data):
        self.play_media_id(data["content_id"])
        self.wait_for(["PLAYING"])
        self.seek(data["current_time"])
示例#2
0
class YoutubeCastController(CastController, MediaControllerMixin, PlaybackBaseMixin):
    def __init__(self, cast, app, prep=None):
        self._controller = YouTubeController()
        super(YoutubeCastController, self).__init__(cast, app, prep=prep)
        self.info_type = "id"
        self.save_capability = "partial"
        self.playlist_capability = "complete"

    def play_media_id(self, video_id):
        self._controller.play_video(video_id)

    def play_playlist(self, playlist_id, video_id):
        self.clear()
        self._controller.play_video(video_id, playlist_id)

    def add(self, video_id):
        # You can't add videos to the queue while the app is buffering.
        self.wait_for(["BUFFERING"], invert=True)
        self._controller.add_to_queue(video_id)

    def add_next(self, video_id):
        self.wait_for(["BUFFERING"], invert=True)
        self._controller.play_next(video_id)

    def remove(self, video_id):
        self.wait_for(["BUFFERING"], invert=True)
        self._controller.remove_video(video_id)

    def clear(self):
        self._controller.clear_playlist()

    def restore(self, data):
        self.play_media_id(data["content_id"])
        self.wait_for(["PLAYING"])
        self.seek(data["current_time"])
def main():
    chromecasts, browser = pychromecast.get_listed_chromecasts(
        friendly_names=[CAST_NAME])
    if not chromecasts:
        print('No chromecast with name "{}" discovered'.format(args.cast))
        sys.exit(1)

    cast = chromecasts[0]
    # Start socket client's worker thread and wait for initial status update
    cast.wait()

    # Create Youtube Controller + Register it
    yt = YouTubeController()
    cast.register_handler(yt)

    # Create a new Youtube Session
    yt.start_session_if_none()
    s1 = yt._session
    s1._start_session()

    # Initialize the Queue to play
    s1._initialize_queue(VIDEO_LIST[0])

    print("Queue Play Order: ")
    print("1. " + VIDEO_LIST[0])
    order = 2

    # Add wanted video id's to the Queue
    for id in VIDEO_LIST[1:]:
        print(str(order) + ". " + id)
        yt.add_to_queue(id)
        order += 1
示例#4
0
def cast(postDict, cast):
    i = 1
    chromecasts = pychromecast.get_chromecasts()
    cast = next(cc for cc in chromecasts if cc.device.friendly_name == cast)
    cast.wait()
    yt = YouTubeController()
    for value in postDict['url']:
        cast.register_handler(yt)
        video = get_ID(postDict['url'][i])
        if not (yt._screen_id and yt._session):
            yt.play_video(video)
            print('Casting: ' + postDict['title'][i])

        else:
            yt.add_to_queue(video)
            print('Queueing: ' + postDict['title'][i])

        i += 1
        time.sleep(5)
示例#5
0
cast.register_handler(yt)
reddit = praw.Reddit(client_id=os.getenv("CLIENT_ID"),
                     client_secret=os.getenv("CLIENT_SECRET"),
                     username=os.getenv("REDDIT_USERNAME"),
                     password=os.getenv("REDDIT_PASSWORD"),
                     user_agent="youtube_haiku_bot")
for submission in reddit.subreddit('youtubehaiku').hot(limit=25):
    if submission.spoiler and not args.show_spoilers:
        continue
    link = submission.url
    VIDEO_ID = ""
    if "youtu.be" in link:
        # resolve youtu.be urls
        r = requests.get(link)
        link = r.url
    if "youtube.com" in link:
        v_spot = link.find("v=")
        just_params = link[v_spot + 2:]
        VIDEO_ID = just_params
        amp = VIDEO_ID.find("&")
        if amp != -1:
            VIDEO_ID = VIDEO_ID[:amp]
    if VIDEO_ID != "":
        if played_yet:
            yt.add_to_queue(VIDEO_ID)
        else:
            played_yet = True
            yt.play_video(VIDEO_ID)
        print(VIDEO_ID)
# Change to the name of your Chromecast
示例#6
0
class ChromecastWrapper(Wrapper):
  """
  A wrapper to make it easier to switch out backend implementations.

  Holds common logic for dealing with underlying Chromecast API.
  """

  def __init__(self, cc: Chromecast):
    self.cc = cc
    self.yt_ctl = YouTubeController()
    self.cc.register_handler(self.yt_ctl)

  def __getattr__(self, name: str) -> Any:
    return getattr(self.cc, name)

  def __repr__(self) -> str:
    return f"<{self.__name__} for {self.cc}>"

  @property
  def cast_status(self) -> Union[CastStatus, ReturnsNone]:
    if self.cc.status:
      return self.cc.status

    return ReturnsNone()

  @property
  def media_status(self) -> Union[MediaStatus, ReturnsNone]:
    if self.cc.media_controller.status:
      return self.cc.media_controller.status

    return ReturnsNone()

  def can_play_next(self) -> Optional[bool]:
    if self.media_status:
      return self.media_status.supports_queue_next

    return False

  def can_play_prev(self) -> Optional[bool]:
    if self.media_status:
      return self.media_status.supports_queue_prev

    return False

  def play_next(self):
    self.cc.media_controller.queue_next()

  def play_prev(self):
    self.cc.media_controller.queue_prev()

  def can_pause(self) -> Optional[bool]:
    return self.media_status.supports_pause

  def can_seek(self) -> Optional[bool]:
    return self.media_status.supports_seek

  def quit(self):
    self.cc.quit_app()

  def get_current_position(self) -> Microseconds:
    position_secs = self.media_status.adjusted_current_time

    if position_secs:
      return int(position_secs * US_IN_SEC)

    return BEGINNING

  def next(self):
    self.cc.play_next()

  def previous(self):
    self.cc.play_previous()

  def pause(self):
    self.cc.media_controller.pause()

  def resume(self):
    self.play()

  def stop(self):
    self.cc.media_controller.stop()

  def play(self):
    self.cc.media_controller.play()

  def get_playstate(self) -> PlayState:
    if self.cc.media_controller.is_paused:
      return PlayState.PAUSED

    elif self.cc.media_controller.is_playing:
      return PlayState.PLAYING

    return PlayState.STOPPED

  def seek(self, time: Microseconds):
    seconds = int(round(time / US_IN_SEC))
    self.cc.media_controller.seek(seconds)

  def open_uri(self, uri: str):
    video_id = get_video_id(uri)

    if video_id:
      self.play_youtube(video_id)
      return

    mimetype, _ = guess_type(uri)
    self.cc.media_controller.play_media(uri, mimetype)

  def is_repeating(self) -> bool:
    return False

  def is_playlist(self) -> bool:
    return self.can_go_next() or self.can_go_previous()

  def set_repeating(self, val: bool):
    pass

  def set_loop_status(self, val: str):
    pass

  def get_rate(self) -> RateDecimal:
    return DEFAULT_RATE

  def set_rate(self, val: RateDecimal):
    pass

  def get_shuffle(self) -> bool:
    return False

  def set_shuffle(self, val: bool):
    return False

  def get_art_url(self, track: int = None) -> str:
    thumb = self.media_controller.thumbnail
    return thumb if thumb else DEFAULT_THUMB

  def get_volume(self) -> VolumeDecimal:
    return self.cast_status.volume_level

  def set_volume(self, val: VolumeDecimal):
    curr = self.get_volume()
    diff = val - curr

    # can't adjust vol by 0
    if diff > NO_DELTA:  # vol up
      self.cc.volume_up(diff)

    elif diff < NO_DELTA:
      self.cc.volume_down(abs(diff))

  def is_mute(self) -> Optional[bool]:
    if self.cast_status:
      return self.cast_status.volume_muted

    return False

  def set_mute(self, val: bool):
    self.cc.set_volume_muted(val)

  def get_stream_title(self) -> str:
    title = self.cc.media_controller.title
    metadata = self.media_status.media_metadata

    if metadata and 'subtitle' in metadata:
      title = ' - '.join((title, metadata['subtitle']))

    return title

  def get_duration(self) -> Microseconds:
    duration = self.media_status.duration

    if duration:
      duration *= US_IN_SEC

    else:
      duration = NO_DURATION

    return duration

  def metadata(self) -> Metadata:
    title: str = self.get_stream_title()
    dbus_name: DbusObj = get_track_id(title)

    artist: Optional[str] = self.media_status.artist
    artists: List[str] = [artist] if artist else []
    comments: List[str] = []

    metadata = {
      "mpris:trackid": dbus_name,
      "mpris:length": self.get_duration(),
      "mpris:artUrl": self.get_art_url(),
      "xesam:url": self.media_status.content_id,
      "xesam:title": title,
      "xesam:artist": artists,
      "xesam:album": self.media_status.album_name,
      "xesam:albumArtist": artists,
      "xesam:discNumber": DEFAULT_DISC_NO,
      "xesam:trackNumber": self.media_status.track,
      "xesam:comment": comments,
    }

    return metadata

  def get_current_track(self) -> Track:
    art_url = self.get_art_url()
    content_id = self.media_status.content_id
    name = self.media_status.artist
    duration = int(self._get_duration())
    title = self.get_stream_title()
    artist = Artist(name)

    album = Album(
      name=self.media_status.album_name,
      artists=(artist,),
      art_url=art_url,
    )

    track = Track(
      track_id=get_track_id(title),
      name=title,
      track_no=self.media_status.track,
      length=duration,
      uri=content_id,
      artists=(artist,),
      album=album,
      art_url=art_url,
      disc_no=DEFAULT_DISC_NO,
      type=get_media_type(self.cc)
    )

    return track

  def get_desktop_entry(self) -> str:
    return str(Path(DESKTOP_FILE).absolute())

  def launch_youtube(self):
    self.yt_ctl.launch()

  def play_youtube(self, video_id: str):
    if not self.yt_ctl.is_active:
      self.launch_youtube()

    self.yt_ctl.play_video(video_id)

  def add_track(
    self,
    uri: str,
    after_track: DbusObj,
    set_as_current: bool
  ):
    video_id = get_video_id(uri)

    if video_id:
      self.yt_ctl.add_to_queue()
示例#7
0
def main():

    os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

    PLAYLIST = {}

    # Authenticate OAuth2 with Google
    creds = client.GoogleCredentials(access_token=None,
                                     client_id=CLIENT_ID,
                                     client_secret=CLIENT_SECRET,
                                     refresh_token=REFRESH_TOKEN,
                                     token_expiry=None,
                                     token_uri=TOKEN_URI,
                                     user_agent=USER_AGENT)

    http = creds.authorize(httplib2.Http())
    creds.refresh(http)

    # Build the service
    youtube = build(API_SERVICE_NAME, API_VERSION, http=http)

    # Randomize Playlists
    # Comment this line if you don't want randomized playlists
    random.shuffle(SERIAL_LIST)

    # Loop through each playlist
    for serials in SERIAL_LIST:

        # Retrieve video's JSON values
        request = youtube.playlistItems().list(part="snippet,contentDetails",
                                               maxResults=10,
                                               playlistId=serials)

        response = request.execute()

        # Get a list of playlist items
        list_of_videos = response.get('items')
        video_ids = []

        # For each playlist item, get the corresponding video id
        for vids in list_of_videos:
            content_details = vids.get('contentDetails')
            snippet = vids.get('snippet')
            # Region blocking, age-restriction, deleted vid - maybe, later ....

            # Check if video is private
            if snippet.get('title') != "Private video":
                video_ids.append(content_details.get('videoId'))

        PLAYLIST[serials] = video_ids

    # Combine all video id's together into Queue
    # Plays the videos in playlist in order
    x = PLAYLIST.values()
    queue = [j for i in x for j in i][::-1]

    # If you want to randomize the videos, uncomment below
    # random.shuffle(queue)

    cast = None

    # Keep trying to connect until wanted chromecast is online
    while (cast == None):
        chromecasts, browsers = pychromecast.get_chromecasts()
        try:
            # Loop through all the chromecasts in the house
            cast = next(cc for cc in chromecasts
                        if cc.device.friendly_name == CAST_NAME)
        except:
            print("Chromecast Not Found")

    cast.wait()

    # Create Youtube Controller + Register it
    yt = YouTubeController()
    cast.register_handler(yt)

    # Create a new Youtube Session
    yt.start_session_if_none()
    s1 = yt._session
    s1._start_session()

    # Initialize the Queue to play
    s1._initialize_queue(queue[0])

    print("Queue Play Order: ")
    print("1. " + queue[0])
    order = 2

    # Add wanted video id's to the Queue
    for id in queue[1:]:
        print(str(order) + ". " + id)
        yt.add_to_queue(id)
        order += 1