Skip to content

Commit

Permalink
Better m3u8 codec parsing (#1213)
Browse files Browse the repository at this point in the history
* M3U8.Stream.ExtStreamInfo.Codecs string -> IReadOnlyList<string>

* Update tests
  • Loading branch information
ScrubN authored Sep 16, 2024
1 parent 851f881 commit cb805e9
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 50 deletions.
13 changes: 12 additions & 1 deletion TwitchDownloaderCLI/Modes/InfoHandler.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
Expand Down Expand Up @@ -149,7 +150,7 @@ private static void HandleVodTable(GqlVideoResponse videoInfo, GqlVideoChapterRe
var name = stream.GetResolutionFramerateString();
var resolution = stream.StreamInfo.Resolution.StringifyOrDefault(x => x.ToString(), DEFAULT_STRING);
var fps = stream.StreamInfo.Framerate.StringifyOrDefault(x => $"{x:F0}", DEFAULT_STRING);
var codecs = stream.StreamInfo.Codecs.StringifyOrDefault(x => x, DEFAULT_STRING);
var codecs = stream.StreamInfo.Codecs.StringifyOrDefault(x => string.Join(", ", x), DEFAULT_STRING);

if (hasBitrate)
{
Expand Down Expand Up @@ -364,6 +365,16 @@ private static string StringifyOrDefault<T>(this T? value, Func<T, string> strin
return defaultString;
}

private static string StringifyOrDefault<T>(this IEnumerable<T> values, Func<IEnumerable<T>, string> stringify, string defaultString)
{
if (values.Any())
{
return stringify(values);
}

return defaultString;
}

private static string StringifyTimestamp(TimeSpan timeSpan)
{
return timeSpan.Ticks switch
Expand Down
38 changes: 19 additions & 19 deletions TwitchDownloaderCore.Tests/ExtensionTests/M3U8ExtensionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ public static void CorrectlyFindsStreamOfQualityFromLiveM3U8Response(string qual
{
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "chunked", "1080p60 (source)", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.4D401F,mp4a.40.2", (1920, 1080), "chunked", 60),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.4D401F", "mp4a.40.2" }, (1920, 1080), "chunked", 60),
"1080p60"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "720p60", "720p60", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.4D401F,mp4a.40.2", (1280, 720), "720p60", 60),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.4D401F", "mp4a.40.2" }, (1280, 720), "720p60", 60),
"720p60"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "720p30", "720p", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.4D401F,mp4a.40.2", (1280, 720), "720p30", 30),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.4D401F", "mp4a.40.2" }, (1280, 720), "720p30", 30),
"720p30")
});

Expand Down Expand Up @@ -74,31 +74,31 @@ public static void CorrectlyFindsStreamOfQualityFromOldM3U8Response(string quali
{
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "chunked", "Source", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.4D401F,mp4a.40.2", (1920, 1080), "chunked", 58.644M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.4D401F", "mp4a.40.2" }, (1920, 1080), "chunked", 58.644M),
"1080p60"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "720p60", "720p60", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.4D401F,mp4a.40.2", (1280, 720), "720p60", 58.644M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.4D401F", "mp4a.40.2" }, (1280, 720), "720p60", 58.644M),
"720p60"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "720p30", "720p", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.4D401F,mp4a.40.2", (1280, 720), "720p30", 28.814M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.4D401F", "mp4a.40.2" }, (1280, 720), "720p30", 28.814M),
"720p30"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "480p30", "480p", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.42C01E,mp4a.40.2", (852, 480), "480p30", 30.159M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.42C01E", "mp4a.40.2" }, (852, 480), "480p30", 30.159M),
"480p30"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "360p30", "360p", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.42C01E,mp4a.40.2", (640, 360), "360p30", 30.159M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.42C01E", "mp4a.40.2" }, (640, 360), "360p30", 30.159M),
"360p30"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "144p30", "144p", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.42C00C,mp4a.40.2", (256, 144), "144p30", 30.159M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.42C00C", "mp4a.40.2" }, (256, 144), "144p30", 30.159M),
"144p30"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "audio_only", "Audio Only", false, false),
new M3U8.Stream.ExtStreamInfo(0, 1, "mp4a.40.2", (256, 144), "audio_only", 0),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "mp4a.40.2" }, (256, 144), "audio_only", 0),
"audio_only")
});

Expand All @@ -122,11 +122,11 @@ public static void CorrectlyFindsStreamOfQualityFromM3U8ResponseWithoutFramerate
{
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "chunked", "Source", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.4D401F,mp4a.40.2", (1920, 1080), "chunked", 0),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.4D401F", "mp4a.40.2" }, (1920, 1080), "chunked", 0),
"1080p60"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "720p60", "720p60", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.4D401F,mp4a.40.2", (1280, 720), "720p60", 58.644M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.4D401F", "mp4a.40.2" }, (1280, 720), "720p60", 58.644M),
"720p60"),
});

Expand All @@ -146,31 +146,31 @@ public static void ReturnsHighestQualityWhenDesiredQualityNotFoundForOldM3U8Resp
{
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "chunked", "Source", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.4D401F,mp4a.40.2", (1920, 1080), "chunked", 58.644M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.4D401F", "mp4a.40.2" }, (1920, 1080), "chunked", 58.644M),
"1080p60"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "720p60", "720p60", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.4D401F,mp4a.40.2", (1280, 720), "720p60", 58.644M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.4D401F", "mp4a.40.2" }, (1280, 720), "720p60", 58.644M),
"720p60"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "720p30", "720p", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.4D401F,mp4a.40.2", (1280, 720), "720p30", 28.814M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.4D401F", "mp4a.40.2" }, (1280, 720), "720p30", 28.814M),
"720p30"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "480p30", "480p", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.42C01E,mp4a.40.2", (852, 480), "480p30", 30.159M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.42C01E", "mp4a.40.2" }, (852, 480), "480p30", 30.159M),
"480p30"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "360p30", "360p", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.42C01E,mp4a.40.2", (640, 360), "360p30", 30.159M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.42C01E", "mp4a.40.2" }, (640, 360), "360p30", 30.159M),
"360p30"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "144p30", "144p", true, true),
new M3U8.Stream.ExtStreamInfo(0, 1, "avc1.42C00C,mp4a.40.2", (256, 144), "144p30", 30.159M),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "avc1.42C00C", "mp4a.40.2" }, (256, 144), "144p30", 30.159M),
"144p30"),
new M3U8.Stream(
new M3U8.Stream.ExtMediaInfo(M3U8.Stream.ExtMediaInfo.MediaType.Video, "audio_only", "Audio Only", false, false),
new M3U8.Stream.ExtStreamInfo(0, 1, "mp4a.40.2", (256, 144), "audio_only", 0),
new M3U8.Stream.ExtStreamInfo(0, 1, new[] { "mp4a.40.2" }, (256, 144), "audio_only", 0),
"audio_only")
});

Expand Down
Loading

0 comments on commit cb805e9

Please sign in to comment.