Skip to content

Commit

Permalink
Merge pull request #62 from athoik/master
Browse files Browse the repository at this point in the history
Add plugin for Livestation.com
  • Loading branch information
chrippa committed Dec 6, 2012
2 parents 661699d + de0e37f commit cbab745
Showing 1 changed file with 107 additions and 0 deletions.
107 changes: 107 additions & 0 deletions src/livestreamer/plugins/livestation.py
@@ -0,0 +1,107 @@
from livestreamer.stream import RTMPStream, HLSStream
from livestreamer.plugins import Plugin, PluginError, NoStreamsError
from livestreamer.utils import urlget

from time import time
import re

class Livestation(Plugin):
SWFURL = "http://beta.cdn.livestation.com/player/5.10/livestation-player.swf"
APIURL = "http://tokens.api.livestation.com/channels/{0}/tokens.json?{1}"

@classmethod
def can_handle_url(self, url):
return "livestation.com" in url

def _get_rtmp_streams(self, text):
match = re.search("streamer=(rtmp://.+?)&", text)
if not match:
raise PluginError(("No RTMP streamer found on URL {0}").format(self.url))

rtmp = match.group(1)

match = re.search("<meta content=\"(http://.+?\.swf)\?", text)
if not match:
self.logger.warning("Failed to get player SWF URL location on URL {0}", sel.url)
else:
self.SWFURL = match.group(1)
self.logger.debug("Found player SWF URL location {0}", self.SWFURL)

match = re.search("<meta content=\"(.+)\" name=\"item-id\" />", text)
if not match:
raise PluginError(("Missing channel item-id on URL {0}").format(self.url))

res = urlget(self.APIURL.format(match.group(1), time()), params=dict(output="json"))

if not isinstance(res.json, list):
raise PluginError("Stream info response is not JSON")

rtmplist = {}

for jdata in res.json:
if "stream_name" not in jdata or "type" not in jdata:
continue

if "rtmp" not in jdata["type"]:
continue

playpath = jdata["stream_name"]

if "token" in jdata and jdata["token"]:
playpath += jdata["token"]

if len(res.json) == 1:
stream_name = "live"
else:
stream_name = jdata["stream_name"]

rtmplist[stream_name] = RTMPStream(self.session, {
"rtmp": rtmp,
"pageUrl": self.url,
"swfVfy": self.SWFURL,
"playpath": playpath,
"live": True
})

return rtmplist

def _get_hls_streams(self, text):
match = re.search("\"(http://.+\.m3u8)\"", text)
if not match:
raise PluginError(("No HLS playlist found on URL {0}").format(self.url))

playlisturl = match.group(1)
self.logger.debug("Playlist URL is {0}", playlisturl)
playlist = {}

try:
playlist = HLSStream.parse_variant_playlist(self.session, playlisturl)
except IOError as err:
raise PluginError(err)

return playlist

def _get_streams(self):
res = urlget(self.url)
streams = {}

if RTMPStream.is_usable(self.session):
try:
rtmpstreams = self._get_rtmp_streams(res.text)
streams.update(rtmpstreams)
except PluginError as err:
self.logger.error("Error when fetching RTMP stream info: {0}", str(err))
else:
self.logger.warning("rtmpdump is not usable, only HLS streams will be available")

try:
hlsstreams = self._get_hls_streams(res.text)
streams.update(hlsstreams)
except PluginError as err:
self.logger.error("Error when fetching HLS stream info: {0}", str(err))

return streams


__plugin__ = Livestation

0 comments on commit cbab745

Please sign in to comment.