Skip to content

Commit

Permalink
added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Neon-Dlea committed Jul 14, 2015
1 parent 4273698 commit f50cad5
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 78 deletions.
2 changes: 1 addition & 1 deletion m3u8/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ def _parse_ts_chunk(line, data, state):
segment['program_date_time'] = state['current_program_date_time']
state['current_program_date_time'] += datetime.timedelta(seconds=segment['duration'])
segment['uri'] = line
segment['discontinuity'] = state.pop('discontinuity', False)
segment['cue_out'] = state.pop('cue_out', False)
segment['discontinuity'] = state.pop('discontinuity', False)
if state.get('current_key'):
segment['key'] = state['current_key']
data['segments'].append(segment)
Expand Down
2 changes: 1 addition & 1 deletion m3u8/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
ext_x_byterange = '#EXT-X-BYTERANGE'
ext_x_i_frame_stream_inf = '#EXT-X-I-FRAME-STREAM-INF'
ext_x_discontinuity = '#EXT-X-DISCONTINUITY'
ext_x_cue_out = '#EXT-X-CUE-OUT'
ext_x_cue_out = '#EXT-X-CUE-OUT'
66 changes: 34 additions & 32 deletions tests/playlists.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@
PLAYLIST_WITH_ENCRIPTED_SEGMENTS = '''
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:7794
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=52",KEYFORMAT="identity",KEYFORMATVERSIONS="1/2/5"
#EXT-X-TARGETDURATION:15
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=52"
#EXTINF:15,
http://media.example.com/fileSequence52-1.ts
#EXTINF:15,
Expand Down Expand Up @@ -101,39 +103,9 @@
video-64k.m3u8
'''

VARIANT_PLAYLIST_WITH_MEDIA = '''
#EXTM3U
#EXT-X-MEDIA:URI="captions.m3u8",TYPE=SUBTITLES,GROUP-ID="subs",LANGUAGE="en",NAME="English",DEFAULT=YES,AUTOSELECT=YES,FORCED=NO
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000,RESOLUTION=624x352,CODECS="avc1.4d001f, mp4a.40.5",SUBTITLES="subs"
video-800k.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1200000,CODECS="avc1.4d001f, mp4a.40.5",SUBTITLES="subs"
video-1200k.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=400000,CODECS="avc1.4d001f, mp4a.40.5",SUBTITLES="subs"
video-400k.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=150000,CODECS="avc1.4d001f, mp4a.40.5",SUBTITLES="subs"
video-150k.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=64000,CODECS="mp4a.40.5",SUBTITLES="subs"
video-64k.m3u8
'''

VARIANT_PLAYLIST_WITH_CLOSED_CAPTIONS = '''
#EXTM3U
#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS,GROUP-ID="cc",INSTREAM-ID=SERVICE43,LANGUAGE="en",NAME="English",DEFAULT=YES,AUTOSELECT=YES,FORCED=NO
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000,RESOLUTION=624x352,CODECS="avc1.4d001f, mp4a.40.5",CLOSED-CAPTIONS="cc"
video-800k.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1200000,CODECS="avc1.4d001f, mp4a.40.5",CLOSED-CAPTIONS="cc"
video-1200k.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=400000,CODECS="avc1.4d001f, mp4a.40.5",CLOSED-CAPTIONS="cc"
video-400k.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=150000,CODECS="avc1.4d001f, mp4a.40.5",CLOSED-CAPTIONS="cc"
video-150k.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=64000,CODECS="mp4a.40.5",CLOSED-CAPTIONS="cc"
video-64k.m3u8
'''


