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
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)
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
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()
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