audio_player_handler.dart 3.34 KB
import 'package:appframe/bloc/web_cubit.dart';
import 'package:appframe/config/locator.dart';
import 'package:appframe/services/dispatcher.dart';
import 'package:appframe/services/player_service.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:uuid/uuid.dart';

class AudioPlayHandler extends MessageHandler {
  late WebCubit? _webCubit;

  @override
  Future<dynamic> handleMessage(dynamic params) async {
    try {
      if (params is! Map<String, dynamic>) {
        throw Exception('参数错误');
      }

      // 检测音量
      _webCubit!.checkVolume();

      final url = params['url'] as String;
      final seek = params['seek'] as int? ?? 0;
      // 暂时忽略
      // final isBg = params['isBg'] as bool ?? false;
      final playRate = (params['playRate'] as num?)?.toDouble() ?? 1.0;

      var playId = params['playId'] as String? ?? '';
      if (playId.isEmpty) {
        playId = Uuid().v4();
      }

      var playerService = getIt.get<PlayerService>();
      var result = false;
      try {
        result = await playerService.playAudio(url, seek, playId, playRate);
      } catch (e) {
        // 播放异常(下载失败/音频损坏/播放器重建失败等):提示用户后继续上抛,保持 H5 的错误回调语义
        _showPlayFailedToast();
        rethrow;
      }

      if (!result) {
        _showPlayFailedToast();
        throw Exception('播放错误');
      }
      return {'playId': playId};
    } finally {
      _unfollowCubit();
    }
  }

  @override
  void setCubit(WebCubit cubit) {
    this._webCubit = cubit;
  }

  /// 播放失败统一提示
  void _showPlayFailedToast() {
    Fluttertoast.showToast(msg: '无法播放该音频', gravity: ToastGravity.CENTER, backgroundColor: Colors.grey);
  }

  void _unfollowCubit() {
    this._webCubit = null;
  }
}

class AudioPauseHandler extends MessageHandler {
  @override
  Future<dynamic> handleMessage(dynamic params) async {
    return await getIt.get<PlayerService>().pauseAudio();
  }
}

class AudioResumeHandler extends MessageHandler {
  @override
  Future<dynamic> handleMessage(dynamic params) async {
    double? playRate = (params['playRate'] as num?)?.toDouble();
    return await getIt.get<PlayerService>().resumeAudio(playRate);
  }
}

class AudioSeekHandler extends MessageHandler {
  @override
  Future<dynamic> handleMessage(dynamic params) async {
    if (params is! Map<String, dynamic>) {
      throw Exception('参数错误');
    }

    final seek = params['seek'] as int;
    return await getIt.get<PlayerService>().seekAudio(seek);
  }
}

class AudioPlayRateHandler extends MessageHandler {
  @override
  Future<dynamic> handleMessage(dynamic params) async {
    if (params is! Map<String, dynamic>) {
      throw Exception('参数错误');
    }

    // var playId = params['playId'] as String? ?? '';
    final playRate = (params['playRate'] as num?)?.toDouble() ?? 1.0;

    return await getIt.get<PlayerService>().rateAudio(playRate);
  }
}

class AudioStopHandler extends MessageHandler {
  @override
  Future<dynamic> handleMessage(dynamic params) async {
    return await getIt.get<PlayerService>().stopAudio();
  }
}

class AudioClearHandler extends MessageHandler {
  @override
  Future<dynamic> handleMessage(dynamic params) async {
    await getIt.get<PlayerService>().clearAudio();
    return true;
  }
}