restreamer: Make media playlist streamed

To deal better with very large playlists
pull/389/head
Mike Lang 1 year ago committed by Mike Lang
parent a6d4f2466a
commit be7a9cd1fa

@ -36,6 +36,8 @@ def generate_media(segments, base_url):
"""Generate a media playlist from a list of segments as returned by common.get_best_segments(). """Generate a media playlist from a list of segments as returned by common.get_best_segments().
Segments are specified as hour/name.ts relative to base_url. Segments are specified as hour/name.ts relative to base_url.
""" """
# segments may be an iterator, make it reusable
segments = list(segments)
# We have to pick a "target duration". in most circumstances almost all segments # We have to pick a "target duration". in most circumstances almost all segments
# will be of that duration, so we get the most common duration out of all the segments # will be of that duration, so we get the most common duration out of all the segments
@ -48,10 +50,8 @@ def generate_media(segments, base_url):
else: else:
target_duration = datetime.timedelta(seconds=6) target_duration = datetime.timedelta(seconds=6)
lines = [ yield "#EXTM3U\n"
"#EXTM3U", yield "#EXT-X-TARGETDURATION:{:.3f}\n".format(target_duration.total_seconds())
"#EXT-X-TARGETDURATION:{:.3f}".format(target_duration.total_seconds()),
]
# Note and remove any trailing None from the segment list - this indicates there is a hole # Note and remove any trailing None from the segment list - this indicates there is a hole
# at the end, which means we should mark the stream as incomplete but not include a discontinuity. # at the end, which means we should mark the stream as incomplete but not include a discontinuity.
@ -74,18 +74,19 @@ def generate_media(segments, base_url):
# and it should start decoding fresh on the next segment. This is required when # and it should start decoding fresh on the next segment. This is required when
# someone stops/starts a stream and a good idea if we're missing a segment in a # someone stops/starts a stream and a good idea if we're missing a segment in a
# continuous stream. # continuous stream.
lines.append("#EXT-X-DISCONTINUITY") yield "#EXT-X-DISCONTINUITY\n"
else: else:
# Each segment has two prefixes: timestamp and duration. # Each segment has two prefixes: timestamp and duration.
# This tells the client exactly what time the segment represents, which is important # This tells the client exactly what time the segment represents, which is important
# for the editor since it needs to describe cut points in these times. # for the editor since it needs to describe cut points in these times.
path = '/'.join(segment.path.split('/')[-2:]) path = '/'.join(segment.path.split('/')[-2:])
lines.append("#EXT-X-PROGRAM-DATE-TIME:{}".format(segment.start.strftime("%Y-%m-%dT%H:%M:%S.%fZ"))) lines = [
lines.append("#EXTINF:{:.3f},live".format(segment.duration.total_seconds())) "#EXT-X-PROGRAM-DATE-TIME:{}".format(segment.start.strftime("%Y-%m-%dT%H:%M:%S.%fZ")),
lines.append(urllib.parse.quote(os.path.join(base_url, path))) "#EXTINF:{:.3f},live".format(segment.duration.total_seconds()),
urllib.parse.quote(os.path.join(base_url, path)),
]
yield "\n".join(lines) + "\n"
# If stream is complete, add an ENDLIST marker to show this. # If stream is complete, add an ENDLIST marker to show this.
if not incomplete: if not incomplete:
lines.append("#EXT-X-ENDLIST") yield "#EXT-X-ENDLIST\n"
return "\n".join(lines) + '\n'

Loading…
Cancel
Save