[arch-commits] Commit in livestreamer/trunk (2 files)
Evangelos Foutras
foutrelis at archlinux.org
Sun Feb 8 16:16:01 UTC 2015
Date: Sunday, February 8, 2015 @ 17:16:00
Author: foutrelis
Revision: 127300
upgpkg: livestreamer 1.11.1-2
Add upstream fix for the hitbox plugin.
Added:
livestreamer/trunk/plugins-hitbox-Refactor-to-use-the-StreamMapper.patch
Modified:
livestreamer/trunk/PKGBUILD
-------------------------------------------------------+
PKGBUILD | 15 -
plugins-hitbox-Refactor-to-use-the-StreamMapper.patch | 197 ++++++++++++++++
2 files changed, 209 insertions(+), 3 deletions(-)
Modified: PKGBUILD
===================================================================
--- PKGBUILD 2015-02-08 14:20:49 UTC (rev 127299)
+++ PKGBUILD 2015-02-08 16:16:00 UTC (rev 127300)
@@ -3,7 +3,7 @@
# Contributor: Christopher Rosell <chrippa at tanuki.se>
pkgname=livestreamer
pkgver=1.11.1
-pkgrel=1
+pkgrel=2
pkgdesc='CLI program that launches streams from various streaming services in a custom video player'
arch=('any')
url='https://github.com/chrippa/livestreamer'
@@ -10,9 +10,18 @@
license=('BSD')
depends=('python-requests' 'rtmpdump' 'python-setuptools')
makedepends=('python-sphinx')
-source=(https://pypi.python.org/packages/source/l/$pkgname/$pkgname-$pkgver.tar.gz)
-sha256sums=('84dd83d301518ffcf96f30cbffc0e0598e0756e7ab8e7498d11285d42fe17f9c')
+source=(https://pypi.python.org/packages/source/l/$pkgname/$pkgname-$pkgver.tar.gz
+ plugins-hitbox-Refactor-to-use-the-StreamMapper.patch)
+sha256sums=('84dd83d301518ffcf96f30cbffc0e0598e0756e7ab8e7498d11285d42fe17f9c'
+ '1a305add9db98912f0cdb16862d1296588b2ed299587de26d93c5be53f9fd572')
+prepare() {
+ cd "$srcdir/$pkgname-$pkgver"
+
+ # https://github.com/chrippa/livestreamer/issues/648
+ patch -Np1 -i ../plugins-hitbox-Refactor-to-use-the-StreamMapper.patch
+}
+
build() {
cd "$srcdir/$pkgname-$pkgver"
python setup.py build_sphinx -b man
Added: plugins-hitbox-Refactor-to-use-the-StreamMapper.patch
===================================================================
--- plugins-hitbox-Refactor-to-use-the-StreamMapper.patch (rev 0)
+++ plugins-hitbox-Refactor-to-use-the-StreamMapper.patch 2015-02-08 16:16:00 UTC (rev 127300)
@@ -0,0 +1,197 @@
+From 3cd7f604b9f3327f7626b719a3035c47a68ea9a2 Mon Sep 17 00:00:00 2001
+From: Christopher Rosell <chrippa at tanuki.se>
+Date: Tue, 16 Dec 2014 23:03:17 +0100
+Subject: [PATCH] plugins.hitbox: Refactor to use the StreamMapper.
+
+Also add support for HLS streams.
+
+Resolves #648.
+---
+ src/livestreamer/plugins/hitbox.py | 139 ++++++++++++++++++++++++-------------
+ 1 file changed, 92 insertions(+), 47 deletions(-)
+
+diff --git a/src/livestreamer/plugins/hitbox.py b/src/livestreamer/plugins/hitbox.py
+index 306a318..556a3d9 100644
+--- a/src/livestreamer/plugins/hitbox.py
++++ b/src/livestreamer/plugins/hitbox.py
+@@ -1,10 +1,13 @@
+ import re
+
++from itertools import chain
++
+ from livestreamer.compat import urlparse
+ from livestreamer.plugin import Plugin
+-from livestreamer.plugin.api import http, validate
++from livestreamer.plugin.api import StreamMapper, http, validate
+ from livestreamer.stream import HLSStream, HTTPStream, RTMPStream
+
++HLS_PLAYLIST_BASE = "http://www.hitbox.tv{0}"
+ LIVE_API = "http://www.hitbox.tv/api/media/live/{0}?showHidden=true"
+ PLAYER_API = "http://www.hitbox.tv/api/player/config/{0}/{1}?embed=false&showHidden=true"
+ SWF_BASE = "http://edge.vie.hitbox.tv/static/player/flowplayer/"
+@@ -43,7 +46,7 @@
+ validate.filter(lambda b: b.get("url") and b.get("label")),
+ [{
+ "label": validate.text,
+- "url": validate.text
++ "url": validate.text,
+ }],
+ )
+ },
+@@ -52,15 +55,20 @@
+ validate.optional("netConnectionUrl"): validate.text,
+ validate.optional("bitrates"): [{
+ "label": validate.text,
+- "url": validate.text
++ "url": validate.text,
++ "provider": validate.text
+ }]
+ }],
+- "plugins": {
+- validate.optional("clustering"): {
+- "netConnectionUrl": validate.text,
+- "url": validate.text
++ "plugins": validate.all(
++ dict,
++ validate.filter(lambda k, v: k in ["rtmp", "rtmpHitbox", "hls"]),
++ {
++ validate.text: {
++ validate.optional("netConnectionUrl"): validate.text,
++ "url": validate.text
++ }
+ }
+- }
++ )
+ }
+ )
+
+@@ -77,6 +85,79 @@ def _get_quality(self, label):
+
+ return "live"
+
++ def _create_hls_streams(self, bitrate):
++ url = bitrate["url"]
++ quality = self._get_quality(bitrate["label"])
++
++ if not url.startswith("http"):
++ url = HLS_PLAYLIST_BASE.format(url)
++
++ if bitrate["label"] == "Auto":
++ try:
++ streams = HLSStream.parse_variant_playlist(self.session, url)
++ return streams.items()
++ except IOError as err:
++ self.logger.warning("Failed to extract HLS streams: {0}", err)
++ else:
++ return quality, HLSStream(self.session, url)
++
++ def _create_rtmp_stream(self, rtmp, swf_url, bitrate):
++ quality = self._get_quality(bitrate["label"])
++ url = bitrate["url"]
++ stream = RTMPStream(self.session, {
++ "rtmp": rtmp,
++ "pageUrl": self.url,
++ "playpath": url,
++ "swfVfy": swf_url,
++ "live": True
++ })
++
++ return quality, stream
++
++ def _get_live_streams(self, player):
++ mappers = []
++ swf_url = SWF_URL
++ for playlist in player.get("playlist", []):
++ bitrates = playlist.get("bitrates")
++ provider = playlist.get("connectionProvider")
++ rtmp = None
++
++ if bitrates:
++ rtmp = playlist.get("netConnectionUrl")
++ elif provider and provider in player["plugins"]:
++ provider = player["plugins"][provider]
++ swf_name = provider["url"]
++ swf_url = SWF_BASE + swf_name
++ rtmp = provider["netConnectionUrl"]
++ bitrates = player["clip"]["bitrates"]
++ else:
++ continue
++
++ mapper = StreamMapper(
++ cmp=lambda provider, bitrate: bitrate["provider"].startswith(provider)
++ )
++ mapper.map("hls", self._create_hls_streams)
++ mapper.map("rtmp", self._create_rtmp_stream, rtmp, swf_url)
++ mappers.append(mapper(bitrates))
++
++ return chain.from_iterable(mappers)
++
++ def _create_video_stream(self, cls, base_url, bitrate):
++ url = base_url + "/" + bitrate["url"]
++ quality = self._get_quality(bitrate["label"])
++ return quality, cls(self.session, url)
++
++ def _get_video_streams(self, player):
++ base_url = player["clip"]["baseUrl"] or VOD_BASE_URL
++ mapper = StreamMapper(
++ cmp=lambda ext, bitrate: urlparse(bitrate["url"]).path.endswith(ext)
++ )
++ mapper.map(".m3u8", self._create_video_stream, HLSStream, base_url)
++ mapper.map(".mp4", self._create_video_stream, HTTPStream, base_url)
++ mapper.map(".flv", self._create_video_stream, HTTPStream, base_url)
++
++ return mapper(player["clip"]["bitrates"])
++
+ def _get_streams(self):
+ match = _url_re.match(self.url)
+ if not match:
+@@ -96,46 +177,10 @@ def _get_streams(self):
+
+ res = http.get(PLAYER_API.format(media_type, media_id))
+ player = http.json(res, schema=_player_schema)
++
+ if media_type == "live":
+- swf_url = SWF_URL
+- for playlist in player.get("playlist", []):
+- bitrates = playlist.get("bitrates")
+- provider = playlist.get("connectionProvider")
+- rtmp = None
+-
+- if bitrates:
+- rtmp = playlist.get("netConnectionUrl")
+- elif provider and provider in player["plugins"]:
+- provider = player["plugins"][provider]
+- swf_name = provider["url"]
+- swf_url = SWF_BASE + swf_name
+- rtmp = provider["netConnectionUrl"]
+- bitrates = player["clip"]["bitrates"]
+- else:
+- continue
+-
+- for bitrate in bitrates:
+- quality = self._get_quality(bitrate["label"])
+- url = bitrate["url"]
+- stream = RTMPStream(self.session, {
+- "rtmp": rtmp,
+- "pageUrl": self.url,
+- "playpath": url,
+- "swfVfy": swf_url,
+- "live": True
+- })
+- yield quality, stream
++ return self._get_live_streams(player)
+ else:
+- base_url = player["clip"]["baseUrl"] or VOD_BASE_URL
+- for bitrate in player["clip"]["bitrates"]:
+- url = base_url + "/" + bitrate["url"]
+- quality = self._get_quality(bitrate["label"])
+-
+- if urlparse(url).path.endswith("m3u8"):
+- stream = HLSStream(self.session, url)
+- else:
+- stream = HTTPStream(self.session, url)
+-
+- yield quality, stream
++ return self._get_video_streams(player)
+
+ __plugin__ = Hitbox
More information about the arch-commits
mailing list