Skip to content

Commit

Permalink
model: add is_variant and playlists attribute, refs #4
Browse files Browse the repository at this point in the history
  • Loading branch information
igorsobreira committed May 2, 2012
1 parent fd5ac96 commit 20f9fbe
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
40 changes: 40 additions & 0 deletions m3u8/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ def dump(self, filename):
'''
pass

@property
def is_variant(self):
'''
Returns true if this M3U8 is a variant playlist, with links to
other M3U8s with different bitrates.
If true, `playlists` if a list of the playlists available.
'''
return self.data.get('is_variant', False)

@property
def target_duration(self):
'''
Expand Down Expand Up @@ -98,3 +109,32 @@ def files(self):
segments and key uri, if present.
'''
return ()

@property
def playlists(self):
'''
If this is a variant playlist (`is_variant` is True), returns a list of
Playlist objects, each one representing a link to another M3U8 with
a specific bitrate.
Each object in the list has the following attributes:
`resource`
url to the m3u8
`stream_info`
object with all attributes from EXT-X-STREAM-INF (`program_id`, `bandwidth` and `codecs`)
'''
Playlist = namedtuple('Playlist', ['resource', 'stream_info'])
StreamInfo = namedtuple('StreamInfo', ['bandwidth', 'program_id', 'codecs'])

playlists = []
for playlist in self.data.get('playlists', []):
stream_info = StreamInfo(bandwidth = playlist['stream_info']['bandwidth'],
program_id = playlist['stream_info'].get('program_id'),
codecs = playlist['stream_info'].get('codecs'))
playlists.append(Playlist(resource = playlist['resource'],
stream_info = stream_info))

return playlists
44 changes: 44 additions & 0 deletions tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,47 @@ def test_segments_attribute_without_duration():
assert '/foo/bar-1.ts' == obj.segments[0].uri
assert 'Segment title' == obj.segments[0].title
assert None == obj.segments[0].duration

def test_is_variant_attribute():
obj = m3u8.M3U8(SIMPLE_PLAYLIST)
obj.data = {'is_variant': False}
assert not obj.is_variant

obj.data = {'is_variant': True}
assert obj.is_variant

def test_playlists_attribute():
obj = m3u8.M3U8(SIMPLE_PLAYLIST)
obj.data = {'playlists': [{'resource': '/url/1.m3u8',
'stream_info': {'program_id': '1',
'bandwidth': '320000'}},
{'resource': '/url/2.m3u8',
'stream_info': {'program_id': '1',
'bandwidth': '120000',
'codecs': 'mp4a.40.5'}},
]}

assert 2 == len(obj.playlists)

assert '/url/1.m3u8' == obj.playlists[0].resource
assert '1' == obj.playlists[0].stream_info.program_id
assert '320000' == obj.playlists[0].stream_info.bandwidth
assert None == obj.playlists[0].stream_info.codecs

assert '/url/2.m3u8' == obj.playlists[1].resource
assert '1' == obj.playlists[1].stream_info.program_id
assert '120000' == obj.playlists[1].stream_info.bandwidth
assert 'mp4a.40.5' == obj.playlists[1].stream_info.codecs

def test_playlists_attribute_without_program_id():
obj = m3u8.M3U8(SIMPLE_PLAYLIST)
obj.data = {'playlists': [{'resource': '/url/1.m3u8',
'stream_info': {'bandwidth': '320000'}}
]}

assert 1 == len(obj.playlists)

assert '/url/1.m3u8' == obj.playlists[0].resource
assert '320000' == obj.playlists[0].stream_info.bandwidth
assert None == obj.playlists[0].stream_info.codecs
assert None == obj.playlists[0].stream_info.program_id

0 comments on commit 20f9fbe

Please sign in to comment.