feat: import Chinese-localized Buzz source snapshot
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Signed-off-by: cls_宁波本机 <908705107@qq.com>
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:buzz/shared/relay/mp4_fast_start.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
late Directory tempDirectory;
|
||||
|
||||
setUp(() async {
|
||||
tempDirectory = await Directory.systemTemp.createTemp(
|
||||
'buzz-faststart-test-',
|
||||
);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
await tempDirectory.delete(recursive: true);
|
||||
});
|
||||
|
||||
for (final offsetBox in ['stco', 'co64']) {
|
||||
test('moves moov before mdat and patches $offsetBox offsets', () async {
|
||||
final ftyp = _box('ftyp', [
|
||||
...ascii.encode('isom'),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
...ascii.encode('isom'),
|
||||
]);
|
||||
final mdat = _box('mdat', [1, 2, 3, 4]);
|
||||
final originalMediaOffset = ftyp.length + 8;
|
||||
final offsetPayload = BytesBuilder()
|
||||
..add([0, 0, 0, 0])
|
||||
..add(_uint32(1))
|
||||
..add(
|
||||
offsetBox == 'stco'
|
||||
? _uint32(originalMediaOffset)
|
||||
: _uint64(originalMediaOffset),
|
||||
);
|
||||
final sampleTable = _box(offsetBox, offsetPayload.takeBytes());
|
||||
final moov = _nestedMoov(sampleTable);
|
||||
final sourceBytes = Uint8List.fromList([...ftyp, ...mdat, ...moov]);
|
||||
final source = File('${tempDirectory.path}/source.mp4');
|
||||
final destination = File('${tempDirectory.path}/output.mp4');
|
||||
await source.writeAsBytes(sourceBytes);
|
||||
|
||||
await rewriteMp4ForFastStart(source, destination);
|
||||
|
||||
final output = await destination.readAsBytes();
|
||||
expect(_topLevelTypes(output), ['ftyp', 'moov', 'mdat']);
|
||||
expect(
|
||||
output.sublist(ftyp.length + moov.length + 8),
|
||||
equals([1, 2, 3, 4]),
|
||||
);
|
||||
|
||||
final typeOffset = _findAscii(output, offsetBox);
|
||||
expect(typeOffset, greaterThanOrEqualTo(4));
|
||||
final entryOffset = typeOffset + 12;
|
||||
final adjusted = offsetBox == 'stco'
|
||||
? _readUint32(output, entryOffset)
|
||||
: _readUint64(output, entryOffset);
|
||||
expect(adjusted, originalMediaOffset + moov.length);
|
||||
});
|
||||
}
|
||||
|
||||
test(
|
||||
'rejects excessive nested box depth and deletes partial output',
|
||||
() async {
|
||||
final ftyp = _box('ftyp', [
|
||||
...ascii.encode('isom'),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
...ascii.encode('isom'),
|
||||
]);
|
||||
final mdat = _box('mdat', [1]);
|
||||
var nested = _box('stco', [0, 0, 0, 0, ..._uint32(0)]);
|
||||
for (var index = 0; index < 34; index++) {
|
||||
nested = _box('stbl', nested);
|
||||
}
|
||||
final source = File('${tempDirectory.path}/deep.mp4');
|
||||
final destination = File('${tempDirectory.path}/output.mp4');
|
||||
await source.writeAsBytes([...ftyp, ...mdat, ..._box('moov', nested)]);
|
||||
|
||||
await expectLater(
|
||||
rewriteMp4ForFastStart(source, destination),
|
||||
throwsA(isA<FormatException>()),
|
||||
);
|
||||
expect(await destination.exists(), isFalse);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Uint8List _nestedMoov(List<int> leaf) =>
|
||||
_box('moov', _box('trak', _box('mdia', _box('minf', _box('stbl', leaf)))));
|
||||
|
||||
Uint8List _box(String type, List<int> payload) => Uint8List.fromList([
|
||||
..._uint32(payload.length + 8),
|
||||
...ascii.encode(type),
|
||||
...payload,
|
||||
]);
|
||||
|
||||
Uint8List _uint32(int value) {
|
||||
final bytes = ByteData(4)..setUint32(0, value, Endian.big);
|
||||
return bytes.buffer.asUint8List();
|
||||
}
|
||||
|
||||
Uint8List _uint64(int value) {
|
||||
final bytes = ByteData(8)..setUint64(0, value, Endian.big);
|
||||
return bytes.buffer.asUint8List();
|
||||
}
|
||||
|
||||
int _readUint32(Uint8List bytes, int offset) =>
|
||||
ByteData.sublistView(bytes).getUint32(offset, Endian.big);
|
||||
|
||||
int _readUint64(Uint8List bytes, int offset) =>
|
||||
ByteData.sublistView(bytes).getUint64(offset, Endian.big);
|
||||
|
||||
List<String> _topLevelTypes(Uint8List bytes) {
|
||||
final types = <String>[];
|
||||
var offset = 0;
|
||||
while (offset < bytes.length) {
|
||||
final size = _readUint32(bytes, offset);
|
||||
types.add(ascii.decode(bytes.sublist(offset + 4, offset + 8)));
|
||||
offset += size;
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
int _findAscii(Uint8List bytes, String value) {
|
||||
final needle = ascii.encode(value);
|
||||
for (var offset = 0; offset + needle.length <= bytes.length; offset++) {
|
||||
var matches = true;
|
||||
for (var index = 0; index < needle.length; index++) {
|
||||
if (bytes[offset + index] != needle[index]) {
|
||||
matches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (matches) return offset;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
Reference in New Issue
Block a user