123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- import 'dart:async';
- import 'package:fis_i18n/i18n.dart';
- import 'package:fis_jsonrpc/rpc.dart';
- import 'package:fis_measure/interfaces/process/workspace/exam_info.dart';
- import 'package:fis_measure/interfaces/process/workspace/measure_3d_view_controller.dart';
- import 'package:fis_measure/interfaces/process/workspace/measure_controller.dart';
- import 'package:fis_measure/process/workspace/application.dart';
- import 'package:fis_measure/process/workspace/measure_3d_view_controller.dart';
- import 'package:fis_measure/process/workspace/third_part/application.dart';
- import 'package:fis_measure/utils/prompt_box.dart';
- import 'package:fis_measure/view/player/controller.dart';
- import 'package:fis_measure/view/player/enums.dart';
- import 'package:fis_measure/view/player/events.dart';
- import 'package:fis_measure/interfaces/process/workspace/application.dart';
- import 'package:fis_measure/interfaces/process/player/play_controller.dart';
- import 'package:fis_measure/interfaces/process/config/style_config.dart';
- import 'package:fis_common/event/event_type.dart';
- import 'package:fis_ui/index.dart';
- import 'package:get/get.dart';
- import 'package:vid/us/vid_us_image.dart';
- import 'measure_data_controller.dart';
- import 'package:universal_html/html.dart' as html;
- typedef MeasureImagesFetchFunc = Future<List<ExamImageInfo>> Function(
- String code);
- class MeasureController implements IMeasureController {
- late final ExamInfo _examInfo;
- IPlayerController? _playerController;
- IApplication? _application;
- int _recursive = 0;
- late bool _enableLoopPlayback;
- final ValueCallback<bool>? onLoopPlaybackEnableChanged;
- late final MeasureImagesFetchFunc _imagesFetchFunc;
- final measureData = Get.find<MeasureDataController>();
- final measure3DViewController = Get.find<Measure3DViewController>();
- MeasureController(
- String code, {
- required MeasureImagesFetchFunc imagesFetchFunc,
- bool enableLoopPlayback = false,
- this.onLoopPlaybackEnableChanged,
- }) {
- _enableLoopPlayback = enableLoopPlayback;
- _examInfo = ExamInfo(code);
- _imagesFetchFunc = imagesFetchFunc;
- }
- @override
- ExamInfo get examInfo => _examInfo;
- @override
- String get currentVidUrl => examInfo.selectedImage.url;
- @override
- bool get canDoMeasure => playerController.status == VidPlayStatus.pause;
- @override
- IPlayerController get playerController => _playerController!;
- @override
- // TODO: implement styleConfiguration
- IStyeConfiguration get styleConfiguration => throw UnimplementedError();
- @override
- IApplication get workingApplication => _application!;
- @override
- var imageLoaded = FEventHandler<ExamImageInfo?>();
- @override
- Future<void> load() async {
- final images = await _imagesFetchFunc.call(examInfo.code);
- examInfo.images.addAll(images);
- examInfo.selectedImageChanged.addListener(_onExamImageSelectedChanged);
- // // 加载第一张图像
- // examInfo.selectedImageIndex = 0;
- }
- @override
- void dispose() {
- examInfo.selectedImageChanged.removeListener(_onExamImageSelectedChanged);
- _playerController?.dispose();
- Get.delete<IApplication>();
- Get.delete<IPlayerController>();
- }
- /// 轮询下载接口
- void _recursivePlayer(Object sender) {
- playerController.load().then((_) async {
- if (playerController.status != VidPlayStatus.ready) {
- if (_recursive <= 2) {
- _recursive += 1;
- _recursivePlayer(sender);
- } else {
- PromptBox.toast(i18nBook.common.networkUnstable.t);
- _recursive = 0;
- _recursivePlayer(sender);
- // throw FlutterError("Vid file load fail.");
- }
- } else {
- playerController.eventHandler.addListener(_onPlayerEnvent);
- }
- });
- }
- void _onExamImageSelectedChanged(Object sender, int index) async {
- final url = currentVidUrl;
- _playerController?.firstFrameLoaded.removeListener(_onFirstFrameLoaded);
- _playerController?.frameUpdated.removeListener(_onFrameUpdated);
- _playerController?.eventHandler.removeListener(_onPlayerEnvent);
- _playerController?.dispose();
- Get.delete<IPlayerController>();
- _windowSetState(index);
- _playerController = Get.put<IPlayerController>(
- VidPlayerController(url)
- ..enableLoop = _enableLoopPlayback
- ..enableLoopChanged.addListener(_onEnableLoopPlaybackChanged),
- );
- playerController.firstFrameLoaded.addListener(_onFirstFrameLoaded);
- playerController.frameUpdated.addListener(_onFrameUpdated);
- playerController.eventHandler.addListener(_onPlayerEnvent);
- _tryLoadPlayer();
- }
- void _onEnableLoopPlaybackChanged(Object _, bool e) {
- _enableLoopPlayback = e;
- onLoopPlaybackEnableChanged?.call(e);
- }
- void _tryLoadPlayer() async {
- int tryCount = 0;
- const limitCount = 5;
- bool loaded = false;
- while (loaded == false) {
- if (limitCount <= tryCount) break;
- if (playerController.disposed) break;
- loaded = await playerController.load();
- if (loaded == false) {
- if (tryCount == 0) {
- PromptBox.toast(i18nBook.common.networkUnstable.t);
- }
- }
- tryCount++;
- }
- if (playerController.disposed) return;
- if (loaded) {
- _onPlayerLoaded();
- }
- }
- void _onPlayerLoaded() {
- _buildApplication();
- // 通知图像加载完成
- imageLoaded.emit(this, examInfo.selectedImage);
- }
- void _onFirstFrameLoaded(Object sender, VidUsImage frame) {
- workingApplication.loadFrame(frame);
- if (workingApplication.canMeasure) {
- if (workingApplication.frameData!.index != 0) {
- // 非首帧,切换第一个测量项
- final items = measureData.curItemMetaList;
- if (items.isNotEmpty) {
- workingApplication.switchItem(items.first);
- }
- }
- }
- /// 非颈动脉2D模式下需要将 isAdaptiveCarotid2D 置为 false
- if (measure3DViewController.curMeasureMode != MeasureMode.carotid2DMode) {
- workingApplication.isAdaptiveCarotid2D = false;
- }
- }
- void _onFrameUpdated(Object sender, VidUsImage frame) {
- if (frame.index != 0) workingApplication.loadFrame(frame);
- }
- void _onPlayerEnvent(Object sender, VidPlayerEvent e) {
- if (e is VidPlayerStatusChangeEvent) {
- _application?.canMeasure = e.status == VidPlayStatus.pause;
- }
- }
- Future<void> _buildApplication() async {
- final dataChannel = playerController.dataChannel;
- final probe = dataChannel.probe;
- final is3rd = probe.name == Application.C_VID_THIRDPART_NAME;
- IApplication app;
- if (is3rd) {
- app = ThirdPartApplication(probe, dataChannel.extendedData);
- } else {
- app = Application(probe);
- }
- Get.delete<IApplication>();
- _application = Get.put<IApplication>(app);
- _application!.isSingleFrame = dataChannel.imageCount == 1;
- }
- void _windowSetState(int index) {
- try {
- final measureData = Get.find<MeasureDataController>();
- var remedicalList = measureData.remedicalList;
- var examCode = examInfo.code;
- if (index > remedicalList.length - 1) {
- return;
- }
- var remedicalInfo = remedicalList[index];
- if (remedicalInfo != null) {
- var searchUrl = html.window.location.search ?? '';
- var remedicalCode = remedicalInfo.remedicalCode;
- var parameters = searchUrl.split('&');
- if (parameters.isNotEmpty) {
- var target = parameters
- .firstWhereOrNull((element) => element.contains("remedicalCode"));
- if (target != null) {
- var paraneter = "remedicalCode=$remedicalCode";
- var newSearchUrl = searchUrl.replaceAll(target, paraneter);
- html.window.history.replaceState('', '', newSearchUrl);
- }
- }
- }
- } catch (e) {}
- }
- }
|