aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Christopher Rosell <chrippa@tanuki.se>2012-10-04 12:14:11 +0200
committerGravatar Christopher Rosell <chrippa@tanuki.se>2012-10-04 12:14:59 +0200
commitd116953ddae86499392cab68bc4b14c119231821 (patch)
treee98a5e91604bd111555db1653708105130a38e9e
parent894612390e84eb111dd2457f4b04e2fd8d6abdcb (diff)
stream.hls: Some minor improvements.
-rw-r--r--src/livestreamer/stream/hls.py59
1 files changed, 43 insertions, 16 deletions
diff --git a/src/livestreamer/stream/hls.py b/src/livestreamer/stream/hls.py
index cc646f1..f899287 100644
--- a/src/livestreamer/stream/hls.py
+++ b/src/livestreamer/stream/hls.py
@@ -1,8 +1,10 @@
from . import Stream, StreamError
from ..utils import urlget
+from ..compat import urljoin
from time import time, sleep
+import os.path
import re
try:
@@ -75,6 +77,9 @@ class HLSStream(Stream):
Stream.__init__(self, session)
self.url = url
+ self.logger = session.logger.new_module("stream.hls")
+
+ def open(self):
self.playlist = {}
self.playlist_reload_time = 0
self.playlist_minimal_reload_time = 15
@@ -83,11 +88,8 @@ class HLSStream(Stream):
self.decryptor = None
self.decryptor_key = None
self.decryptor_iv = None
- self.fd = None
self.sequence = 0
- self.logger = session.logger.new_module("stream.hls")
- def open(self):
return self
def read(self, size=-1):
@@ -97,7 +99,7 @@ class HLSStream(Stream):
except IOError:
return b""
- data = self.fd.read(size)
+ data = self.entry.read(size)
if len(data) == 0:
self._next_entry()
@@ -112,6 +114,8 @@ class HLSStream(Stream):
if len(self.playlist) == 0:
self._reload_playlist()
+ self._open_playlist_fds()
+
# Periodic reload is not fatal if it fails
elapsed = time() - self.playlist_reload_time
if elapsed > self.playlist_minimal_reload_time:
@@ -129,15 +133,11 @@ class HLSStream(Stream):
sleep(1)
return self._next_entry()
+
self.entry = self.playlist[self.sequence]
self.logger.debug("Next entry: {0}", self.entry)
- res = urlget(self.entry["url"], prefetch=False,
- exception=IOError)
-
- self.playlist[self.sequence] = None
-
if self.decryptor_key:
if not self.decryptor_iv:
iv = num_to_iv(self.sequence)
@@ -146,7 +146,6 @@ class HLSStream(Stream):
self.decryptor = AES.new(self.decryptor_key, AES.MODE_CBC, iv)
- self.fd = res.raw
self.sequence += 1
def _reload_playlist(self):
@@ -184,17 +183,41 @@ class HLSStream(Stream):
self.decryptor_key = res.content
for i, entry in enumerate(entries):
- self.playlist[sequence + i] = entry
+ entry["sequence"] = sequence + i
- if entry["tag"][0] == "EXTINF":
- duration = entry["tag"][1][0]
- self.playlist_minimal_reload_time = duration
+ self.entries = entries
if self.sequence == 0:
self.sequence = sequence
self.playlist_reload_time = time()
+ def _open_playlist_fds(self):
+ maxseq = self.sequence + 5
+
+ for entry in self.entries:
+ if entry["sequence"] > maxseq:
+ break
+
+ if not entry["sequence"] in self.playlist:
+ url = self._relative_url(entry["url"])
+ self.logger.debug("Opening fd: {0}", url)
+ res = urlget(url, prefetch=False,
+ exception=IOError)
+
+ self.playlist[entry["sequence"]] = res.raw
+
+ if entry["tag"][0] == "EXTINF":
+ duration = entry["tag"][1][0]
+ self.playlist_minimal_reload_time = duration
+
+ def _relative_url(self, url):
+ if url[0] == "/":
+ return urljoin(os.path.dirname(self.url), url)
+ else:
+ return url
+
+
@classmethod
def parse_variant_playlist(cls, session, url):
res = urlget(url, exception=IOError)
@@ -202,16 +225,20 @@ class HLSStream(Stream):
(tags, entries) = parse_m3u(res.text)
+
for entry in entries:
(tag, value) = entry["tag"]
if tag != "EXT-X-STREAM-INF":
continue
- if not "RESOLUTION" in value:
+ if "RESOLUTION" in value:
+ quality = value["RESOLUTION"].split("x")[1] + "p"
+ elif "BANDWIDTH" in value:
+ quality = str(int(int(value["BANDWIDTH"]) / 1000)) + "k"
+ else:
continue
- quality = value["RESOLUTION"].split("x")[1] + "p"
stream = HLSStream(session, entry["url"])
streams[quality] = stream