From edfc2de50a4a15fc883a57dffed1e1ae60e93fc9 Mon Sep 17 00:00:00 2001 From: Christopher Rosell Date: Wed, 21 Mar 2012 22:49:15 +0100 Subject: Make livestreamer more usable as a library. --- src/livestreamer/__init__.py | 2 +- src/livestreamer/cli.py | 6 +++--- src/livestreamer/plugins/__init__.py | 1 + src/livestreamer/plugins/justintv.py | 14 ++++++++++---- src/livestreamer/stream.py | 28 +++++++++++++++++++++++++--- 5 files changed, 40 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/livestreamer/__init__.py b/src/livestreamer/__init__.py index 7b5a628..6a0b463 100644 --- a/src/livestreamer/__init__.py +++ b/src/livestreamer/__init__.py @@ -10,7 +10,7 @@ def resolve_url(url): for name, plugin in plugins.get_plugins().items(): if plugin.can_handle_url(url): obj = plugin(url) - return (name, obj) + return obj return None def get_plugins(): diff --git a/src/livestreamer/cli.py b/src/livestreamer/cli.py index c395319..6187f39 100644 --- a/src/livestreamer/cli.py +++ b/src/livestreamer/cli.py @@ -19,12 +19,12 @@ def exit(msg): sys.exit() def handle_url(args): - (pluginname, plugin) = livestreamer.resolve_url(args.url) + channel = livestreamer.resolve_url(args.url) - if not plugin: + if not channel: exit(("No plugin can handle url: {0}").format(args.url)) - streams = plugin.get_streams() + streams = channel.get_streams() if not streams: exit(("No streams found on url: {0}").format(args.url)) diff --git a/src/livestreamer/plugins/__init__.py b/src/livestreamer/plugins/__init__.py index a989799..cf6954b 100644 --- a/src/livestreamer/plugins/__init__.py +++ b/src/livestreamer/plugins/__init__.py @@ -8,6 +8,7 @@ plugins_loaded = {} class Plugin(object): def __init__(self, url): self.url = url + self.args = None @classmethod def can_handle_url(self, url): diff --git a/src/livestreamer/plugins/justintv.py b/src/livestreamer/plugins/justintv.py index 8db4db4..b21f9a4 100644 --- a/src/livestreamer/plugins/justintv.py +++ b/src/livestreamer/plugins/justintv.py @@ -13,6 +13,8 @@ class JustinTV(Plugin): MetadataURL = "http://www.justin.tv/meta/{0}.xml?on_site=true" SWFURL = "http://www.justin.tv/widgets/live_embed_player.swf" + cookie = None + @classmethod def can_handle_url(self, url): return ("justin.tv" in url) or ("twitch.tv" in url) @@ -21,6 +23,10 @@ class JustinTV(Plugin): def handle_parser(self, parser): parser.add_argument("--jtv-cookie", metavar="cookie", help="JustinTV cookie to allow access to subscription channels") + @classmethod + def handle_args(self, args): + self.cookie = args.jtv_cookie + def _get_channel_name(self, url): fd = urllib.urlopen(url) data = fd.read() @@ -30,9 +36,9 @@ class JustinTV(Plugin): if match: return str(match.group(1), "ascii") - def _get_metadata(self, channel, cookie=None): - if cookie: - headers = {"Cookie": cookie} + def _get_metadata(self, channel): + if self.cookie: + headers = {"Cookie": self.cookie} req = urllib.Request(self.MetadataURL.format(channel), headers=headers) else: req = urllib.Request(self.MetadataURL.format(channel)) @@ -76,7 +82,7 @@ class JustinTV(Plugin): if not channelname: return False - metadata = self._get_metadata(channelname, self.args.jtv_cookie) + metadata = self._get_metadata(channelname) if "chansub_guid" in metadata: fd = urllib.urlopen(self.StreamInfoURLSub.format(channelname, randomp, metadata["chansub_guid"])) diff --git a/src/livestreamer/stream.py b/src/livestreamer/stream.py index 4893172..c2b5658 100644 --- a/src/livestreamer/stream.py +++ b/src/livestreamer/stream.py @@ -1,14 +1,35 @@ from livestreamer.utils import CommandLine +import subprocess, shlex + class Stream(object): def __init__(self, params={}): self.params = params + self.process = None + + def open(self): + if self.process: + self.close() + + cmdline = self.cmdline().format() + args = shlex.split(cmdline) + + self.process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + def read(self, *args): + if self.process: + return self.process.stdout.read(*args) + + def close(self): + if self.process: + self.process.kill() + self.process = None - def cmdline(self, out): + def cmdline(self, out=None): raise NotImplementedError class RTMPStream(Stream): - def cmdline(self, out): + def cmdline(self, out=None): cmd = CommandLine("rtmpdump") for key, value in self.params.items(): @@ -18,6 +39,7 @@ class RTMPStream(Stream): cmd.args[key] = value - cmd.args["flv"] = out + if out: + cmd.args["flv"] = out return cmd -- cgit v1.2.3