feat: resolve HTTP video URLs with bundled yt-dlp

This commit is contained in:
2026-10-22 17:05:29 +02:00
parent 6a4afc9f0e
commit b132bab393
14 changed files with 121 additions and 79 deletions
+21 -8
View File
@@ -55,7 +55,7 @@ static NSArray<NSDictionary *> *records(const std::string &path) {
"schema version is numeric one");
require([@[@"progress", @"ended", @"closed"] containsObject:row[@"event"]], "known event type");
require([row[@"media_url"] isKindOfClass:[NSString class]] &&
ProgressReporter::validMediaURL([row[@"media_url"] UTF8String]), "canonical consumer identity");
ProgressReporter::validMediaURL([row[@"media_url"] UTF8String]), "HTTP(S) consumer identity");
require([row[@"position_seconds"] isKindOfClass:[NSNumber class]] &&
std::isfinite([row[@"position_seconds"] doubleValue]) &&
[row[@"position_seconds"] doubleValue] >= 0, "position is finite and nonnegative");
@@ -240,13 +240,26 @@ int main(int argc, char **argv) {
for (NSUInteger i = 0; i < rows.count; ++i)
expect(rows[i], i % 2 ? @"closed" : @"progress", firstURL, 97, false, i < 8 ? 0 : 100);
require(ProgressReporter::validMediaURL(firstURL) &&
ProgressReporter::validMediaURL("https://www.youtube.com/watch?v=aA0_-123456"), "eleven ASCII ID characters are accepted");
for (const char *invalid : {"", "http://www.youtube.com/watch?v=AAAAAAAAAAA",
"https://youtube.com/watch?v=AAAAAAAAAAA", "https://www.youtube.com/watch?v=AAAAAAAAAA",
"https://www.youtube.com/watch?v=AAAAAAAAAAAA", "https://www.youtube.com/watch?v=AAAAAAAAAAA&x=1",
"https://www.youtube.com/watch?v=AAAAAAAAAA%", "https://www.youtube.com/watch?v=AAAAAAAAAA\n"})
require(!ProgressReporter::validMediaURL(invalid), "noncanonical URLs are rejected");
const std::string genericURL = "https://video.example/watch?label=\"quoted\"&id=123#part";
require(ProgressReporter::validMediaURL(genericURL) &&
ProgressReporter::validMediaURL("http://127.0.0.1:8080/video.mp4"),
"HTTP(S) page identities are accepted beyond YouTube");
for (const char *invalid : {"", "file:///tmp/video.mp4", "ftp://example.com/video",
"https://", "https://user:secret@example.com/video", "https://example.com:0/video",
"https://example.com:65536/video", "https://example.com/video\n"})
require(!ProgressReporter::validMediaURL(invalid), "unsafe page identities are rejected");
const auto genericPath = root + "/generic.jsonl";
{
ProgressReporter reporter(genericPath, [] { return 0.; });
reporter.begin(genericURL);
reporter.observe(sample(PLAYER_PLAYING, 25));
reporter.finish();
require(reporter.error().empty(), "generic page progress drains successfully");
}
rows = records(genericPath);
require(rows.count == 2, "generic page has initial and terminal snapshots");
expect(rows[0], @"progress", genericURL, 25, true);
expect(rows[1], @"closed", genericURL, 25, true);
require(ProgressReporter::validMediaIdentity("miruro:opaque_A-1:12") &&
ProgressReporter::validMediaIdentity("miruro:a:2147483647"), "strict Miruro identities accepted");