import 'dart:typed_data'; import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; import 'package:flutter_sound/flutter_sound.dart'; import 'package:star_lock/talk/call/g711.dart'; import 'package:star_lock/talk/call/iFrameInfo.dart'; import 'package:star_lock/talk/udp/udp_talkClass.dart'; import '../../tools/eventBusEventManage.dart'; class CallTalk { static CallTalk? _manager; static int POS_iframe_index = 63; static int POS_alen = 65; static int POS_blen = 73; static int POS_bag_index = 71; static int POS_bag_num = 69; static int POS_data = 77; static int ABUF_NUM = 100; static int FIRSTINDEX = 1; int status = 0; // 假设有这个成员变量 IframeInfo? iframe; // 假设有这个成员变量 var growableList; bool getFirstFrame = false; //是否得到了第一帧 final FlutterSoundPlayer _audioPlayer = FlutterSoundPlayer(); List allPcmData = []; int _bufferSize = 400; // 设置缓冲区大小,根据需求调整 CallTalk._init() { iframe = IframeInfo(); } static CallTalk _share() { _manager ??= CallTalk._init(); return _manager!; } factory CallTalk() => _share(); CallTalk get manager => _share(); Future getAVData(Uint8List bb, int len) async { // 音频数据 if (bb[61] == 1) { Uint8List g711Data = bb.sublist(77, bb.length); List pcmBytes; try { // 将 ALaw 转为 Linear pcmBytes = G711().convertList(g711Data); allPcmData.addAll(pcmBytes); // await Future.delayed(const Duration(seconds: 1)); _initializeAudioPlayer(allPcmData); } catch (e) { print('Error decoding G.711 to PCM: $e'); } } // 视频数据 else { // 音视频数据开始下标 var bagLen = bb[POS_blen + 2] + bb[POS_blen + 3] * 256; // print('音视频数据开始下标 bagLen:$bagLen'); // 获取帧序号 63 int getIframeIndex = bb[POS_iframe_index] + bb[POS_iframe_index + 1] * 256; // print('获取帧序号 getIframeIndex:$getIframeIndex'); // 获取帧长度 65 // int alen = bb[POS_alen] & 0xff; // var alenList = bb.sublist(POS_alen, POS_alen + 4); // int alen = ((0xff & alenList[(0)]) << 24 | // (0xff & alenList[1]) << 16 | // (0xff & alenList[2]) << 8 | // (0xFF & alenList[3])); // print('获取帧长度 alen:$alen'); // 当前包号 71 int getBagIndex = bb[POS_bag_index] & 0xff; // print('当前包号 getBagIndex:$getBagIndex'); // 总包数 69 int getBagNum = bb[POS_bag_num] & 0xff; // print('总包数 getBagNum:$getBagNum'); // 数据长度 73 int blen = bb[POS_blen] + bb[POS_blen + 1] * 256; // print('数据长度 blen:$blen'); // 这里判断是否是同一帧,如果不是同一帧就重新创建一个 IframeInfo if (getIframeIndex != iframe!.iframeIndex) { iframe = IframeInfo(); iframe!.iframeIndex = getIframeIndex; iframe!.bagNum = getBagNum; // iframe!.cur_len = alen; // iframe!.bb = Uint8List(alen); growableList = iframe!.bb!.toList(growable: true); } iframe!.bagReceive++; // 如果是同一帧就添加起来 if (getIframeIndex == iframe!.iframeIndex) { var getList = bb.sublist(77, bb.length); growableList.addAll(getList); } // print('iframe.bagNum: ${iframe!.bagNum} iframe.bagReceive: ${iframe!.bagReceive}'); // 如果收到的包数等于总包数,说明这一帧数据已经接收完毕 if (iframe!.bagNum == iframe!.bagReceive) { // print('播放第${iframe!.iframeIndex}帧 一帧图片的hexStringData: ${Uint8List.fromList(growableList)}'); //判断第一帧是否接收到 if (iframe!.iframeIndex == 0) { getFirstFrame = true; eventBus.fire(GetFirstFrameGoPush(getFirstFrame)); } eventBus.fire(GetTVDataRefreshUI(growableList)); } } } //视频相关处理 void printByteArray(String printTitle, Uint8List byteArray) { final int chunkSize = byteArray.length; // 每行显示的字节数 int length = byteArray.length; for (int i = 0; i < length; i += chunkSize) { int end = (i + chunkSize < length) ? i + chunkSize : length; Uint8List chunk = byteArray.sublist(i, end); String hexString = chunk.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join(' '); debugPrint(hexString); } } //音频相关处理 Future _initializeAudioPlayer(List audioData) async { // _audioPlayer.closePlayer(); _audioPlayer.openPlayer(); // await _audioPlayer // .setSubscriptionDuration(const Duration(milliseconds: 10)); if (audioData.isNotEmpty) { // 在这里处理你的音频数据 print('转换pcmBytes数据长度为:${audioData.length}'); // _playRawData(audioData); playAudioStream(audioData); } else { print('Failed to read audio data.'); } } Future _playRawData(List rawData) async { print( '啊啦啦啦啦啦数据长度为:${G711().convertToInt8ListLittleEndian(rawData).length}, 数据为 ${G711().convertToInt8ListLittleEndian(rawData)}'); await _audioPlayer.startPlayer( fromDataBuffer: G711().convertToInt8ListLittleEndian(rawData), codec: Codec.pcm16, sampleRate: 8000, numChannels: 1, ); } Future playAudioStream(List audioData) async { await _audioPlayer .setSubscriptionDuration(const Duration(milliseconds: 10)); // 启动播放器 await _audioPlayer.startPlayer( codec: Codec.pcm16, sampleRate: 8000, numChannels: 1, ); // 将音频数据逐步添加到缓冲区 for (int i = 0; i < audioData.length; i += 320) { int chunkSize = 320; if (i + chunkSize > audioData.length) { chunkSize = audioData.length - i; } List chunk = audioData.sublist(i, i + chunkSize); await _audioPlayer .feedFromStream(G711().convertToInt8ListLittleEndian(chunk)); } // 停止播放器 await _audioPlayer.stopPlayer(); } }