import 'dart:async'; import 'dart:typed_data'; import 'package:flutter/services.dart'; /// OPUS解码参数选项 class OpusOption { /// 是否具有协议头 final bool hasHeader; /// 通道数。取值范围:[1, 2] final int channel; /// 采样率。参考值:{8000, 16000, 24000, 32000, 44100, 48000} final int sampleRate; /// 数据包长度。仅hasHeader = false时生效。 final int packetSize; /// 构造函数 OpusOption({ this.hasHeader = false, this.channel = 1, this.sampleRate = 16000, this.packetSize = 40, }); /// 转换为参数Map Map toMap() { return { 'hasHeader': hasHeader, 'channel': channel, 'sampleRate': sampleRate, 'packetSize': packetSize, }; } } /// 杰理OPUS编解码器事件 class OpusEvent { /// 事件类型 final String event; /// 数据类型 (file或stream) final String? type; /// 解码后的数据 (仅在流解码时有效) final Uint8List? data; /// 输出文件路径 (仅在文件解码完成时有效) final String? filePath; /// 错误码 (仅在发生错误时有效) final int? errorCode; /// 错误信息 (仅在发生错误时有效) final String? errorMessage; /// 构造函数 OpusEvent({ required this.event, this.type, this.data, this.filePath, this.errorCode, this.errorMessage, }); /// 从Map构造对象 factory OpusEvent.fromMap(Map map) { return OpusEvent( event: map['event'], type: map['type'], data: map['data'], filePath: map['filePath'], errorCode: map['code'], errorMessage: map['message'], ); } } /// 杰理OPUS编解码插件 class JlOpus { static const MethodChannel _methodChannel = MethodChannel('com.yunqiinnovation.jl_opus'); static const EventChannel _eventChannel = EventChannel('com.yunqiinnovation.jl_opus/events'); /// 事件流 Stream? _eventStream; /// 获取事件流 Stream get eventStream { _eventStream ??= _eventChannel.receiveBroadcastStream().map((event) { if (event is Map) { return OpusEvent.fromMap(event); } throw PlatformException( code: 'INVALID_EVENT', message: '无效的事件数据', ); }); return _eventStream!; } /// 解码后的数据流 final StreamController _decodedDataController = StreamController.broadcast(); /// 获取解码数据流 Stream get decodedDataStream => _decodedDataController.stream; /// 构造函数,设置事件监听 JlOpus() { _setupEventListener(); } /// 设置事件监听 void _setupEventListener() { eventStream.listen((event) { if (event.event == 'onDecodeStream' && event.data != null) { _decodedDataController.add(event.data!); } }); } /// 初始化OPUS解码器 Future initOpusDecoder() async { try { final result = await _methodChannel.invokeMethod('initOpusDecoder'); return result ?? false; } catch (e) { return false; } } /// 解码OPUS文件 /// /// [inPath] 输入文件路径 /// [outPath] 输出文件路径 /// [option] 解码参数 Future decodeOpusFile(String inPath, String outPath, OpusOption option) async { try { final result = await _methodChannel.invokeMethod( 'decodeOpusFile', { 'inPath': inPath, 'outPath': outPath, ...option.toMap(), }, ); return result; } catch (e) { rethrow; } } /// 开始解码OPUS数据流 /// /// [option] 解码参数 Future startDecodeStream(OpusOption option) async { try { final result = await _methodChannel.invokeMethod( 'startDecodeStream', option.toMap(), ); return result ?? false; } catch (e) { rethrow; } } /// 停止解码OPUS数据流 Future stopDecodeStream() async { try { final result = await _methodChannel.invokeMethod('stopDecodeStream'); return result ?? false; } catch (e) { return false; } } /// 写入OPUS音频数据进行解码 /// /// [data] OPUS音频数据 Future writeAudioStream(Uint8List data) async { try { final result = await _methodChannel.invokeMethod( 'writeAudioStream', {'data': data}, ); return result ?? false; } catch (e) { rethrow; } } /// 判断是否正在解码 Future isDecoding() async { try { final result = await _methodChannel.invokeMethod('isDecoding'); return result ?? false; } catch (e) { return false; } } /// 释放资源 Future dispose() async { try { _decodedDataController.close(); final result = await _methodChannel.invokeMethod('dispose'); return result ?? false; } catch (e) { return false; } } }