FFmpeg's protocol lookup is case-sensitive, so a stored "Https://" base URL reaches mpv verbatim through the direct-play string concat and fails with "Protocol not found" (API calls survive because Dart's Uri lowercases the scheme). Canonicalize at Jellyfin URL intake and in the connection constructor so persisted configs self-heal on load, and register mpv-escaped (https\://) redaction variants so option-value logs stop leaking the server host. close #1465
31 lines
1.3 KiB
Dart
31 lines
1.3 KiB
Dart
/// Backend-neutral URL helpers.
|
|
library;
|
|
|
|
/// Removes a single trailing `/` from [input] so subsequent path joins
|
|
/// don't produce double slashes (`http://host//Items` → `http://host/Items`).
|
|
/// Trims whitespace first; returns the input unchanged if it has no trailing
|
|
/// slash. Empty input returns empty.
|
|
String stripTrailingSlash(String input) {
|
|
final trimmed = input.trim();
|
|
if (trimmed.isEmpty) return trimmed;
|
|
if (trimmed.endsWith('/')) {
|
|
return trimmed.substring(0, trimmed.length - 1);
|
|
}
|
|
return trimmed;
|
|
}
|
|
|
|
final RegExp _schemePattern = RegExp(r'^[A-Za-z][A-Za-z\d+.-]*://');
|
|
|
|
/// Canonicalizes a server base URL: trims, strips one trailing `/`, and
|
|
/// lowercases the scheme (`Https://host` → `https://host`). Dart's `Uri`
|
|
/// normalizes scheme case for API requests, but URLs handed to the player as
|
|
/// raw strings don't get that treatment, and FFmpeg's protocol lookup is
|
|
/// case-sensitive — a mixed-case scheme fails with "Protocol not found".
|
|
/// Everything after `://` is left untouched.
|
|
String canonicalizeBaseUrl(String input) {
|
|
final stripped = stripTrailingSlash(input);
|
|
final match = _schemePattern.firstMatch(stripped);
|
|
if (match == null) return stripped;
|
|
return stripped.replaceRange(0, match.end, match.group(0)!.toLowerCase());
|
|
}
|