IFRAME_PLAYLIST = '''
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-VERSION:4
#EXT-X-TARGETDURATION:10
#EXT-X-PLAYLIST-TYPE:VOD
Expand All @@ -152,6 +124,7 @@

PLAYLIST_USING_BYTERANGES = '''
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-VERSION:4
#EXT-X-TARGETDURATION:11
#EXTINF:10,
Expand Down Expand Up @@ -291,8 +264,37 @@
'''

CUE_OUT_PLAYLIST = '''
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:143474331
#EXT-X-VERSION:3
#EXTINF:10,
#EXT-X-PROGRAM-DATE-TIME:2015-06-18T23:22:10Z
1432451707508/ts/71737/sequence143474338.ts
#EXT-X-CUE-OUT-CONT:CAID=0x000000002310E3A8,ElapsedTime=161,Duration=181
#EXTINF:10,
#EXT-X-PROGRAM-DATE-TIME:2015-06-18T23:22:20Z
1432451707508/ts/71737/sequence143474339.ts
#EXT-X-CUE-OUT-CONT:CAID=0x000000002310E3A8,ElapsedTime=171,Duration=181
#EXTINF:10,
#EXT-X-PROGRAM-DATE-TIME:2015-06-18T23:22:30Z
1432451707508/ts/71737/sequence143474340.ts
#EXT-OATCLS-SCTE35:/DA5AAAAAAAA/wCABQb+aDhDgAAjAhdDVUVJQAAAV3+fCAgAAAAAIxDjqDUCAAAIQ1VFSQAAAABSV+PX
#EXT-X-CUE-IN
#EXTINF:10,
#EXT-X-PROGRAM-DATE-TIME:2015-06-18T23:22:40Z
1432451707508/ts/71737/sequence143474341.ts
'''


RELATIVE_PLAYLIST_FILENAME = abspath(join(dirname(__file__), 'playlists/relative-playlist.m3u8'))

RELATIVE_PLAYLIST_URI = TEST_HOST + '/path/to/relative-playlist.m3u8'

CUE_OUT_PLAYLIST_FILENAME = abspath(join(dirname(__file__), 'playlists/cue_out.m3u8'))

CUE_OUT_PLAYLIST_URI = TEST_HOST + '/path/to/cue_out.m3u8'

del abspath, dirname, join
60 changes: 16 additions & 44 deletions tests/test_model.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
#Tests M3U8 class to make sure all attributes and methods use the correct
#data returned from parser.parse()

import arrow
import datetime
import m3u8
import playlists
from m3u8.model import Segment
from m3u8.parser import cast_date_time

def test_target_duration_attribute():
obj = m3u8.M3U8(playlists.SIMPLE_PLAYLIST)
Expand All @@ -24,28 +24,23 @@ def test_media_sequence_attribute():

assert '1234567' == obj.media_sequence

def test_implicit_media_sequence_value():
obj = m3u8.M3U8(playlists.SIMPLE_PLAYLIST)

assert 0 == obj.media_sequence

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

assert cast_date_time('2014-08-13T13:36:33+00:00') == obj.program_date_time
assert arrow.get('2014-08-13T13:36:33+00:00').datetime == obj.program_date_time

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

first_program_date_time = cast_date_time('2014-08-13T13:36:33+00:00')
first_program_date_time = arrow.get('2014-08-13T13:36:33+00:00').datetime
for idx, segment in enumerate(obj.segments):
assert segment.program_date_time == first_program_date_time + datetime.timedelta(seconds=idx * 3)

def test_program_date_time_attribute_with_discontinuity():
obj = m3u8.M3U8(playlists.DISCONTINUITY_PLAYLIST_WITH_PROGRAM_DATE_TIME)

first_program_date_time = cast_date_time('2014-08-13T13:36:33+00:00')
discontinuity_program_date_time = cast_date_time('2014-08-13T13:36:55+00:00')
first_program_date_time = arrow.get('2014-08-13T13:36:33+00:00').datetime
discontinuity_program_date_time = arrow.get('2014-08-13T13:36:55+00:00').datetime

segments = obj.segments

Expand All @@ -62,6 +57,15 @@ def test_segment_discontinuity_attribute():
assert segments[5].discontinuity == True
assert segments[6].discontinuity == False

def test_segment_cue_out_attribute():
obj = m3u8.M3U8(playlists.CUE_OUT_PLAYLIST)
print obj
segments = obj.segments

assert segments[0].cue_out == True
assert segments[1].cue_out == True
assert segments[2].cue_out == True

def test_key_attribute():
obj = m3u8.M3U8(playlists.SIMPLE_PLAYLIST)
data = {'key': {'method': 'AES-128',
Expand Down Expand Up @@ -318,11 +322,7 @@ def test_no_playlist_type_leaves_attribute_empty():
# dump m3u8

def test_dumps_should_build_same_string():
playlists_model = [
playlists.PLAYLIST_WITH_NON_INTEGER_DURATION,
playlists.PLAYLIST_WITH_ENCRIPTED_SEGMENTS,
playlists.PLAYLIST_WITH_ENCRIPTED_SEGMENTS_AND_IV,
]
playlists_model = [playlists.PLAYLIST_WITH_NON_INTEGER_DURATION, playlists.PLAYLIST_WITH_ENCRIPTED_SEGMENTS_AND_IV]
for playlist in playlists_model:
obj = m3u8.M3U8(playlist)
expected = playlist.replace(', IV', ',IV').strip()
Expand Down Expand Up @@ -369,13 +369,6 @@ def test_dump_should_work_for_variant_playlists_with_iframe_playlists():

assert expected == obj.dumps().strip()

def test_dump_should_work_for_variant_playlists_with_media():
obj = m3u8.M3U8(playlists.VARIANT_PLAYLIST_WITH_MEDIA)

expected = playlists.VARIANT_PLAYLIST_WITH_MEDIA.strip()

assert expected == obj.dumps().strip()

def test_dump_should_work_for_iframe_playlists():
obj = m3u8.M3U8(playlists.IFRAME_PLAYLIST)

Expand Down Expand Up @@ -499,7 +492,7 @@ def test_0_media_sequence_added_to_file():
obj = m3u8.M3U8()
obj.media_sequence = 0
result = obj.dumps()
expected = '#EXTM3U\n'
expected = '#EXTM3U\n#EXT-X-MEDIA-SEQUENCE:0\n'
assert result == expected

def test_none_media_sequence_gracefully_ignored():
Expand Down Expand Up @@ -535,27 +528,6 @@ def test_m3u8_should_propagate_base_uri_to_key():
assert '../key.bin' == obj.key.uri
assert '/any/key.bin' == obj.key.absolute_uri

def test_m3u8_should_propagate_base_uri_to_media():
content = playlists.VARIANT_PLAYLIST_WITH_MEDIA
obj = m3u8.M3U8(content, base_uri='/any/path/')
assert 'captions.m3u8' == obj.media[0].uri
assert '/any/path/captions.m3u8' == obj.media[0].absolute_uri
obj.base_uri = '/any/where/'
assert 'captions.m3u8' == obj.media[0].uri
assert '/any/where/captions.m3u8' == obj.media[0].absolute_uri

def test_m3u8_should_not_fail_on_closed_captions():
content = playlists.VARIANT_PLAYLIST_WITH_CLOSED_CAPTIONS
obj = m3u8.M3U8(content, base_uri='/any/path/')
assert 'video-800k.m3u8' == obj.playlists[0].uri
assert '/any/path/video-800k.m3u8' == obj.playlists[0].absolute_uri
obj.base_uri = '/any/where/'
assert 'video-800k.m3u8' == obj.playlists[0].uri
assert '/any/where/video-800k.m3u8' == obj.playlists[0].absolute_uri
assert obj.media[0].uri is None
assert obj.media[0].absolute_uri is None
assert obj.media[0].type == 'CLOSED-CAPTIONS'


# custom asserts

Expand Down

0 comments on commit f50cad5

Please sign in to comment.