123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- import 'dart:async';
- import 'dart:convert';
- import 'dart:typed_data';
- import 'package:fis_common/extensions/date.dart';
- import 'package:fis_common/index.dart';
- import 'package:fis_common/web/shell_api_hepler.dart';
- import 'package:vid/us/vid_us_data_http_reader.dart';
- import '../reader.dart';
- class AsyncShellVidDataReader extends AsyncVidDataReaderBase {
- final int minChunkSize;
- int _imageCount = 0;
- bool _isBreak = false;
- bool _isStop = false;
- int _skipFrameIndex = 0;
- Completer<void> _completer = Completer<void>();
- late final String id =
- DateTime.now().format('MMddHHmmssSSS') + hashCode.toString();
- AsyncShellVidDataReader(
- String url, {
- DownloadCallback? downloadCallback,
- this.minChunkSize = 65536,
- }) : super(url, downloadCallback: downloadCallback);
- @override
- void close() {
- _isStop = true;
- cancelFetchVid();
- }
- @override
- void startDownload() async {
- final size = await getFileSize();
- // 获取到size即开始下载
- if (size == null) {
- setError(true, 'Get file size fail.');
- } else if (isVrd) {
- _imageCount = size;
- fetchFrames(0, size, isNeedReload: true);
- }
- }
- @override
- Future<void> skipToFrame(int index) async {
- if (_skipFrameIndex == index || index == 0) {
- return;
- }
- //停用上个不断获取帧的请求
- if (!_completer.isCompleted) {
- _isStop = true;
- _completer.complete();
- }
- _skipFrameIndex = index;
- print(
- "_skipFrameIndex change:$_skipFrameIndex _completer:${_completer.isCompleted}");
- await Future.delayed(const Duration(milliseconds: 2000));
- _isStop = false;
- print("fetchFrames : $_skipFrameIndex $_imageCount");
- //从跳帧的位置开始不断获取数据
- fetchFrames(_skipFrameIndex, _imageCount, isNeedReload: true);
- }
- void cancelFetchVid() {
- ShellApiHelper.call('cancelFetchVid', id);
- }
- /// 接收分片数据
- void receiveChunk(Uint8List chunk) {
- appendChunk(chunk);
- final progress = downloadedSize / totalSize;
- print('updateProgress : $progress');
- updateProgress(progress);
- }
- //注意:此处VRD返回的是总帧数,非VRD返回的是数据大小
- Future<int?> getFileSize() async {
- final result = await ShellApiHelper.call(
- (isVrd) ? 'dynamicFetchVidAsync' : 'fetchVid',
- {
- 'Id': id,
- 'Url': url,
- 'MinChunkSize': minChunkSize,
- },
- );
- if (result != null) {
- if (isVrd) {
- _imageCount = result!;
- }
- initChunk(result);
- }
- await fetchFrames(0, 1, isNeedReload: true);
- print("getFileSize result:$result");
- return result;
- }
- @override
- Future<void> fetchFrames(int startIndex, int size,
- {bool isNeedReload = false}) async {
- _completer = Completer<void>();
- int batchSize = 5; // 每次获取的帧数
- try {
- for (int start = startIndex; start < size; start += batchSize) {
- if (_isStop) {
- break;
- }
- int end = start + batchSize;
- if (end > size) {
- end = size; // 确保最后一次获取不会超出范围
- }
- print("batchFetchFrames: start:$start end:$end");
- bool result = await batchFetchFrames(
- start,
- end,
- isNeedReload: isNeedReload,
- );
- if (_isStop) {
- break;
- }
- if (result == false) {
- continue;
- }
- }
- } finally {
- _completer.complete();
- }
- return _completer.future;
- }
- Future<bool> batchFetchFrames(
- int start,
- int end, {
- bool isNeedReload = false,
- }) async {
- print("batchFetchFrames : $start $end");
- final result = await ShellApiHelper.call(
- 'batchFetchFrames',
- {
- 'Id': id,
- 'Url': url,
- 'Start': start,
- 'End': end,
- },
- );
- if (_isStop) {
- return false;
- }
- if (result.toString().isEmpty) {
- print("batchFetchFrames result is empty");
- _isBreak = true;
- if (isNeedReload) {
- await Future.delayed(const Duration(milliseconds: 1000));
- return await batchFetchFrames(start, end, isNeedReload: isNeedReload);
- }
- return false;
- }
- List<String> base64Frames = result.toString().split("&");
- int index = start;
- for (var f in base64Frames) {
- var frame = base64Decode(f);
- appendFrame(frame, index);
- print("appendFrame ${frame.length} index: $index");
- //非空,且之前没有中断,则允许更新进度
- if (frame.isNotEmpty) {
- if (!_isBreak) {
- if (_isStop) {
- return false;
- }
- updateProgress(index / _imageCount);
- }
- } else {
- //如果遇到获取不到帧,则中断更新进度
- print('updateProgress isBreak true');
- _isBreak = true;
- }
- index++;
- }
- //base64Decode
- print("batchFetchFrames result:${base64Frames.length}");
- return true;
- }
- }
|