fix(playback): use display criteria for matching

This commit is contained in:
edde746
2026-05-15 19:46:04 +02:00
parent ef4980db09
commit 5df3ec0c12
13 changed files with 59 additions and 55 deletions
+7 -8
View File
@@ -5,7 +5,7 @@ import 'package:plezy/services/file_info_parser.dart';
/// represented by its own [FileInfoStreamReader] implementation, so the
/// tests fix two things:
/// 1. The walker's accounting (single video pointer, every audio + sub
/// tracked, frame rate captured once).
/// tracked, raw video stream retained once).
/// 2. Each reader's mapping from raw JSON to the neutral track classes.
void main() {
group('walkStreams (Plex reader)', () {
@@ -50,7 +50,7 @@ void main() {
expect(out.videoStream?['id'], 100);
expect(out.audioStream?['id'], 101);
expect(out.frameRate, closeTo(23.976, 1e-6));
expect(out.videoStream?['frameRate'], closeTo(23.976, 1e-6));
expect(out.audioTracks.map((t) => t.id), [101, 102]);
expect(out.audioTracks[0].channels, 6);
expect(out.audioTracks[0].selected, isTrue);
@@ -74,7 +74,7 @@ void main() {
expect(out.audioTracks, isEmpty);
expect(out.subtitleTracks, isEmpty);
expect(out.videoStream?['id'], 3);
expect(out.frameRate, 24.0);
expect(out.videoStream?['frameRate'], 24);
});
test('skips non-Map entries gracefully', () {
@@ -84,7 +84,6 @@ void main() {
expect(out.audioStream, isNull);
expect(out.audioTracks, isEmpty);
expect(out.subtitleTracks, isEmpty);
expect(out.frameRate, isNull);
});
});
@@ -111,7 +110,7 @@ void main() {
expect(out.videoStream?['Index'], 0);
expect(out.audioStream?['Index'], 1);
expect(out.frameRate, closeTo(23.976, 1e-6));
expect(out.videoStream?['RealFrameRate'], closeTo(23.976, 1e-6));
expect(out.audioTracks.map((t) => t.id), [1, 2]);
expect(out.audioTracks[0].selected, isTrue);
expect(out.audioTracks[0].languageCode, 'eng');
@@ -130,12 +129,12 @@ void main() {
expect(out.audioTracks.map((t) => t.id), [1, 7, 3]);
});
test('frameRateOf falls back to AverageFrameRate when RealFrameRate is null', () {
test('captures video stream when only AverageFrameRate is present', () {
final streams = [
{'Type': 'Video', 'AverageFrameRate': 25.0},
];
final out = walkStreams(streams, reader);
expect(out.frameRate, 25.0);
expect(out.videoStream?['AverageFrameRate'], 25.0);
});
test('skips streams with unknown Type', () {
@@ -172,7 +171,7 @@ void main() {
expect(jf.audioTracks, hasLength(1));
expect(plex.subtitleTracks, hasLength(1));
expect(jf.subtitleTracks, hasLength(1));
expect(plex.frameRate, jf.frameRate);
expect(plex.videoStream?['frameRate'], jf.videoStream?['RealFrameRate']);
expect(plex.audioTracks.first.codec, jf.audioTracks.first.codec);
expect(plex.audioTracks.first.channels, jf.audioTracks.first.channels);
expect(plex.audioTracks.first.selected, jf.audioTracks.first.selected);
+2 -2
View File
@@ -51,7 +51,7 @@ void main() {
expect(info.audioTracks.length, 2);
expect(info.subtitleTracks.length, 1);
expect(info.frameRate, closeTo(23.976, 0.001));
expect(info.displayCriteria?.fps, closeTo(23.976, 0.001));
// Plex partId is null on Jellyfin because Jellyfin persists selected
// stream indexes through playback progress reports instead.
expect(info.getPartId(), isNull);
@@ -142,7 +142,7 @@ void main() {
final info = jellyfinMediaSourceToMediaSourceInfo({'Id': 'x'});
expect(info.audioTracks, isEmpty);
expect(info.subtitleTracks, isEmpty);
expect(info.frameRate, isNull);
expect(info.displayCriteria, isNull);
});
test('uses Jellyfin default stream indexes over per-stream default flags', () {
+1 -1
View File
@@ -44,7 +44,7 @@ void main() {
expect(result.availableVersions, hasLength(2));
expect(result.availableVersions.first.isPlayable, isFalse);
expect(result.mediaInfo?.partId, 20);
expect(result.mediaInfo?.frameRate, 23.976);
expect(result.mediaInfo?.displayCriteria?.fps, 23.976);
expect(result.mediaInfo?.audioTracks.single.languageCode, 'eng');
});