#flutter #dart
Вопрос:
Я получаю поток MotionJPEG с видеокамеры и хочу сохранить поток в файл. Я начинаю с программы командной строки Dart. В настоящее время я сохраняю отдельные кадры в файл для проверки и анализа. Я хотел бы добавить возможность сохранения всего потока в файл. Я помещаю текущие сохраненные кадры в jpeg ниже. Я полагаю, что мне не нужно находить начало и конец каждого кадра, если я сохраню весь видеопоток в один файл. Однако я не могу понять, как открыть один файл для видео, а затем закрыть его. Я попытался добавить фрагменты в один файл, но полученное видео невозможно использовать. Может ли кто-нибудь подсказать, как сохранить фрагменты потока в один файл?
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
const int framesToSave = 5;
/// only works on SC2. Does not work with Z1 or V
void main() async {
http.Client client = http.Client();
Uri url = Uri.parse('http://192.168.1.1/osc/commands/execute');
var request = http.Request('POST', url);
Map<String, String> bodyMap = {"name": "camera.getLivePreview"};
request.body = jsonEncode(bodyMap);
Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8'
};
client.head(url, headers: headers);
http.StreamedResponse response = await client.send(request);
var startIndex = -1;
var endIndex = -1;
List<int> buf = [];
List<File> listOfFiles = [];
int frameCount = 0;
for (var i = 0; i < framesToSave; i ) {
listOfFiles.add(File('sc2_frame_$i.jpg'));
}
bool cancelledSubscription = false;
StreamSubscription? videoStream;
videoStream = response.stream.listen((List<int> data) async {
buf.addAll(data);
for (var i = 0; i < data.length - 1; i ) {
if (data[i] == 0xFF amp;amp; data[i 1] == 0xd8) {
startIndex = i;
print('found frame start');
}
if (data[i] == 0xff amp;amp; data[i 1] == 0xd9) {
endIndex = buf.length;
print('found frame end');
}
}
// save frame
if (!cancelledSubscription) {
if (startIndex != -1 amp;amp; endIndex != -1) {
try {
if (frameCount < framesToSave 1) {
// skip first frame as it does not seem to be correctly
// formatted
if (frameCount != 0) {
listOfFiles[frameCount - 1]
.writeAsBytes(buf.sublist(startIndex, endIndex));
}
print(frameCount);
frameCount ;
} else {
if (videoStream != null) {
await videoStream.cancel();
cancelledSubscription = true;
client.close();
}
}
} catch (error) {
print(error);
}
}
}
});
}