Skip to content

Commit

Permalink
try to parse pls stream
Browse files Browse the repository at this point in the history
  • Loading branch information
xiongyihui committed Dec 29, 2017
1 parent 96aec30 commit 8e088ad
Showing 1 changed file with 62 additions and 46 deletions.
108 changes: 62 additions & 46 deletions avs/interface/audio_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,74 @@
import hashlib
import requests
import logging
from contextlib import closing
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse


from avs.player import Player

logger = logging.getLogger('AudioPlayer')


# TODO: parse M3U8 and PLSv2
# refer to https://github.com/alexa/avs-device-sdk/blob/master/PlaylistParser/src/PlaylistParser.cpp
def get_audio_url(audio_url, timeout=3000):
timeout = timeout / 1000.
if audio_url.startswith('cid:'):
filename = base64.urlsafe_b64encode(audio_url[4:])
filename = hashlib.md5(filename).hexdigest()
mp3_file = os.path.join(tempfile.gettempdir(), filename + '.mp3')
if os.path.isfile(mp3_file):
return 'file://{}'.format(mp3_file)
else:
logger.warn('Unable to parse {}'.format(audio_url))
return None

if audio_url.find('radiotime.com') >= 0:
logger.debug('parse TuneIn audio stream: {}'.format(audio_url))

try:
response = requests.get(audio_url, timeout=timeout)
lines = response.content.decode().split('\n')
# audio/x-mpegurl; charset=utf-8
content_type = response.headers['Content-Type']
logger.debug(content_type)
logger.debug(lines)
if lines and lines[0]:
audio_url = lines[0]
logger.debug('Set audio_url to {}'.format(audio_url))
if content_type.find('audio/x-mpegurl'):
return audio_url
except Exception:
pass

extension = urlparse(audio_url).path[-4:]
if extension in ['.mp3', '.wma']:
logger.debug('Found audio stream {}'.format(audio_url))
return audio_url

logger.debug('Parse stream: {}'.format(audio_url))
with closing(requests.get(audio_url, timeout=timeout, stream=True)) as response:
content_type = response.headers['Content-Type'] or ''
if content_type.find('pls') >= 0:
try:
logger.debug('parsing playlist: {}'.format(audio_url))
lines = response.content.decode().split('\n')
logger.debug(lines)
for line in lines:
if line.find('File') == 0:
audio_url = lines[2].split('=', 2)[1]
logger.debug('Set audio_url to {}'.format(audio_url))
break
except Exception:
pass

return audio_url


class AudioPlayer(object):
STATES = {'IDLE', 'PLAYING', 'STOPPED', 'PAUSED', 'BUFFER_UNDERRUN', 'FINISHED'}

Expand Down Expand Up @@ -63,52 +125,6 @@ def Play(self, directive):
self.player.play(audio_url)
self.PlaybackStarted()


# -- Return a cleaned up, playable URL, for the returned URL...
#
def get_audio_url(audio_url):
if audio_url.startswith('cid:'):
filename = base64.urlsafe_b64encode(audio_url[4:])
filename = hashlib.md5(filename).hexdigest()
mp3_file = os.path.join(tempfile.gettempdir(), filename + '.mp3')
if os.path.isfile(mp3_file):
return 'file://{}'.format(mp3_file)
else:
logger.warn('Unable to parse %s' % (audio_url))
return None

if audio_url.find('radiotime.com') >= 0:
logger.debug('parse TuneIn audio stream: {}'.format(audio_url))

try:
response = requests.get(audio_url)
lines = response.content.decode().split('\n')
logger.debug(lines)
if lines and lines[0]:
audio_url = lines[0]
logger.debug('Set audio_url to [%s]' % (audio_url))
except Exception:
pass

response = requests.head(audio_url)
contentType = response.headers['Content-Type'] or ''
if contentType.find('pls') >= 0:
try:
logger.debug('parsing playlist: {}'.format(audio_url))
response = requests.get(audio_url)
lines = response.content.decode().split('\n')
logger.debug(lines)
for line in lines:
if line.find('File') == 0:
audio_url = lines[2].split('=', 2)[1]
logger.debug('Set audio_url to [%s]' % (audio_url))
break
except Exception:
pass

return audio_url


def PlaybackStarted(self):
self.state = 'PLAYING'

Expand Down

0 comments on commit 8e088ad

Please sign in to comment.