@ -1,4 +1,5 @@
import datetime
import errno
import errno
import functools
import functools
import json
import json
@ -85,6 +86,17 @@ def list_segments(stream, variant, hour):
return json . dumps ( listdir ( path , error = False ) )
return json . dumps ( listdir ( path , error = False ) )
def time_range_for_variant ( stream , variant ) :
""" Returns earliest and latest times that the given variant has segments for
( up to hour resolution ) , or 404 if it doesn ' t exist / is empty. " " "
hours = listdir ( os . path . join ( app . static_folder , stream , variant ) )
if not hours :
abort ( 404 )
first , last = min ( hours ) , max ( hours )
# note last hour parses to _start_ of that hour, so we add 1h to go to end of that hour
return dateutil . parser . parse ( first ) , dateutil . parser . parse ( last ) + datetime . timedelta ( hours = 1 )
@app.route ( ' /playlist/<stream>.m3u8 ' )
@app.route ( ' /playlist/<stream>.m3u8 ' )
@has_path_args
@has_path_args
def generate_master_playlist ( stream ) :
def generate_master_playlist ( stream ) :
@ -93,11 +105,24 @@ def generate_master_playlist(stream):
start , end : The time to begin and end the stream at .
start , end : The time to begin and end the stream at .
See generate_media_playlist for details .
See generate_media_playlist for details .
"""
"""
start = dateutil . parser . parse ( request . args [ ' start ' ] ) if ' start ' in request . args else None
end = dateutil . parser . parse ( request . args [ ' end ' ] ) if ' end ' in request . args else None
variants = listdir ( os . path . join ( app . static_folder , stream ) )
variants = listdir ( os . path . join ( app . static_folder , stream ) )
playlists = {
variant : url_for ( ' generate_media_playlist ' , stream = stream , variant = variant , * * request . args )
playlists = { }
for variant in variants
for variant in variants :
}
# If start or end are given, try to restrict offered variants to ones which exist for that
# time range.
if start is not None or end is not None :
first , last = time_range_for_variant ( stream , variant )
if start is not None and last < start :
continue # last time for variant is before our start time, don't offer variant
if end is not None and end < first :
continue # our end time is before first time for variant, don't offer variant
playlists [ variant ] = url_for (
' generate_media_playlist ' , stream = stream , variant = variant , * * request . args
)
return generate_hls . generate_master ( playlists )
return generate_hls . generate_master ( playlists )