222 lines
4.6 KiB
Text
222 lines
4.6 KiB
Text
// ignore_for_file: avoid_print
|
|
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:integration_test/integration_test.dart';
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
import 'package:aves/services/cast/cast_fmp4_fragment_parser.dart';
|
|
|
|
void main() {
|
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
const channel = MethodChannel(
|
|
'aves/cast_video_optimizer',
|
|
);
|
|
|
|
testWidgets(
|
|
'genera il primo segmento TS dal fragmented MP4',
|
|
(tester) async {
|
|
final cacheDirectory = await getApplicationCacheDirectory();
|
|
|
|
final inputFile = File(
|
|
'${cacheDirectory.path}/stream_test.fmp4',
|
|
);
|
|
|
|
final outputFile = File(
|
|
'${cacheDirectory.path}/segment_00000.ts',
|
|
);
|
|
|
|
expect(
|
|
await inputFile.exists(),
|
|
isTrue,
|
|
reason: 'Copia prima stream_test.fmp4 nella cache Android',
|
|
);
|
|
|
|
expect(
|
|
await inputFile.length(),
|
|
greaterThan(2344107),
|
|
);
|
|
|
|
if (await outputFile.exists()) {
|
|
await outputFile.delete();
|
|
}
|
|
|
|
final partialOutput = File(
|
|
'${outputFile.path}.part',
|
|
);
|
|
|
|
if (await partialOutput.exists()) {
|
|
await partialOutput.delete();
|
|
}
|
|
|
|
const moofOffset = 1684;
|
|
const moofSize = 3164;
|
|
const mdatOffset = 4848;
|
|
const mdatSize = 2339259;
|
|
const mdatHeaderSize = 8;
|
|
|
|
final source = await inputFile.open(
|
|
mode: FileMode.read,
|
|
);
|
|
|
|
late final List<int> moofBytes;
|
|
|
|
try {
|
|
await source.setPosition(
|
|
moofOffset,
|
|
);
|
|
|
|
moofBytes = await source.read(
|
|
moofSize,
|
|
);
|
|
} finally {
|
|
await source.close();
|
|
}
|
|
|
|
expect(
|
|
moofBytes.length,
|
|
moofSize,
|
|
);
|
|
|
|
const parser = CastFmp4FragmentParser();
|
|
|
|
final fragment = parser.parse(
|
|
moofBytes: Uint8List.fromList(
|
|
moofBytes,
|
|
),
|
|
moofOffset: moofOffset,
|
|
mdatOffset: mdatOffset,
|
|
mdatSize: mdatSize,
|
|
mdatHeaderSize: mdatHeaderSize,
|
|
initialDecodeTimes: const <int, int>{
|
|
1: 0,
|
|
2: 0,
|
|
},
|
|
);
|
|
|
|
final audioTrack = fragment.tracks.singleWhere(
|
|
(track) => track.trackId == 1,
|
|
);
|
|
|
|
final videoTrack = fragment.tracks.singleWhere(
|
|
(track) => track.trackId == 2,
|
|
);
|
|
|
|
final audioSamples = audioTrack.samples
|
|
.where(
|
|
(sample) => sample.decodeTime < 144000,
|
|
)
|
|
.map(_sampleToMap)
|
|
.toList(growable: false);
|
|
|
|
final videoSamples = videoTrack.samples
|
|
.where(
|
|
(sample) => sample.decodeTime < 270000,
|
|
)
|
|
.map(_sampleToMap)
|
|
.toList(growable: false);
|
|
|
|
expect(
|
|
audioSamples.length,
|
|
inInclusiveRange(140, 143),
|
|
);
|
|
|
|
expect(
|
|
videoSamples.length,
|
|
90,
|
|
);
|
|
|
|
expect(
|
|
videoTrack.samples.first.isSync,
|
|
isTrue,
|
|
);
|
|
|
|
print(
|
|
'FMP4 TOOL INPUT '
|
|
'input=${inputFile.path} '
|
|
'audioSamples=${audioSamples.length} '
|
|
'videoSamples=${videoSamples.length}',
|
|
);
|
|
|
|
final report = await channel.invokeMapMethod<String, dynamic>(
|
|
'writeFmp4FirstTsSegmentTest',
|
|
<String, dynamic>{
|
|
'inputPath': inputFile.path,
|
|
'outputPath': outputFile.path,
|
|
'audioSamples': audioSamples,
|
|
'videoSamples': videoSamples,
|
|
},
|
|
);
|
|
|
|
expect(
|
|
report,
|
|
isNotNull,
|
|
);
|
|
|
|
expect(
|
|
report!['success'],
|
|
isTrue,
|
|
);
|
|
|
|
expect(
|
|
report['videoSamples'],
|
|
90,
|
|
);
|
|
|
|
expect(
|
|
report['audioSamples'],
|
|
inInclusiveRange(140, 143),
|
|
);
|
|
|
|
expect(
|
|
report['keyframes'],
|
|
3,
|
|
);
|
|
|
|
expect(
|
|
report['accessUnitDelimiterCount'],
|
|
90,
|
|
);
|
|
|
|
expect(
|
|
await outputFile.exists(),
|
|
isTrue,
|
|
);
|
|
|
|
final outputBytes = await outputFile.length();
|
|
|
|
expect(
|
|
outputBytes,
|
|
greaterThan(0),
|
|
);
|
|
|
|
expect(
|
|
outputBytes % 188,
|
|
0,
|
|
);
|
|
|
|
print(
|
|
'FMP4 FIRST TS TOOL PASS '
|
|
'output=${outputFile.path} '
|
|
'bytes=$outputBytes '
|
|
'report=$report',
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> _sampleToMap(
|
|
Fmp4SampleInfo sample,
|
|
) {
|
|
return <String, dynamic>{
|
|
'offset': sample.absoluteOffset,
|
|
'size': sample.size,
|
|
'dts': sample.decodeTime,
|
|
'pts': sample.presentationTime,
|
|
'duration': sample.duration,
|
|
'sync': sample.isSync,
|
|
};
|
|
}
|