193 lines
4.2 KiB
Dart
193 lines
4.2 KiB
Dart
// ignore_for_file: avoid_print
|
|
|
|
import 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:aves/services/cast/cast_fmp4_fragment_parser.dart';
|
|
import 'package:aves/services/cast/cast_fmp4_progressive_reader.dart';
|
|
|
|
Future<void> main(List<String> arguments) async {
|
|
final sourcePath = arguments.isNotEmpty ? arguments.first : 'stream_test.fmp4';
|
|
|
|
final sourceFile = File(sourcePath);
|
|
|
|
if (!await sourceFile.exists()) {
|
|
throw StateError(
|
|
'File fMP4 non trovato: ${sourceFile.absolute.path}',
|
|
);
|
|
}
|
|
|
|
const expectedFragments = 5;
|
|
|
|
final fragments = <Fmp4FragmentInfo>[];
|
|
late final CastFmp4ProgressiveReader reader;
|
|
|
|
reader = CastFmp4ProgressiveReader(
|
|
sourcePath: sourceFile.path,
|
|
pollingInterval: const Duration(
|
|
milliseconds: 20,
|
|
),
|
|
onFragment: (fragment) async {
|
|
final fragmentIndex = fragments.length;
|
|
fragments.add(fragment);
|
|
|
|
final audio = fragment.tracks.singleWhere(
|
|
(track) => track.trackId == 1,
|
|
);
|
|
|
|
final video = fragment.tracks.singleWhere(
|
|
(track) => track.trackId == 2,
|
|
);
|
|
|
|
print(
|
|
'FRAGMENT '
|
|
'index=$fragmentIndex '
|
|
'moofOffset=${fragment.moofOffset} '
|
|
'mdatOffset=${fragment.mdatOffset} '
|
|
'audioSamples=${audio.sampleCount} '
|
|
'audioInitialDts=${audio.initialDecodeTime} '
|
|
'audioNextDts=${audio.nextDecodeTime} '
|
|
'videoSamples=${video.sampleCount} '
|
|
'videoInitialDts=${video.initialDecodeTime} '
|
|
'videoNextDts=${video.nextDecodeTime} '
|
|
'videoSyncSamples=${video.syncSampleCount}',
|
|
);
|
|
|
|
if (fragments.length >= expectedFragments) {
|
|
reader.requestStop();
|
|
}
|
|
},
|
|
);
|
|
|
|
await reader.start();
|
|
|
|
if (fragments.length != expectedFragments) {
|
|
throw StateError(
|
|
'Numero frammenti inatteso: '
|
|
'actual=${fragments.length} '
|
|
'expected=$expectedFragments',
|
|
);
|
|
}
|
|
|
|
const expectedAudioNextDts = <int>[
|
|
166912,
|
|
311296,
|
|
454656,
|
|
599040,
|
|
743424,
|
|
];
|
|
|
|
const expectedVideoNextDts = <int>[
|
|
270000,
|
|
540000,
|
|
810000,
|
|
1080000,
|
|
1350000,
|
|
];
|
|
|
|
for (var index = 0; index < fragments.length; index++) {
|
|
final fragment = fragments[index];
|
|
|
|
final audio = fragment.tracks.singleWhere(
|
|
(track) => track.trackId == 1,
|
|
);
|
|
|
|
final video = fragment.tracks.singleWhere(
|
|
(track) => track.trackId == 2,
|
|
);
|
|
|
|
_expectEqual(
|
|
'fragment[$index].audio.nextDts',
|
|
audio.nextDecodeTime,
|
|
expectedAudioNextDts[index],
|
|
);
|
|
|
|
_expectEqual(
|
|
'fragment[$index].video.nextDts',
|
|
video.nextDecodeTime,
|
|
expectedVideoNextDts[index],
|
|
);
|
|
|
|
_expectEqual(
|
|
'fragment[$index].video.sampleCount',
|
|
video.sampleCount,
|
|
90,
|
|
);
|
|
|
|
_expectEqual(
|
|
'fragment[$index].video.duration',
|
|
video.totalDuration,
|
|
270000,
|
|
);
|
|
|
|
if (!video.samples.first.isSync) {
|
|
throw StateError(
|
|
'Il frammento $index non inizia con un keyframe',
|
|
);
|
|
}
|
|
|
|
if (index > 0) {
|
|
final previous = fragments[index - 1];
|
|
|
|
final previousAudio = previous.tracks.singleWhere(
|
|
(track) => track.trackId == 1,
|
|
);
|
|
|
|
final previousVideo = previous.tracks.singleWhere(
|
|
(track) => track.trackId == 2,
|
|
);
|
|
|
|
_expectEqual(
|
|
'fragment[$index].audio.continuity',
|
|
audio.initialDecodeTime,
|
|
previousAudio.nextDecodeTime,
|
|
);
|
|
|
|
_expectEqual(
|
|
'fragment[$index].video.continuity',
|
|
video.initialDecodeTime,
|
|
previousVideo.nextDecodeTime,
|
|
);
|
|
}
|
|
}
|
|
|
|
_expectEqual(
|
|
'reader.fragmentCount',
|
|
reader.fragmentCount,
|
|
expectedFragments,
|
|
);
|
|
|
|
_expectEqual(
|
|
'reader.audioDecodeTime',
|
|
reader.decodeTimes[1] ?? -1,
|
|
743424,
|
|
);
|
|
|
|
_expectEqual(
|
|
'reader.videoDecodeTime',
|
|
reader.decodeTimes[2] ?? -1,
|
|
1350000,
|
|
);
|
|
|
|
print('');
|
|
print(
|
|
'FMP4 PROGRESSIVE READER TEST: PASS '
|
|
'fragments=${reader.fragmentCount} '
|
|
'audioDts=${reader.decodeTimes[1]} '
|
|
'videoDts=${reader.decodeTimes[2]}',
|
|
);
|
|
}
|
|
|
|
void _expectEqual(
|
|
String name,
|
|
int actual,
|
|
int expected,
|
|
) {
|
|
if (actual != expected) {
|
|
throw StateError(
|
|
'$name inatteso: '
|
|
'actual=$actual '
|
|
'expected=$expected',
|
|
);
|
|
}
|
|
}
|