hls segmenter fixes (#824)

* fix pts warning when channel first starts streaming

* rework playlist filtering
This commit is contained in:
Jason Dove
2022-05-25 21:05:55 -05:00
committed by GitHub
parent 4e2ebcc48a
commit 777a0d09ed
4 changed files with 482 additions and 113 deletions
@@ -20,7 +20,7 @@ public class HlsPlaylistFilterTests
private HlsPlaylistFilter _hlsPlaylistFilter;
[Test]
public void _hlsPlaylistFilter_ShouldRewriteProgramDateTime()
public void HlsPlaylistFilter_ShouldRewriteProgramDateTime()
{
var start = new DateTimeOffset(2021, 10, 9, 8, 0, 0, TimeSpan.FromHours(-5));
string[] input = NormalizeLineEndings(
@@ -50,9 +50,8 @@ live001139.ts").Split(Environment.NewLine);
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:1137
#EXT-X-DISCONTINUITY-SEQUENCE:0
#EXT-X-DISCONTINUITY-SEQUENCE:1
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-DISCONTINUITY
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-09T08:00:00.000-0500
live001137.ts
@@ -66,7 +65,7 @@ live001139.ts
}
[Test]
public void _hlsPlaylistFilter_ShouldLimitSegments()
public void HlsPlaylistFilter_ShouldLimitSegments()
{
var start = new DateTimeOffset(2021, 10, 9, 8, 0, 0, TimeSpan.FromHours(-5));
string[] input = NormalizeLineEndings(
@@ -96,9 +95,8 @@ live001139.ts").Split(Environment.NewLine);
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:1137
#EXT-X-DISCONTINUITY-SEQUENCE:0
#EXT-X-DISCONTINUITY-SEQUENCE:1
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-DISCONTINUITY
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-09T08:00:00.000-0500
live001137.ts
@@ -109,7 +107,7 @@ live001138.ts
}
[Test]
public void _hlsPlaylistFilter_ShouldAddDiscontinuity()
public void HlsPlaylistFilter_ShouldAddDiscontinuity()
{
var start = new DateTimeOffset(2021, 10, 9, 8, 0, 0, TimeSpan.FromHours(-5));
string[] input = NormalizeLineEndings(
@@ -144,9 +142,8 @@ live001139.ts").Split(Environment.NewLine);
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:1137
#EXT-X-DISCONTINUITY-SEQUENCE:0
#EXT-X-DISCONTINUITY-SEQUENCE:1
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-DISCONTINUITY
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-09T08:00:00.000-0500
live001137.ts
@@ -161,7 +158,7 @@ live001139.ts
}
[Test]
public void _hlsPlaylistFilter_ShouldFilterOldSegments()
public void HlsPlaylistFilter_ShouldFilterOldSegmentsBeyondMax()
{
var start = new DateTimeOffset(2021, 10, 9, 8, 0, 0, TimeSpan.FromHours(-5));
string[] input = NormalizeLineEndings(
@@ -181,48 +178,7 @@ live001138.ts
#EXT-X-PROGRAM-DATE-TIME:2021-10-08T08:34:57.320-0500
live001139.ts").Split(Environment.NewLine);
TrimPlaylistResult result = _hlsPlaylistFilter.TrimPlaylist(start, start.AddSeconds(6), input);
result.PlaylistStart.Should().Be(start.AddSeconds(8));
result.Sequence.Should().Be(1139);
result.Playlist.Should().Be(
NormalizeLineEndings(
@"#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:1139
#EXT-X-DISCONTINUITY-SEQUENCE:0
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-DISCONTINUITY
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-09T08:00:08.000-0500
live001139.ts
"));
}
[Test]
public void _hlsPlaylistFilter_ShouldFilterOldDiscontinuity()
{
var start = new DateTimeOffset(2021, 10, 9, 8, 0, 0, TimeSpan.FromHours(-5));
string[] input = NormalizeLineEndings(
@"#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:1137
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-DISCONTINUITY
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-08T08:34:49.320-0500
live001137.ts
#EXT-X-DISCONTINUITY
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-08T08:34:53.320-0500
live001138.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-08T08:34:57.320-0500
live001139.ts").Split(Environment.NewLine);
TrimPlaylistResult result = _hlsPlaylistFilter.TrimPlaylist(start, start.AddSeconds(6), input);
TrimPlaylistResult result = _hlsPlaylistFilter.TrimPlaylist(start, start.AddSeconds(6), input, 1);
result.PlaylistStart.Should().Be(start.AddSeconds(8));
result.Sequence.Should().Be(1139);
@@ -234,13 +190,367 @@ live001139.ts").Split(Environment.NewLine);
#EXT-X-MEDIA-SEQUENCE:1139
#EXT-X-DISCONTINUITY-SEQUENCE:1
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-DISCONTINUITY
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-09T08:00:08.000-0500
live001139.ts
"));
}
[Test]
public void HlsPlaylistFilter_ShouldFilterOldDiscontinuity()
{
var start = new DateTimeOffset(2021, 10, 9, 8, 0, 0, TimeSpan.FromHours(-5));
string[] input = NormalizeLineEndings(
@"#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:1137
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-DISCONTINUITY
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-08T08:34:49.320-0500
live001137.ts
#EXT-X-DISCONTINUITY
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-08T08:34:53.320-0500
live001138.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-08T08:34:57.320-0500
live001139.ts").Split(Environment.NewLine);
TrimPlaylistResult result = _hlsPlaylistFilter.TrimPlaylist(start, start.AddSeconds(6), input);
result.PlaylistStart.Should().Be(start);
result.Sequence.Should().Be(1137);
result.Playlist.Should().Be(
NormalizeLineEndings(
@"#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:1137
#EXT-X-DISCONTINUITY-SEQUENCE:1
#EXT-X-INDEPENDENT-SEGMENTS
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-09T08:00:00.000-0500
live001137.ts
#EXT-X-DISCONTINUITY
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-09T08:00:04.000-0500
live001138.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2021-10-09T08:00:08.000-0500
live001139.ts
"));
}
[Test]
public void HlsPlaylistFilter_Should_Increment_DiscontinuityCount()
{
var start = new DateTimeOffset(2022, 5, 25, 20, 8, 0, TimeSpan.FromHours(-5));
string[] input = NormalizeLineEndings(
@"#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-DISCONTINUITY
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-DISCONTINUITY
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:08:55.981-0500
live000000.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:08:59.985-0500
live000001.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:03.989-0500
live000002.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:07.993-0500
live000003.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:11.997-0500
live000004.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:16.001-0500
live000005.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:20.005-0500
live000006.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:24.009-0500
live000007.ts
#EXTINF:3.970633,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:28.013-0500
live000008.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:31.983-0500
live000009.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:35.987-0500
live000010.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:39.991-0500
live000011.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:43.995-0500
live000012.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:47.999-0500
live000013.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:52.003-0500
live000014.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:09:56.007-0500
live000015.ts
#EXTINF:3.970633,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:00.011-0500
live000016.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:03.982-0500
live000017.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:07.986-0500
live000018.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:11.990-0500
live000019.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:15.994-0500
live000020.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:19.998-0500
live000021.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:24.002-0500
live000022.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:28.006-0500
live000023.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:32.010-0500
live000024.ts
#EXTINF:3.970633,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:36.014-0500
live000025.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:39.985-0500
live000026.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:43.989-0500
live000027.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:47.993-0500
live000028.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:51.997-0500
live000029.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:10:56.001-0500
live000030.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:00.005-0500
live000031.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:04.009-0500
live000032.ts
#EXTINF:3.970633,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:08.013-0500
live000033.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:11.983-0500
live000034.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:15.987-0500
live000035.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:19.991-0500
live000036.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:23.995-0500
live000037.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:27.999-0500
live000038.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:32.003-0500
live000039.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:36.007-0500
live000040.ts
#EXTINF:3.970633,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:40.011-0500
live000041.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:43.982-0500
live000042.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:47.986-0500
live000043.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:51.990-0500
live000044.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:55.994-0500
live000045.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:59.998-0500
live000046.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:04.002-0500
live000047.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:08.006-0500
live000048.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:12.010-0500
live000049.ts
#EXTINF:3.970633,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:16.014-0500
live000050.ts
#EXTINF:4.004000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:19.985-0500
live000051.ts
#EXTINF:0.433767,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:23.989-0500
live000052.ts
#EXT-X-DISCONTINUITY
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:30.007-0500
live000053.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:34.007-0500
live000054.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:38.007-0500
live000055.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:42.007-0500
live000056.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:46.007-0500
live000057.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:50.007-0500
live000058.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:54.007-0500
live000059.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:58.007-0500
live000060.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:02.007-0500
live000061.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:06.007-0500
live000062.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:10.007-0500
live000063.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:14.007-0500
live000064.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:18.007-0500
live000065.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:22.007-0500
live000066.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:26.007-0500
live000067.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:30.007-0500
live000068.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:34.007-0500
live000069.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:38.007-0500
live000070.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:42.007-0500
live000071.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:46.007-0500
live000072.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:50.007-0500
live000073.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:54.007-0500
live000074.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:58.007-0500
live000075.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:13:02.007-0500
live000076.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:13:06.007-0500
live000077.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:13:10.007-0500
live000078.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:13:14.007-0500
live000079.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:13:18.007-0500
live000080.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:13:22.007-0500
live000081.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:13:26.007-0500
live000082.ts").Split(Environment.NewLine);
TrimPlaylistResult result = _hlsPlaylistFilter.TrimPlaylist(start, start.AddSeconds(220), input);
// result.PlaylistStart.Should().Be(start);
result.Sequence.Should().Be(56);
result.Playlist.Should().Be(
NormalizeLineEndings(
@"#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:56
#EXT-X-DISCONTINUITY-SEQUENCE:2
#EXT-X-INDEPENDENT-SEGMENTS
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:40.441-0500
live000056.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:44.441-0500
live000057.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:48.441-0500
live000058.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:52.441-0500
live000059.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:11:56.441-0500
live000060.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:00.441-0500
live000061.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:04.441-0500
live000062.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:08.441-0500
live000063.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:12.441-0500
live000064.ts
#EXTINF:4.000000,
#EXT-X-PROGRAM-DATE-TIME:2022-05-25T20:12:16.441-0500
live000065.ts
"));
}
private static string NormalizeLineEndings(string str) =>
str
.Replace("\r\n", "\n")