import 'dart:async'; import 'package:fis_common/event/event_type.dart'; import 'package:fis_common/index.dart'; import 'package:fis_vid/async_vid/vid_data.dart'; import 'package:flutter/foundation.dart'; import 'package:vid/us/vid_us_data_http_reader.dart'; import 'package:vid/us/vid_us_image.dart'; import 'package:vid/us/vid_us_image_data.dart'; import 'package:vid/us/vid_us_probe.dart'; import 'channel_stub.dart' if (dart.library.html) 'channel_web.dart' if (dart.library.io) 'channel_io.dart'; import 'progress_info.dart'; abstract class VidDataChannel { @protected AsyncVidImageDataBase? source; bool get _isVrdPlayer => url.endsWith(".0"); final String url; VidDataChannel(this.url); factory VidDataChannel.create(String url) { return VidDataChannelImpl(url); } static void receiveChunk(String id, Uint8List chunk) { VidDataChannelImpl.receiveChunk(id, chunk); } /// 下载进度变更事件 final downloadProgressChanged = FEventHandler(); bool _initialized = false; /// 是否初始化完成 bool get initialized => _initialized; /// 开始加载数据 /// /// [timeout] 超时时间,单位ms, 默认5s Future load([int timeout = 5 * 1000]) async { if (_initialized) return true; try { _initialized = await _innerLoad(timeout); } catch (e) {} return _initialized; } /// 分发下载进度回调 @protected void onDownloadCallback(double progress, DownloadErrorException? error) { final info = VidDownloadProgressInfo(progress, error: error); downloadProgressChanged.emit(this, info); } Future _innerLoad(int timeout) async { try { source = await buildSource(); source!.setReadHeaderTimeout(timeout + 50); // 50ms buffer 4 timer await source!.initialize(); print("_innerLoad initialize end"); return true; } catch (e) { return false; } } ///获取缓冲量 int getBufferSize() { return source!.getReader().downloadedSize; } /// 获取文件尺寸 int getFileSize() { return source!.getReader().totalSize; } /// 是否缓冲完成 bool get isBufferedDone { var bufferSize = getBufferSize(); var fileSized = getFileSize(); var result = bufferSize >= fileSized; print("是否缓冲完成:$result $bufferSize $fileSized"); return result; } VidUsProbe get probe => source!.probe; int get imageCount => source!.imageCount; VidUsImageFormat get imageFormat => source!.imageFormat; Uint8List get extendedData => source!.extendedData; /// 获取指定帧 /// /// [index] 帧索引 /// /// [timeout] 超时时间ms Future getImage(int index, [int timeout = 500]) async { source!.setReadImageTimeout(timeout); return source!.getImage(index); } bool isBufferedDoneForFrames(int index) { if (_isVrdPlayer) { bool result = source!.getReader().frames.containsKey(index); if (result) { result = source!.getReader().frames[index]!.isNotEmpty; } return result; } else { return false; } } /// 关闭通道 void close() { _initialized = false; try { source?.close(); } catch (e) {} } @protected Future buildSource(); }