diff --git a/restreamer/restreamer/main.py b/restreamer/restreamer/main.py index c5bc873..7f32ad5 100644 --- a/restreamer/restreamer/main.py +++ b/restreamer/restreamer/main.py @@ -1,4 +1,5 @@ +import datetime import errno import functools import json @@ -85,6 +86,17 @@ def list_segments(stream, variant, hour): 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/.m3u8') @has_path_args 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. 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)) - playlists = { - variant: url_for('generate_media_playlist', stream=stream, variant=variant, **request.args) - for variant in variants - } + + playlists = {} + 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)