Сохраните поток MotionJPEG в файл с помощью Dart

#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);
        }
      }
    }
  });
}