From a9dfd3f847bbc67e27e58531d638b5eb5a1c61f0 Mon Sep 17 00:00:00 2001 From: Daisy <> Date: Fri, 22 Dec 2023 14:22:34 +0800 Subject: [PATCH] =?UTF-8?q?g711=E7=BC=96=E8=A7=A3=E7=A0=81=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- star_lock/lib/talk/call/callTalk.dart | 28 ++++---- star_lock/lib/talk/call/g711.dart | 89 ++++++++++++++++++++++++ star_lock/lib/talk/call/g711Decoder.dart | 36 ---------- star_lock/lib/talk/call/g711Encode.dart | 69 ------------------ star_lock/pubspec.yaml | 2 +- 5 files changed, 106 insertions(+), 118 deletions(-) create mode 100644 star_lock/lib/talk/call/g711.dart delete mode 100644 star_lock/lib/talk/call/g711Decoder.dart delete mode 100644 star_lock/lib/talk/call/g711Encode.dart diff --git a/star_lock/lib/talk/call/callTalk.dart b/star_lock/lib/talk/call/callTalk.dart index 4651ad0a..97b6ea57 100644 --- a/star_lock/lib/talk/call/callTalk.dart +++ b/star_lock/lib/talk/call/callTalk.dart @@ -1,11 +1,13 @@ import 'dart:typed_data'; +import 'package:convert/convert.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_ffmpeg/flutter_ffmpeg.dart'; import 'package:flutter_sound/flutter_sound.dart'; import 'package:get/get.dart'; import 'package:get/get_core/src/get_main.dart'; import 'package:star_lock/appRouters.dart'; import 'package:star_lock/main/lockDetail/monitoring/monitoring/lockMonitoring_page.dart'; -import 'package:star_lock/talk/call/g711Decoder.dart'; +import 'package:star_lock/talk/call/g711.dart'; import 'package:star_lock/talk/call/iFrameInfo.dart'; import '../../tools/eventBusEventManage.dart'; @@ -29,7 +31,6 @@ class CallTalk { CallTalk._init() { iframe = IframeInfo(); - _initializeAudioPlayer(); } static CallTalk _share() { @@ -43,18 +44,19 @@ class CallTalk { Future getAVData(Uint8List bb, int len) async { // 音频数据 if (bb[61] == 1) { - print('dinglingling bb.length:${bb.length} 音频数据来:$bb '); - // 用你的711音频数据替换这里的Uint8List - // Uint8List rawData = G711Decoder().decodeG711uLaw(bb); - // 示例 G711 数据(u-law 或 a-law) - Uint8List g711Data = bb.sublist(77, bb.length); - // 解码为 PCM 数据 - Uint8List pcmData = G711Decoder().g711Decode(g711Data, G711Type.uLaw); - // 现在你可以使用 pcmData 进行播放或其他处理 - print('得到的pcmData:$pcmData'); + print('dinglingling bb.length:${g711Data.length} 音频数据来:$g711Data '); + Uint8List? pcmBytes = await G711().decodeG711ToPCM(g711Data.toList()); - _playRawData(pcmData); + print('PCM decoded data: $pcmBytes'); + + if (pcmBytes != null) { + _initializeAudioPlayer(); + _playRawData(pcmBytes); + } else { + print('Error decoding G.711 to PCM'); + } + // 在这里处理你的 PCM 数据 } // 视频数据 else { @@ -144,6 +146,8 @@ class CallTalk { await _audioPlayer.startPlayer( fromDataBuffer: rawData, codec: Codec.pcm16, + numChannels: 1, + sampleRate: 8000, whenFinished: () { // 播放完成时的回调 print("Playback finished"); diff --git a/star_lock/lib/talk/call/g711.dart b/star_lock/lib/talk/call/g711.dart new file mode 100644 index 00000000..c3ab0ee7 --- /dev/null +++ b/star_lock/lib/talk/call/g711.dart @@ -0,0 +1,89 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:flutter_ffmpeg/flutter_ffmpeg.dart'; +import 'package:path_provider/path_provider.dart'; + +class G711 { + Future decodeG711ToPCM(List g711Data) async { + try { + FlutterFFmpeg flutterFFmpeg = FlutterFFmpeg(); + + // Save G.711 data to a temporary file + Directory appDocDir = await getApplicationDocumentsDirectory(); + String g711FilePath = '${appDocDir.path}/input.g711'; + await File(g711FilePath).writeAsBytes(g711Data); + + // Replace with the desired output PCM file path + String pcmFilePath = '${appDocDir.path}/output.pcm'; + + // Run FFmpeg command to decode G.711 to PCM + String command = + '-y -f u8 -ar 8000 -ac 1 -i $g711FilePath -f s16le -ar 8000 -ac 1 $pcmFilePath'; + int result = await flutterFFmpeg.execute(command); + + if (result == 0) { + print('G.711 decoding successful! PCM file saved at: $pcmFilePath'); + + // Read PCM data from file + Uint8List pcmBytes = await File(pcmFilePath).readAsBytes(); + + // Delete the temporary G.711 file + await File(g711FilePath).delete(); + + // Delete the temporary PCM file + await File(pcmFilePath).delete(); + + return pcmBytes; + } else { + print('Error during G.711 decoding: $result'); + return null; + } + } catch (e) { + print('Error: $e'); + return null; + } + } + + Future encodePCMToG711(Uint8List pcmData) async { + try { + FlutterFFmpeg flutterFFmpeg = FlutterFFmpeg(); + + // Save PCM data to a temporary file + Directory appDocDir = await getApplicationDocumentsDirectory(); + String pcmFilePath = '${appDocDir.path}/input.pcm'; + await File(pcmFilePath).writeAsBytes(pcmData); + + // Replace with the desired output G.711 file path + String g711FilePath = '${appDocDir.path}/output.g711'; + + // Run FFmpeg command to encode PCM to G.711 + String command = + '-y -f s16le -ar 8000 -ac 1 -i $pcmFilePath -f g711 -ar 8000 -ac 1 $g711FilePath'; + int result = await flutterFFmpeg.execute(command); + + if (result == 0) { + print( + 'PCM encoding to G.711 successful! G.711 file saved at: $g711FilePath'); + + // Read G.711 data from file + Uint8List g711Bytes = await File(g711FilePath).readAsBytes(); + + // Delete the temporary PCM file + await File(pcmFilePath).delete(); + + // Delete the temporary G.711 file + await File(g711FilePath).delete(); + + return g711Bytes; + } else { + print('Error during PCM encoding to G.711: $result'); + return null; + } + } catch (e) { + print('Error: $e'); + return null; + } + } +} diff --git a/star_lock/lib/talk/call/g711Decoder.dart b/star_lock/lib/talk/call/g711Decoder.dart deleted file mode 100644 index 2b1d5c74..00000000 --- a/star_lock/lib/talk/call/g711Decoder.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'dart:typed_data'; - -enum G711Type { - uLaw, - aLaw, -} - -class G711Decoder { - Uint8List g711Decode(Uint8List g711Data, G711Type g711Type) { - List pcmData = []; - int sign, exponent, mantissa, sample; - - for (int i = 0; i < g711Data.length; i++) { - int value = g711Data[i]; - - if (g711Type == G711Type.uLaw) { - // μ-law decoding - value = ~value & 0xFF; - sign = (value & 0x80) == 0 ? 1 : -1; - exponent = (value & 0x70) >> 4; - mantissa = ((value & 0x0F) << 4) + 0x10; - sample = (mantissa << exponent) * sign; - } else { - // A-law decoding - sign = (value & 0x80) == 0 ? 1 : -1; - exponent = ((value & 0x70) >> 4) + 1; - mantissa = (value & 0x0F) + 0x10; - sample = (mantissa << exponent) * sign; - } - - pcmData.add(sample); - } - - return Uint8List.fromList(pcmData); - } -} diff --git a/star_lock/lib/talk/call/g711Encode.dart b/star_lock/lib/talk/call/g711Encode.dart deleted file mode 100644 index 3c004a3c..00000000 --- a/star_lock/lib/talk/call/g711Encode.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'dart:typed_data'; - -enum G711Type { - uLaw, - aLaw, -} - -class G711Decoder { - Uint8List g711Encode(Uint8List pcmData, G711Type g711Type) { - List g711Data = []; - - for (int sample in pcmData) { - int sign = (sample < 0) ? 0x80 : 0; - int magnitude = (sample < 0) ? -sample : sample; - - int exponent = 7; - while (magnitude < (1 << exponent) && exponent > 0) { - exponent--; - } - - int mantissa = (magnitude >> (exponent - 4)) & 0x0F; - - if (g711Type == G711Type.uLaw) { - // μ-law encoding - int value = ~(sign | ((exponent << 4) & 0x70) | (mantissa >> 4)); - g711Data.add(value & 0xFF); - } else { - // A-law encoding - int value = sign | ((exponent << 4) & 0x70) | (mantissa >> 4); - g711Data.add(value & 0xFF); - } - } - - return Uint8List.fromList(g711Data); - } - - List pcm16ToG711u(List pcm16Data) { - List g711uData = []; - - for (int i = 0; i < pcm16Data.length; i += 2) { - int pcmSample = (pcm16Data[i + 1] << 8) | pcm16Data[i]; - int g711Sample = pcmToG711u(pcmSample); - - // 将 G.711 样本拆分成两个字节 - g711uData.add(g711Sample & 0xFF); - g711uData.add((g711Sample >> 8) & 0xFF); - } - - return g711uData; - } - - int pcmToG711u(int pcmSample) { - const int MULAW_BIAS = 0x84; - const int CLIP = 32635; - - // 剪裁 PCM 样本 - if (pcmSample > CLIP) { - pcmSample = CLIP; - } else if (pcmSample < -CLIP) { - pcmSample = -CLIP; - } - - // 增加偏置并取反 - pcmSample += MULAW_BIAS; - pcmSample = ~pcmSample & 0xFF; - - return pcmSample; - } -} diff --git a/star_lock/pubspec.yaml b/star_lock/pubspec.yaml index bde1c728..2d1ed9d1 100644 --- a/star_lock/pubspec.yaml +++ b/star_lock/pubspec.yaml @@ -125,7 +125,7 @@ dependencies: convert: ^3.1.1 just_audio: ^0.9.36 flutter_sound: ^9.2.13 - + flutter_ffmpeg: ^0.4.2 fast_gbk: ^1.0.0 dev_dependencies: