channel.dart 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import 'dart:async';
  2. import 'package:fis_common/event/event_type.dart';
  3. import 'package:fis_vid/async_vid/vid_data.dart';
  4. import 'package:flutter/foundation.dart';
  5. import 'package:vid/us/vid_us_data_http_reader.dart';
  6. import 'package:vid/us/vid_us_image.dart';
  7. import 'package:vid/us/vid_us_image_data.dart';
  8. import 'package:vid/us/vid_us_probe.dart';
  9. import 'channel_stub.dart'
  10. if (dart.library.html) 'channel_web.dart'
  11. if (dart.library.io) 'channel_io.dart';
  12. import 'progress_info.dart';
  13. abstract class VidDataChannel {
  14. @protected
  15. late final AsyncVidImageDataBase? source;
  16. final String url;
  17. VidDataChannel(this.url);
  18. factory VidDataChannel.create(String url) {
  19. return VidDataChannelImpl(url);
  20. }
  21. /// 下载进度变更事件
  22. final downloadProgressChanged = FEventHandler<VidDownloadProgressInfo>();
  23. bool _initialized = false;
  24. /// 是否初始化完成
  25. bool get initialized => _initialized;
  26. /// 开始加载数据
  27. ///
  28. /// [timeout] 超时时间,单位ms, 默认5s
  29. Future<bool> load([int timeout = 5 * 1000]) async {
  30. if (_initialized) return true;
  31. try {
  32. final completer = Completer<bool>();
  33. final timer = Timer(
  34. Duration(milliseconds: timeout),
  35. () {
  36. if (!completer.isCompleted) {
  37. completer.complete(_initialized);
  38. }
  39. if (!_initialized) {
  40. source?.close();
  41. }
  42. },
  43. );
  44. _innerLoad(timeout).then((value) {
  45. _initialized = true;
  46. if (timer.isActive) {
  47. timer.cancel();
  48. }
  49. completer.complete(true);
  50. });
  51. return completer.future;
  52. } catch (e) {
  53. return false;
  54. }
  55. }
  56. /// 分发下载进度回调
  57. @protected
  58. void onDownloadCallback(double progress, DownloadErrorException? error) {
  59. final info = VidDownloadProgressInfo(progress, error: error);
  60. downloadProgressChanged.emit(this, info);
  61. }
  62. Future<bool> _innerLoad(int timeout) async {
  63. try {
  64. source = await buildSource();
  65. source!.setReadHeaderTimeout(timeout + 50); // 50ms buffer 4 timer
  66. await source!.initialize();
  67. return true;
  68. } catch (e) {
  69. return false;
  70. }
  71. }
  72. ///获取缓冲量
  73. int getBufferSize() {
  74. return source!.getReader().downloadedSize;
  75. }
  76. /// 获取文件尺寸
  77. int getFileSize() {
  78. return source!.getReader().totalSize;
  79. }
  80. /// 是否缓冲完成
  81. bool get isBufferedDone {
  82. return getBufferSize() >= getFileSize();
  83. }
  84. VidUsProbe get probe => source!.probe;
  85. int get imageCount => source!.imageCount;
  86. VidUsImageFormat get imageFormat => source!.imageFormat;
  87. Uint8List get extendedData => source!.extendedData;
  88. /// 获取指定帧
  89. ///
  90. /// [index] 帧索引
  91. ///
  92. /// [timeout] 超时时间ms
  93. Future<VidUsImage> getImage(int index, [int timeout = 500]) async {
  94. source!.setReadImageTimeout(timeout);
  95. return source!.getImage(index);
  96. }
  97. /// 关闭通道
  98. void close() {
  99. _initialized = false;
  100. try {
  101. source?.close();
  102. } catch (e) {}
  103. }
  104. @protected
  105. Future<AsyncVidImageDataBase> buildSource();
  106. }