def get(self): # TODO: set timeout from config, blacklist this instance when retry fail output = self.queue.get(block=True) self.thread = StoppableThread(target=self._enqueue_output) self.thread.daemon = True self.thread.start() return output
def __init__(self): StoppableThread.__init__(self) Singleton.__init__(self) GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) self.config = self._read_config() self.render = web.template.render('templates')
def __init__(self, sock): self.logger = logging.getLogger(self.__class__.__name__) StoppableThread.__init__(self, name=self.__class__.__name__) self._sleep_period = 0.01 self.sock = sock self.queue = Queue.Queue()
def __init__(self, monitors, handlers, connection_manager): StoppableThread.__init__(self) print('Starting the monitoring service...') self.monitors = monitors self.handlers = handlers self.connection_manager = connection_manager self.infrastructure = dict() self.workers = []
def start_license_thread(): global LICENSE_THREAD print bgcolors.OKBLUE + '\nStarting license update thread' + bgcolors.ENDC try: # TODO: Args need to removed LICENSE_THREAD = StoppableThread(target=update_usage, name='License-Thread') LICENSE_THREAD.start() print bgcolors.OKGREEN + 'Start Done\n' + bgcolors.ENDC except Exception as e: print e
class PlayerModel(object): def __init__(self): self.adaptors = [] self.adaptor = None self.adaptorLock = Lock() self._log = "" self._player = None config = json.load(open('./config/config.json')) for k, v in config.iteritems(): if k == 'youtube': for params in v: self.adaptors.append(YoutubeMusic(params, self.log)) elif k == 'gmusic': for params in v: self.adaptors.append(GoogleMusic(params, self.log)) def log(self, *args): self._log += ' '.join(map(lambda a: unicode(a), args)) + "\n" self._log = '\n'.join(self._log.split('\n')[-10:]) def terminate(self): self.adaptorLock.acquire() if self.adaptor: self.adaptor.thread.terminate() self.ps.terminate() self._player.terminate() self.adaptorLock.release() def get(self): adaptor = random.choice(self.adaptors) self.adaptorLock.acquire() self.adaptor = adaptor self.adaptorLock.release() output = adaptor.get() if not output: return empty_response self.ps = subprocess.Popen(('ffplay', '-autoexit', '-loglevel', 'panic', '-nodisp', '-vn', '-'), stdin=subprocess.PIPE) self._player = StoppableThread(target=self.ps.communicate, kwargs={"input": output.get("audio")}) self._player.daemon = True self._player.start() return { "song_length": '%d sec' % output.get('song_length', 0), "album": output.get('album', ''), "artist": output.get('artist', ''), "title": output.get('title', ''), "song_size": "%d" % len(output.get('audio')), "message": self._log }
def get(self): adaptor = random.choice(self.adaptors) self.adaptorLock.acquire() self.adaptor = adaptor self.adaptorLock.release() output = adaptor.get() if not output: return empty_response self.ps = subprocess.Popen(('ffplay', '-autoexit', '-loglevel', 'panic', '-nodisp', '-vn', '-'), stdin=subprocess.PIPE) self._player = StoppableThread(target=self.ps.communicate, kwargs={"input": output.get("audio")}) self._player.daemon = True self._player.start() return { "song_length": '%d sec' % output.get('song_length', 0), "album": output.get('album', ''), "artist": output.get('artist', ''), "title": output.get('title', ''), "song_size": "%d" % len(output.get('audio')), "message": self._log }
def shutdown(self): print('Shutting down monitoring workers...') for worker in self.workers: worker.shutdown() StoppableThread.shutdown(self)
def __init__(self, client, node_data, monitors): StoppableThread.__init__(self) self.client = client self.node_data = node_data self.monitors = monitors
adaptors.append(GoogleMusic(params)) while True: adaptor = random.choice(adaptors) output = adaptor.get() if not output: print("output is nil") break print("song length: %d sec" % output.get('song_length', 0)) print("album:", output.get('album', '')) print("artist:", output.get('artist', '')) print("title:", output.get("title", '')) print("song size:", len(output.get('audio'))) ps = subprocess.Popen(('ffplay', '-autoexit', '-loglevel', 'panic', '-nodisp', '-vn', '-'), stdin=subprocess.PIPE) player = StoppableThread(target=ps.communicate, kwargs={"input": output.get("audio")}) player.daemon = True timer = StoppableThread(target=time_elapse, args=(output.get('song_length', 0), )) timer.daemon = True timer.start() player.start() try: player.join() except: adaptor.thread.terminate() player.terminate() timer.terminate() break timer.terminate()
class YoutubeMusic(object): def __init__(self, config, log=print): self.config = config self.credential_dir = os.path.join(os.path.expanduser('.'), '.credential') self.credential_path = os.path.join(self.credential_dir, 'credential.pkl') self.credentials = self.get_credentials() http = google_auth_httplib2.AuthorizedHttp(self.credentials, http=build_http()) self.service = discovery.build(API_SERVICE_NAME, API_VERSION, http=http) self.cache_play_list = {} self.cache_song_list = {} random.seed() self.thread = None self.queue = Queue() self.log = log self._enqueue_output() def get_credentials(self): if not os.path.exists(self.credential_dir): os.makedirs(self.credential_dir) if os.path.exists(self.credential_path): with open(self.credential_path, 'rb') as f: return cPickle.load(f) flow = InstalledAppFlow.from_client_config( self.config, SCOPE, redirect_uri='urn:ietf:wg:oauth:2.0:oob') flow.run_local_server() session = flow.authorized_session() with open(self.credential_path, 'wb') as f: cPickle.dump(session.credentials, f, cPickle.HIGHEST_PROTOCOL) return session.credentials def playlist(self): ''' example { "kind": "youtube#playlistListResponse", "etag": "ETAG", "pageInfo": { "totalResults": 7, "resultsPerPage": 25 }, "items": [ { "kind": "youtube#playlist", "etag": "ETAG", "id": "ID", "snippet": { "publishedAt": "2016-02-19T16:01:09.000Z", "channelId": "ID_STRING", "title": "TITLE", "description": "", "thumbnails": { "default": { "url": "https://i.ytimg.com/vi/pZWYqkEwChE/default.jpg", "width": 120, "height": 90 }, "medium": { "url": "https://i.ytimg.com/vi/pZWYqkEwChE/mqdefault.jpg", "width": 320, "height": 180 }, "high": { "url": "https://i.ytimg.com/vi/pZWYqkEwChE/hqdefault.jpg", "width": 480, "height": 360 }, "standard": { "url": "https://i.ytimg.com/vi/pZWYqkEwChE/sddefault.jpg", "width": 640, "height": 480 }, "maxres": { "url": "https://i.ytimg.com/vi/pZWYqkEwChE/maxresdefault.jpg", "width": 1280, "height": 720 } }, "channelTitle": "USER_NAME", "localized": { "title": "TITLE_LOCAL", "description": "" } } } ] } ''' while True: try: data = self.service.playlists().list(part='snippet', maxResults=50, mine=True).execute() result = {} for item in data.get('items', []): if item.get('id') in self.config.get('blacklist', []): continue snippet = item.get('snippet', {}) result[item.get('id', '')] = [ snippet.get('title'), snippet.get('description') ] return result except Exception as e: self.log(e) def playlistSongs(self, id): nextPageToken = "" songs = {} while True: try: data = self.service.playlistItems().list( part='snippet', maxResults=50, playlistId=id, pageToken=nextPageToken).execute() for i in data.get('items', []): snippet = i.get('snippet', {}) videoId = snippet.get('resourceId', {}).get('videoId', '') songs[videoId] = snippet.get('title', '') nextPageToken = data.get('nextPageToken', '') if nextPageToken == '': break except Exception as e: self.log(e) return songs # Deprecated def getVideoUrlHQ(self, vid): vinfo = requests.get( 'http://www.youtube.com/get_video_info?video_id=' + vid) params = parse_qs(vinfo.content) signature = parse_qs(params['probe_url'][0])['signature'][0] self.log(params['title'][0]) self.log(params['length_seconds'][0]) self.log(params['author'][0]) self.log(params.keys()) stream_map = params.get('adaptive_fmts', [''])[0] + ',' + params.get( 'url_encoded_fmt_stream_map', [''])[0] if 'rtmpe%3Dyes' in stream_map: raise Exception("rtmpe cannot be downloaded") vid_info = stream_map.split(',') for video_query in vid_info: if len(video_query) == 0: continue video = parse_qs(video_query) url = video['url'][0] if 'sig' in video: url += '&signature=' + video['sig'][0] elif 's' in video: encrypted_sig = video['s'][0] raise Exception('not implemented') return url def getVideoUrlDirect(self, vid): # blacklist webm, since most players cannot read yd = YoutubeIE(downloader=YoutubeDL(params={"quiet": True})) info = yd._real_extract('https://www.youtube.com/watch?v=%s' % vid) _max = -1 url = '' result = {} for fmt in info['formats']: if fmt.get('height', 0) > _max and result.get('ext', '') != 'webm': _max = fmt.get('height', 0) result = fmt url = fmt['url'] return url, result.get('ext', ''), info.get('duration', 0) def getAudioUrlDirect(self, vid): # only get audio format, but usually in bad quality... video = pafy.new('https://www.youtube.com/watch?v=%s' % vid) bestaudio = video.getbestaudio() self.log(bestaudio.bitrate) return bestaudio.url, bestaudio.extension, bestaudio.length def _enqueue_output(self): retry = 3 while retry > 0: retry -= 1 if not self.cache_play_list: self.cache_play_list = self.playlist() pid = random.choice(self.cache_play_list.keys()) if not self.cache_song_list.get(pid, None): self.cache_song_list[pid] = self.playlistSongs(pid) self.log("select playlist:", pid, self.cache_play_list[pid][0]) if not self.cache_song_list.get(pid): print("select fail") self.cache_play_list.pop(pid) retry += 1 continue vid = random.choice(self.cache_song_list[pid].keys()) self.log("downloading https://www.youtube.com/watch?v=" + vid) url = None ext = '' length = 0 try: url, ext, length = self.getVideoUrlDirect(vid) except Exception as e: self.log(vid + ' exract fail') try: self.log(e) except: pass self.cache_song_list[pid].pop(vid) retry += 1 continue if not url: self.log(vid + "'s video info get fail") continue result = requests.get(url, headers=HEADER) if result.status_code != 200: self.log("fail to download video") continue video = result.content if len(video) == 0: self.log(vid + ' download fail') self.cache_song_list[pid].pop(vid) retry += 1 continue output = { 'song_length': length, 'album': '', 'artist': '', 'title': self.cache_song_list[pid][vid], 'audio': video, 'song_size': len(video) } self.queue.put(output) break if retry == 0: self.log("Youtube download fail, please restart the program") self.queue.put({}) def get(self): output = self.queue.get(block=True) self.thread = StoppableThread(target=self._enqueue_output) self.thread.daeamon = True self.thread.start() return output
def get(self): output = self.queue.get(block=True) self.thread = StoppableThread(target=self._enqueue_output) self.thread.daeamon = True self.thread.start() return output
class GoogleMusic(object): def __init__(self, config, log=print): self.OAUTH_PATH = config.get('oauth_path', '/tmp/oauth.cred') self.mm = Musicmanager() if os.path.isfile(self.OAUTH_PATH): success = self.mm.login(oauth_credentials=self.OAUTH_PATH) if not success: self.mm.perform_oauth(storage_filepath=self.OAUTH_PATH, open_browser=True) else: self.mm.perform_oauth(storage_filepath=self.OAUTH_PATH, open_browser=True) random.seed() self.songs = self.mm.get_uploaded_songs() self.queue = Queue() self.thread = None self.log = log self._enqueue_output() def _enqueue_output(self): song = random.choice(self.songs) self.log("get song id" + song['id']) retry = 3 while retry > 0: try: filename, audio = self.mm.download_song(song['id']) if len(audio) == 0: self.log("audio size 0") song = random.choice(self.songs) continue filelike = StringIO.StringIO(audio) metadata = mutagen.File(filelike) output = { 'song_length': 0, 'album': '', 'artist': '', 'title': '', 'audio': audio } if metadata: output['song_length'] = metadata.info.length output['album'] = fix_name( (metadata.tags or metadata).get('TALB', dummy).text[0]) output['artist'] = fix_name( (metadata.tags or metadata).get('TPE1', dummy).text[0]) output['title'] = fix_name( (metadata.tags or metadata).get('TIT2', dummy).text[0]) self.queue.put(output) break except CallFailure: self.log("call failure") song = random.choice(self.songs) retry -= 1 if retry == 0: self.log("Google Music download fail, please restart the program") self.queue.put({}) def get(self): # TODO: set timeout from config, blacklist this instance when retry fail output = self.queue.get(block=True) self.thread = StoppableThread(target=self._enqueue_output) self.thread.daemon = True self.thread.start() return output