123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- import 'dart:convert';
- import 'dart:typed_data';
- import 'package:fis_common/env/env.dart';
- import 'package:fis_common/web/shell_api_hepler.dart';
- import 'package:flutter/foundation.dart';
- import 'package:vid/us/vid_us_data_http_reader.dart';
- import 'package:vid/us/vid_us_data_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 'reader.dart';
- import 'shell/reader.dart';
- abstract class AsyncVidImageDataBase {
- late AsyncVidDataReaderBase _reader;
- late List<int> _imagePositionList;
- late int _version;
- late int _imageCount;
- late VidUsProbe _probe;
- late VidUsImageFormat _imageFormat;
- late Uint8List _extendedData;
- late int _readHeaderTimeout;
- late int _readImageTimeout;
- late bool _initialized;
- late bool _closed;
- final Duration delayDuration = const Duration(milliseconds: 10);
- static final String vid_header = "VINNO IMAGE DATA";
- /// Gets the version of this image data.
- int get version => _version;
- /// Gets the image count of this image data.
- int get imageCount => _imageCount;
- /// Gets the probe information.
- VidUsProbe get probe => _probe;
- /// Gets the image format of this image data.
- VidUsImageFormat get imageFormat => _imageFormat;
- /// Gets the extended data.
- Uint8List get extendedData => _extendedData;
- /// Gets the initialized state.
- bool get initialized => _initialized;
- /// Create a VINNO Image Data.
- /// [readHeaderTimeout] is the timeout value of reading header and probe information etc..., we need give as much time as possible
- /// to let the reader read the header.
- /// [readImageTimeout] is the timeout value of reading one frame.
- /// [minChunkSize] The min download chunk size, set to a large value may speedup the download speed, but will cause the progress not smooth.
- AsyncVidImageDataBase(
- String url, {
- DownloadCallback? downloadCallback,
- int readHeaderTimeout = 3000,
- int readImageTimeout = 500,
- }) {
- _initialized = false;
- _closed = false;
- _readHeaderTimeout = readHeaderTimeout;
- _readImageTimeout = readImageTimeout;
- _reader = createReader(url, downloadCallback: downloadCallback);
- }
- @protected
- AsyncVidDataReaderBase createReader(String url,
- {DownloadCallback? downloadCallback});
- ///Get the downloaded data of this HttpVidUsImageData
- Uint8List getDownloadedData() {
- return _reader.toBytes();
- }
- void setReadHeaderTimeout(int timeout) => _readHeaderTimeout = timeout;
- void setReadImageTimeout(int timeout) => _readImageTimeout = timeout;
- ///Initialize the HttpVidUsImageData, must be called firstly.
- Future<bool> initialize() async {
- if (!_initialized) {
- String header;
- if (_reader.isVrd) {
- header = vid_header;
- } else {
- header = await _readHeader();
- }
- if (header != vid_header) {
- throw Exception("The input data is not a VID data.");
- }
- if (_reader.isVrd) {
- _version = await _getVersion();
- _probe = await _getProbe();
- _imageFormat = await _getImageFormat();
- _extendedData = await _getExtendedData();
- _imageCount = await _getImageCount();
- print('_imageCount:$_imageCount');
- } else {
- _version = await _readVersion();
- //Get probe info
- _probe = await _readProbe();
- _imageFormat = await _readImageFormat();
- _extendedData = await _readExtendedData();
- _imagePositionList = [];
- var imagePositionListData = await _readImagePositionListData();
- _imageCount = imagePositionListData.length ~/ 8;
- var imagePositionReader = VidUsDataReader(imagePositionListData);
- for (var i = 0; i < _imageCount; i++) {
- _imagePositionList.add(imagePositionReader.readInt64V2());
- }
- }
- _initialized = true;
- }
- return _initialized;
- }
- ///Close the HttpVidUsImageData, it will force close the download operation and reading operation.
- void close() {
- if (_closed) return;
- _closed = true;
- _reader.close();
- }
- T getReader<T extends AsyncVidDataReaderBase>() => _reader as T;
- ///Read header from http data.
- Future<String> _readHeader() async {
- var timeout = 0;
- while (!_closed) {
- try {
- var header = _reader.readString();
- return header;
- } catch (ex) {
- if (ex is NotReadyException) {
- if (timeout >= _readHeaderTimeout) {
- throw ReadTimeoutException();
- }
- await Future.delayed(delayDuration);
- timeout += delayDuration.inMilliseconds;
- } else {
- rethrow;
- }
- }
- }
- throw AlreadyClosedException();
- }
- ///Read the version from http data.
- Future<int> _readVersion() async {
- var timeout = 0;
- while (!_closed) {
- try {
- var version = _reader.readInt();
- return version;
- } catch (ex) {
- if (ex is NotReadyException) {
- if (timeout >= _readHeaderTimeout) {
- throw ReadTimeoutException();
- }
- await Future.delayed(delayDuration);
- timeout += delayDuration.inMilliseconds;
- } else {
- rethrow;
- }
- }
- }
- throw AlreadyClosedException();
- }
- ///Read the probe info from http data.
- Future<VidUsProbe> _readProbe() async {
- var timeout = 0;
- while (!_closed) {
- try {
- var probeData = _reader.readBytes();
- return VidUsProbe.fromBytes(probeData);
- } catch (ex) {
- if (ex is NotReadyException) {
- if (timeout >= _readHeaderTimeout) {
- throw ReadTimeoutException();
- }
- await Future.delayed(delayDuration);
- timeout += delayDuration.inMilliseconds;
- } else {
- rethrow;
- }
- }
- }
- throw AlreadyClosedException();
- }
- ///Read the image format from http data.
- Future<VidUsImageFormat> _readImageFormat() async {
- var timeout = 0;
- while (!_closed) {
- try {
- return VidUsImageFormat.values[_reader.readInt()];
- } catch (ex) {
- if (ex is NotReadyException) {
- if (timeout >= _readHeaderTimeout) {
- throw ReadTimeoutException();
- }
- await Future.delayed(delayDuration);
- timeout += delayDuration.inMilliseconds;
- } else {
- rethrow;
- }
- }
- }
- throw AlreadyClosedException();
- }
- ///Read extended data from http data.
- Future<Uint8List> _readExtendedData() async {
- var timeout = 0;
- while (!_closed) {
- try {
- return _reader.readBytes();
- } catch (ex) {
- if (ex is NotReadyException) {
- if (timeout >= _readHeaderTimeout) {
- throw ReadTimeoutException();
- }
- await Future.delayed(delayDuration);
- timeout += delayDuration.inMilliseconds;
- } else {
- rethrow;
- }
- }
- }
- throw AlreadyClosedException();
- }
- ///Read the image positions data from http data.
- Future<Uint8List> _readImagePositionListData() async {
- var timeout = 0;
- while (!_closed) {
- try {
- return _reader.readBytes();
- } catch (ex) {
- if (ex is NotReadyException) {
- if (timeout >= _readHeaderTimeout) {
- throw ReadTimeoutException();
- }
- await Future.delayed(delayDuration);
- timeout += delayDuration.inMilliseconds;
- } else {
- rethrow;
- }
- }
- }
- throw AlreadyClosedException();
- }
- /// Get one image from the vid.
- Future<VidUsImage> getImage(int index) async {
- if (index >= _imageCount || index < 0) {
- throw Exception(
- "Can not find image Data: index ($index) out of range ([0:${_imageCount - 1}])");
- }
- //Jump to image.
- var timeout = 0;
- while (!_closed) {
- try {
- print('_reader.readBytes index:$index start');
- Uint8List imageData;
- if (_reader.isVrd) {
- imageData = _reader.getImageBytes(index);
- if (imageData.isEmpty) {
- // _reader.skipToFrame(index);
- throw NotReadyException();
- }
- } else {
- imageData = _reader.readBytes(_imagePositionList[index]);
- }
- print('_reader.readBytes index:$index done');
- return VidUsImage.fromBytes(imageData);
- } catch (ex) {
- print('_reader.readBytes index:$index error ex:$ex');
- if (ex is NotReadyException) {
- if (timeout >= _readImageTimeout) {
- throw ReadTimeoutException();
- }
- await Future.delayed(delayDuration);
- timeout += delayDuration.inMilliseconds;
- } else {
- rethrow;
- }
- }
- }
- throw AlreadyClosedException();
- }
- Future<int> _getVersion() async {
- final result = await ShellApiHelper.call(
- 'getVersion',
- {
- 'Url': _reader.url,
- },
- );
- print('_getVersion:$result');
- return result;
- }
- Future<VidUsProbe> _getProbe() async {
- final result = await ShellApiHelper.call(
- 'getVinnoProbe',
- {
- 'Url': _reader.url,
- },
- );
- var probe = base64Decode(result);
- var probeResult = VidUsProbe.fromBytes(probe);
- print("probe : ${probeResult.name} ${probeResult.type}");
- return probeResult;
- }
- Future<VidUsImageFormat> _getImageFormat() async {
- final result = await ShellApiHelper.call(
- 'getImageFormat',
- {
- 'Url': _reader.url,
- },
- );
- return VidUsImageFormat.values
- .firstWhere((element) => element.index == result);
- }
- Future<Uint8List> _getExtendedData() async {
- final result = await ShellApiHelper.call(
- 'getExtendedData',
- {
- 'Url': _reader.url,
- },
- );
- return base64Decode(result);
- }
- Future<int> _getImageCount() async {
- final result = await ShellApiHelper.call(
- 'getImageCount',
- {
- 'Url': _reader.url,
- },
- );
- return result;
- }
- }
|