Skip to content

Commit

Permalink
Fixed 2 problems:
Browse files Browse the repository at this point in the history
Unknown AttributeNames should be ignored, according to https://tools.ietf.org/html/draft-pantos-http-live-streaming-16#section-6.3.1.  Observed BANDWIDTH included in EXT-X-MEDIA tag from ted.com (e.g. http://hls.ted.com/talks/2297.m3u8), which is not defined, but caused an exception. Fixed that with the **extras.

Also changed semantics when an absolute path without a netloc is used in a url, so that base_url will behave like a urljoin, using base_url netloc and the given url's absolute path. Note the change to expected_ts1_abspath in test_load_should_create_object_from_uri_with_relative_segments in test_loader.py. Also impacted parsing of the same video from ted.com.
  • Loading branch information
GrumpyOldTroll committed Jul 28, 2015
1 parent 8b31976 commit 80af35f
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
15 changes: 9 additions & 6 deletions m3u8/model.py
Expand Up @@ -131,6 +131,10 @@ def __init__(self, content=None, base_path=None, base_uri=None, strict=False):
else:
self.data = {}
self._base_uri = base_uri
if self._base_uri:
if not self._base_uri.endswith('/'):
self._base_uri += '/'

self._initialize_attributes()
self.base_path = base_path

Expand Down Expand Up @@ -359,7 +363,8 @@ def dumps(self, last_segment):

if self.discontinuity:
output.append('#EXT-X-DISCONTINUITY\n')
output.append('#EXT-X-PROGRAM-DATE-TIME:%s\n' % parser.format_date_time(self.program_date_time))
if self.program_date_time:
output.append('#EXT-X-PROGRAM-DATE-TIME:%s\n' % parser.format_date_time(self.program_date_time))
if self.cue_out:
output.append('#EXT-X-CUE-OUT-CONT\n')
output.append('#EXTINF:%s,' % int_or_float_to_string(self.duration))
Expand Down Expand Up @@ -579,7 +584,7 @@ class Media(BasePathMixin):
def __init__(self, uri=None, type=None, group_id=None, language=None,
name=None, default=None, autoselect=None, forced=None,
characteristics=None, assoc_language=None,
instream_id=None,base_uri=None):
instream_id=None,base_uri=None, **extras):
self.base_uri = base_uri
self.uri = uri
self.type = type
Expand All @@ -592,6 +597,7 @@ def __init__(self, uri=None, type=None, group_id=None, language=None,
self.assoc_language = assoc_language
self.instream_id = instream_id
self.characteristics = characteristics
self.extras = extras

def dumps(self):
media_out = []
Expand Down Expand Up @@ -649,10 +655,7 @@ def quoted(string):

def _urijoin(base_uri, path):
if parser.is_url(base_uri):
parsed_url = url_parser.urlparse(base_uri)
prefix = parsed_url.scheme + '://' + parsed_url.netloc
new_path = posixpath.normpath(parsed_url.path + '/' + path)
return url_parser.urljoin(prefix, new_path.strip('/'))
return url_parser.urljoin(base_uri, path)
else:
return os.path.normpath(os.path.join(base_uri, path.strip('/')))

Expand Down
2 changes: 1 addition & 1 deletion tests/test_loader.py
Expand Up @@ -68,7 +68,7 @@ def test_load_should_create_object_from_uri_with_relative_segments():
prefix = urlparsed.scheme + '://' + urlparsed.netloc
expected_key_abspath = '%s%s/key.bin' % (prefix, os.path.normpath(base_uri + '/..'))
expected_key_path = '../key.bin'
expected_ts1_abspath = '%s%sentire1.ts' % (prefix, base_uri + '/')
expected_ts1_abspath = '%s/entire1.ts' % (prefix)
expected_ts1_path = '/entire1.ts'
expected_ts2_abspath = '%s%sentire2.ts' % (prefix, os.path.normpath(base_uri + '/..') + '/')
expected_ts2_path = '../entire2.ts'
Expand Down
12 changes: 12 additions & 0 deletions tests/test_model.py
Expand Up @@ -391,6 +391,14 @@ def test_dump_should_work_for_iframe_playlists():
# hence IFRAME_PLAYLIST dump from IFRAME_PLAYLIST2 parse.
assert expected == obj.dumps().strip()

obj = m3u8.M3U8(playlists.IFRAME_PLAYLIST2)

expected = playlists.IFRAME_PLAYLIST.strip()

# expected that dump will reverse EXTINF and EXT-X-BYTERANGE,
# hence IFRAME_PLAYLIST dump from IFRAME_PLAYLIST2 parse.
assert expected == obj.dumps().strip()

def test_dump_should_include_program_date_time():
obj = m3u8.M3U8(playlists.SIMPLE_PLAYLIST_WITH_PROGRAM_DATE_TIME)

Expand Down Expand Up @@ -529,9 +537,13 @@ def test_m3u8_should_propagate_base_uri_to_segments():
obj = m3u8.M3U8(content, base_uri='/any/path')
assert '/entire1.ts' == obj.segments[0].uri
assert '/any/path/entire1.ts' == obj.segments[0].absolute_uri
assert 'entire4.ts' == obj.segments[3].uri
assert '/any/path/entire4.ts' == obj.segments[3].absolute_uri
obj.base_uri = '/any/where/'
assert '/entire1.ts' == obj.segments[0].uri
assert '/any/where/entire1.ts' == obj.segments[0].absolute_uri
assert 'entire4.ts' == obj.segments[3].uri
assert '/any/where/entire4.ts' == obj.segments[3].absolute_uri

def test_m3u8_should_propagate_base_uri_to_key():
with open(playlists.RELATIVE_PLAYLIST_FILENAME) as f:
Expand Down

0 comments on commit 80af35f

Please sign in to comment.