Files
plezy/lib/utils/resolution_label.dart
T

47 lines
2.1 KiB
Dart
Raw Normal View History

2026-04-26 02:34:09 +02:00
/// Map a video stream height (pixels) onto the canonical resolution label
/// the rest of the app uses (`'4k'`, `'1080'`, `'720'`, `'480'`, or the raw
/// height for non-standard sizes). Returns `null` when [height] is null.
///
/// Plex hands the label back already in its `Media.videoResolution` field;
/// Jellyfin only gives raw pixel dimensions, which the Jellyfin mapper feeds
/// through [resolutionLabelFromDimensions] to produce the same shape.
2026-04-26 02:34:09 +02:00
String? resolutionLabelFromHeight(int? height) {
if (height == null) return null;
if (height >= 2160) return '4k';
if (height >= 1080) return '1080';
if (height >= 720) return '720';
if (height >= 480) return '480';
return height.toString();
}
2026-05-19 20:12:19 +02:00
/// Convenience overload that takes width + height. Width is considered first
/// for scope-cropped files, e.g. `3840x1608` should still be labeled `4k`.
String? resolutionLabelFromDimensions(int? width, int? height) {
if ((width != null && width >= 3840) || (height != null && height >= 2160)) return '4k';
if ((width != null && width >= 1920) || (height != null && height >= 1080)) return '1080';
if ((width != null && width >= 1280) || (height != null && height >= 720)) return '720';
if ((width != null && width >= 854) || (height != null && height >= 480)) return '480';
return resolutionLabelFromHeight(height);
}
final _numericResolutionValue = RegExp(r'^(\d+)(?:p)?$');
/// Format a canonical resolution label — or a raw numeric height, with or
/// without a trailing `p` — for display: `'1080'`/`'1080p'` → `'1080p'`,
/// `'4k'`/`'uhd'`/heights ≥ 2160 → `'4K'`, `'sd'` → `'SD'`; anything else is
/// uppercased verbatim.
String resolutionDisplayLabel(String value) {
final normalized = value.trim().toLowerCase();
if (normalized == '4k' || normalized == 'uhd') return '4K';
if (normalized == 'sd') return 'SD';
final numeric = _numericResolutionValue.firstMatch(normalized);
if (numeric != null) {
final height = int.tryParse(numeric.group(1)!);
if (height != null && height >= 2160) return '4K';
return '${numeric.group(1)}p';
}
return value.trim().toUpperCase();
}