import 'dart:async'; import 'dart:typed_data'; import 'package:flutter/services.dart'; /// Opus 音频格式的应用类型 class OpusApplicationType { /// 通用音频编码 (OPUS_APPLICATION_AUDIO) static const int audio = 2048; /// 语音编码 (OPUS_APPLICATION_VOIP) static const int voip = 2048; /// 低延迟编码 (OPUS_APPLICATION_RESTRICTED_LOWDELAY) static const int restrictedLowDelay = 2051; } /// Opus 编解码插件,提供对 Opus 音频格式的编码和解码功能 class Opus { static const MethodChannel _channel = MethodChannel('com.yunqiinnovation.opus'); /// 创建 Opus 编码器实例 /// /// [sampleRate] 采样率 (Hz),常用值:8000, 16000, 24000, 48000 /// [channels] 声道数,1=单声道,2=立体声 /// [application] 应用类型,默认为音频编码 [OpusApplicationType.audio] /// [complexity] 复杂度 (0-10),数值越高质量越好,但CPU占用也更高 /// [frameSize] 编码帧大小,常用值:120, 240, 480, 960, 2880 /// /// 返回创建是否成功 static Future createEncoder({ int sampleRate = 48000, int channels = 2, int application = OpusApplicationType.audio, int complexity = 10, int frameSize = 960, }) async { try { final bool? success = await _channel.invokeMethod('createEncoder', { 'sampleRate': sampleRate, 'channels': channels, 'application': application, 'complexity': complexity, 'frameSize': frameSize, }); return success ?? false; } on PlatformException catch (e) { print('Failed to create Opus encoder: ${e.message}'); return false; } } /// 创建 Opus 解码器实例 /// /// [sampleRate] 采样率 (Hz),常用值:8000, 16000, 24000, 48000 /// [channels] 声道数,1=单声道,2=立体声 /// /// 返回创建是否成功 static Future createDecoder({ int sampleRate = 48000, int channels = 2, }) async { try { final bool? success = await _channel.invokeMethod('createDecoder', { 'sampleRate': sampleRate, 'channels': channels, }); return success ?? false; } on PlatformException catch (e) { print('Failed to create Opus decoder: ${e.message}'); return false; } } /// 编码 PCM 数据为 Opus 格式 /// /// [pcmData] 16位 PCM 音频数据 /// /// 返回编码后的 Opus 数据,如果失败返回 null static Future encodeData(Uint8List pcmData) async { try { final result = await _channel.invokeMethod('encodeData', { 'input': pcmData, }); return result; } on PlatformException catch (e) { print('Failed to encode data: ${e.message}'); return null; } } /// 解码 Opus 数据为 PCM 格式 /// /// [opusData] Opus 编码数据 /// [frameSize] 解码帧大小,需要与编码时使用的帧大小匹配 /// /// 返回解码后的 PCM 数据,如果失败返回 null static Future decodeData(Uint8List opusData, {int frameSize = 960}) async { try { final result = await _channel.invokeMethod('decodeData', { 'input': opusData, 'frameSize': frameSize, }); return result; } on PlatformException catch (e) { print('Failed to decode data: ${e.message}'); return null; } } /// 释放编码器资源 static Future disposeEncoder() async { try { await _channel.invokeMethod('disposeEncoder'); } on PlatformException catch (e) { print('Failed to dispose encoder: ${e.message}'); } } /// 释放解码器资源 static Future disposeDecoder() async { try { await _channel.invokeMethod('disposeDecoder'); } on PlatformException catch (e) { print('Failed to dispose decoder: ${e.message}'); } } }