Пример #1
0
def play(track, immediately_play=True):
    """Play a track."""
    if track is not None:
        if track is application.track and application.stream is not None:
            stream = application.stream
        elif isinstance(track, db.URLStream):
            stream = URLStream(track.url.encode())
        elif not track.downloaded:
            try:
                url = application.api.get_stream_url(track.id)
                if track.artists[0].bio is None:
                    track.artists[0].populate(
                        application.api.get_artist_info(track.artists[0].id))
                if not config.sound['pyglet']:
                    stream = URLStream(url.encode())
                if config.storage['download'] or config.sound['pyglet']:
                    if config.sound['pyglet']:
                        download_track(url, track.path)
                        play(track, immediately_play=immediately_play)
                    else:
                        Thread(target=download_track,
                               args=[url, track.path]).start()
            except NotLoggedIn:
                return do_login(callback=play, args=[track])
        else:
            if config.sound['pyglet']:
                try:
                    stream = PygletFileStream(track.path)
                except Exception as e:
                    return do_error('Error playing track %s: %s' % (track, e))
            else:
                stream = FileStream(file=track.path)
        if not isinstance(track, db.URLStream):
            track.last_played = datetime.now()
        if stream is not application.stream and application.stream is not None:
            if config.sound['pyglet']:
                application.stream.pause()
            else:
                Thread(target=fadeout, args=[application.stream]).start()
        if immediately_play:
            stream.play(True)
            logger.info('Playing track %r.', track)
            if config.interface['notify']:
                application.frame.tb_icon.notify('Now playing %s.' % track)
        set_volume(config.system['volume'])
        set_pan(config.system['pan'])
        set_frequency(config.system['frequency'])
    else:
        track = None
        stream = None
    if application.track is not track and not isinstance(track, db.URLStream):
        Thread(target=application.frame.update_lyrics, args=[track]).start()
    application.track = track
    application.stream = stream
    application.frame.SetTitle()
    application.frame.update_labels()
    return stream
Пример #2
0
 def get_stream(self):
     """Check this track has been downloaded first."""
     assert self.id is not None
     name = '%s.mp3' % self.id
     state = backend.get_download_state(name)
     if state is DownloadStates.downloaded:
         return FileStream(file=backend.get_full_path(name))
     else:
         url = api.get_stream_url(self.id)
         if state is DownloadStates.none:
             add_job('Download track %r' % self,
                     lambda: backend.download_file(url, name))
         return URLStream(url.encode())
Пример #3
0
def on_search(value):
    if '://' not in value:
        value = 'http://' + value
    results = []
    try:
        s = URLStream(value.encode())
        results.append(StreamerTrack(None, None, None, None, url=value))
    except BassError:
        # Probably a web page. Let's see what we can see.
        r = get(value)
        s = BeautifulSoup(r.content)
        for audio in s.find_all('audio'):
            for source in audio.find_all('source'):
                results.append(
                    StreamerTrack(None, None, None, None, url=source['src']))
    return results
Пример #4
0
 def get_stream(self):
     """Get the stream associated with this station."""
     url = stream_url + self.url
     logger.info('Downloading stream information from %s.', url)
     r = get(url)
     if not r.ok:
         raise SomaError('%d error.' % r.status_code)
     scp = SafeConfigParser()
     scp.read_string(r.content.decode())
     section = scp['playlist']
     n = section.getint('numberofentries')
     for i in range(n):
         key = 'File%d' % n
         try:
             return URLStream(section.get(key).encode())
         except Exception as e:
             logger.warning('Failed to get %s of %r:', key, section)
             logger.exception(e)
     logger.critical('No stream URL found in %d entries for station %r.', n,
                     self)
     raise SomaError('No stream URL found.')
Пример #5
0
 def do_load(self, event):
     """OK button was clicked."""
     frame = application.main_frame
     url = self.url.GetValue().strip()
     title = self.title.GetValue().strip() or url
     logger.info('Playing URL "%s" from url %s.', title, url)
     try:
         s = URLStream(url)
         result = [title, url]
         if result not in self._streams:
             self._streams.append(result)
         if frame.current_track:
             frame.current_track.stop()
         frame.current_track = s
         frame.duration = 0.0
         frame.set_volume()
         frame.set_pan()
         frame.set_frequency()
         frame.SetTitle(title)
         frame.current_track.play()
         self.Close(True)
     except BassError as e:
         return wx.MessageBox(str(e), 'Error', style=wx.ICON_EXCLAMATION)
