Skip to content

Commit

Permalink
Add infspec for specifying precision for EXTINF
Browse files Browse the repository at this point in the history
  • Loading branch information
daveisfera authored and mauricioabreu committed Jun 10, 2024
1 parent e3f6b9d commit 8ea8dea
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
18 changes: 12 additions & 6 deletions m3u8/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ def add_segment(self, segment):
def add_rendition_report(self, report):
self.rendition_reports.append(report)

def dumps(self, timespec="milliseconds"):
def dumps(self, timespec="milliseconds", infspec="auto"):
"""
Returns the current m3u8 as a string.
You could also use unicode(<this obj>) or str(<this obj>)
Expand Down Expand Up @@ -414,7 +414,7 @@ def dumps(self, timespec="milliseconds"):
for key in self.session_keys:
output.append(str(key))

output.append(self.segments.dumps(timespec))
output.append(self.segments.dumps(timespec, infspec))

if self.preload_hint:
output.append(str(self.preload_hint))
Expand Down Expand Up @@ -586,7 +586,7 @@ def __init__(
def add_part(self, part):
self.parts.append(part)

def dumps(self, last_segment, timespec="milliseconds"):
def dumps(self, last_segment, timespec="milliseconds", infspec="auto"):
output = []

if last_segment and self.key != last_segment.key:
Expand Down Expand Up @@ -659,7 +659,13 @@ def dumps(self, last_segment, timespec="milliseconds"):

if self.uri:
if self.duration is not None:
output.append("#EXTINF:%s," % number_to_string(self.duration))
if infspec == "milliseconds":
duration = "{:.3f}".format(self.duration)
elif infspec == "microseconds":
duration = "{:.6f}".format(self.duration)
else:
duration = number_to_string(self.duration)
output.append("#EXTINF:%s," % duration)
if self.title:
output.append(self.title)
output.append("\n")
Expand Down Expand Up @@ -704,11 +710,11 @@ def base_uri(self, newbase_uri):


class SegmentList(list, GroupedBasePathMixin):
def dumps(self, timespec="milliseconds"):
def dumps(self, timespec="milliseconds", infspec="auto"):
output = []
last_segment = None
for segment in self:
output.append(segment.dumps(last_segment, timespec))
output.append(segment.dumps(last_segment, timespec, infspec))
last_segment = segment
return "\n".join(output)

Expand Down
14 changes: 14 additions & 0 deletions tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,12 @@ def test_dump_should_not_ignore_zero_duration():
assert "EXTINF:0" in obj.dumps().strip()
assert "EXTINF:5220" in obj.dumps().strip()

assert "EXTINF:0.000" in obj.dumps(infspec="milliseconds").strip()
assert "EXTINF:5220.000" in obj.dumps(infspec="milliseconds").strip()

assert "EXTINF:0.000000" in obj.dumps(infspec="microseconds").strip()
assert "EXTINF:5220.000000" in obj.dumps(infspec="microseconds").strip()


def test_dump_should_use_decimal_floating_point_for_very_short_durations():
obj = m3u8.M3U8(playlists.SIMPLE_PLAYLIST_WITH_VERY_SHORT_DURATION)
Expand All @@ -806,6 +812,14 @@ def test_dump_should_use_decimal_floating_point_for_very_short_durations():
assert "EXTINF:5218.5" in obj.dumps().strip()
assert "EXTINF:0.000011" in obj.dumps().strip()

assert "EXTINF:5220.000" in obj.dumps(infspec="milliseconds").strip()
assert "EXTINF:5218.500" in obj.dumps(infspec="milliseconds").strip()
assert "EXTINF:0.000" in obj.dumps(infspec="milliseconds").strip()

assert "EXTINF:5220.000000" in obj.dumps(infspec="microseconds").strip()
assert "EXTINF:5218.500" in obj.dumps(infspec="microseconds").strip()
assert "EXTINF:0.000011" in obj.dumps(infspec="microseconds").strip()


def test_dump_should_include_segment_level_program_date_time():
obj = m3u8.M3U8(playlists.DISCONTINUITY_PLAYLIST_WITH_PROGRAM_DATE_TIME)
Expand Down

0 comments on commit 8ea8dea

Please sign in to comment.