Пример #6
0
 def get_stream(self):
     return URLStream(self.title.encode())
Пример #7
0
 def play(self, item, history = True, play = True):
  """
  Plays the track given in item.
  
  If history is True, add any current track to the history.
  If play is True, play the track immediately.
  """
  logger.debug('Playing item: %s.', item)
  id = functions.get_id(item)
  track = None # The object to store the track in until it's ready for playing.
  error = None # Any error that occured.
  if id in library.downloaded: # The file has already been downloaded.
   try:
    track = FileStream(file = library.get_path(item))
    if self.current_library and item in self.current_library:
     new_item = copy(item)
     if 'playCount' in new_item:
      new_item['playCount'] += 1
     self.current_library[self.current_library.index(item)] = new_item # Save it with the modified play count so the poll thread doesn't screw anything up.
   except BassError as e:
    del library.downloaded[id]
    return self.play(item, history = history, play = play) # Try again... File's probably not there or something...
  else:
   if id in library.downloading:
    if time() - library.downloading[id] <= config.config.get('library', 'download_timeout'):
     return wx.MessageBox('This song is still downloading, please wait.', 'Download In Progress')
    else:
     del library.downloading[id]
   try:
    url = application.mobile_api.get_stream_url(id)
   except gmusicapi.exceptions.CallFailure as e:
    application.device_id = None
    return wx.MessageBox('Cannot play with that device: %s.' % e, 'Invalid Device')
   except functions.RE as e:
    if self.current_track:
     self.current_track.set_position(self.current_track.get_length() - 1)
     self.play_pause.SetLabel(config.config.get('windows', 'play_label'))
    return wx.MessageBox(*functions.format_requests_error(e))
   try:
    track = URLStream(url = url)
   except BassError as e:
    error = e # Just store it for later alerting.
   if config.config.get('library', 'cache'): # The user wants their tracks downloaded.
    Thread(target = functions.download_file, args = [url, id, item]).start()
  if error:
   return wx.MessageBox(str(e), 'Error')
  if self.current_track:
   self.current_track.stop()
   if history:
    self.add_history(self.get_current_track())
  self._current_track = item
  if application.lyrics_frame:
   Thread(target = application.lyrics_frame.populate_lyrics, args = [item.get('artist'), item.get('title')]).start()
  self.current_track = track
  self.SetTitle()
  self.duration = columns.parse_durationMillis(self.get_current_track().get('durationMillis'))
  self.update_hotkey_area()
  self.set_volume()
  self.set_pan()
  self.set_frequency()
  if play:
   self.current_track.play()
   self.play_pause.SetLabel(config.config.get('windows', 'pause_label'))
  else:
   self.play_pause.SetLabel(config.config.get('windows', 'play_label'))
  filename = os.path.join(application.artwork_directory, item['albumId'] + '.jpg')
  if filename != self.album_art_filename:
   if filename in os.listdir(application.artwork_directory):
    logger.debug('Loading album art from cache.')
   else:
    url = item['albumArtRef'][0]['url']
    logger.debug('Downloading album art from %s.', url)
    art = requests.get(url)
    with open(filename, 'wb') as f:
     f.write(art.content)
   self.album_art_filename = filename
   i = wx.Image(filename)
   self.album_art.SetBitmap(i.ConvertToBitmap())
   i.Destroy()
   logger.info('Loaded album art from %s.', filename)
  try:
   Thread(target = application.mobile_api.increment_song_playcount, args = [id]).start()
   self.artist_info = application.mobile_api.get_artist_info(item['artistId'][0])
   try:
    self.set_artist_bio(self.artist_info.get('artistBio', 'No information available.'))
   except wx.PyDeadObjectError:
    pass # The frame has been deleted.
  except functions.RE:
   pass # We are not connected to the internet, but we can still play stuff.