完善对讲语音发送功能
This commit is contained in:
parent
5a5f8ea42f
commit
535d274c6e
@ -39,6 +39,10 @@
|
|||||||
|
|
||||||
<!--允许读设备等信息,用于问题排查-->
|
<!--允许读设备等信息,用于问题排查-->
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
|
<!--允许麦克风权限,用于录音发送-->
|
||||||
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<application
|
<application
|
||||||
android:label="星锁"
|
android:label="星锁"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
import '../../../../tools/baseGetXController.dart';
|
import '../../../../tools/baseGetXController.dart';
|
||||||
import '../../../../tools/eventBusEventManage.dart';
|
import '../../../../tools/eventBusEventManage.dart';
|
||||||
@ -33,6 +34,30 @@ class LockMonitoringLogic extends BaseGetXController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> getPermissionStatus() async {
|
||||||
|
Permission permission = Permission.microphone;
|
||||||
|
//granted 通过,denied 被拒绝,permanentlyDenied 拒绝且不在提示
|
||||||
|
PermissionStatus status = await permission.status;
|
||||||
|
if (status.isGranted) {
|
||||||
|
return true;
|
||||||
|
} else if (status.isDenied) {
|
||||||
|
requestPermission(permission);
|
||||||
|
} else if (status.isPermanentlyDenied) {
|
||||||
|
openAppSettings();
|
||||||
|
} else if (status.isRestricted) {
|
||||||
|
requestPermission(permission);
|
||||||
|
} else {}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
///申请权限
|
||||||
|
void requestPermission(Permission permission) async {
|
||||||
|
PermissionStatus status = await permission.request();
|
||||||
|
if (status.isPermanentlyDenied) {
|
||||||
|
openAppSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onReady() {
|
void onReady() {
|
||||||
// TODO: implement onReady
|
// TODO: implement onReady
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:flutter_sound/flutter_sound.dart';
|
import 'package:flutter_sound/flutter_sound.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:network_info_plus/network_info_plus.dart';
|
import 'package:network_info_plus/network_info_plus.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
import '../../../../app_settings/app_colors.dart';
|
import '../../../../app_settings/app_colors.dart';
|
||||||
import '../../../../talk/udp/udp_manage.dart';
|
import '../../../../talk/udp/udp_manage.dart';
|
||||||
@ -160,22 +163,48 @@ class _LockMonitoringPageState extends State<LockMonitoringPage> {
|
|||||||
Widget bottomBottomBtnWidget() {
|
Widget bottomBottomBtnWidget() {
|
||||||
return Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
|
return Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
|
||||||
// 接听
|
// 接听
|
||||||
Obx(() => bottomBtnItemWidget(
|
Obx(() => bottomBtnItemWidget(getAnswerBtnImg(), getAnswerBtnName(), Colors.white, () async {
|
||||||
getAnswerBtnImg(), getAnswerBtnName(), Colors.white, () async {
|
//获取麦克风权限
|
||||||
var userMobileIP = await NetworkInfo().getWifiIP();
|
await logic.getPermissionStatus().then((value) async {
|
||||||
var userMobile = await Storage.getMobile();
|
if (!value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var userMobileIP = await NetworkInfo().getWifiIP();
|
||||||
|
var userMobile = await Storage.getMobile();
|
||||||
|
|
||||||
// 刚进来是接听状态,然后改为长按对讲
|
// 刚进来是接听状态,然后改为长按对讲
|
||||||
UDPSenderManage.sendMainProtocol(
|
UDPSenderManage.sendMainProtocol(
|
||||||
command: 150,
|
command: 150,
|
||||||
commandTypeIsCalling: 1,
|
commandTypeIsCalling: 1,
|
||||||
subCommand: 6,
|
subCommand: 6,
|
||||||
lockID: UDPManage().lockId,
|
lockID: UDPManage().lockId,
|
||||||
lockIP: UDPManage().host,
|
lockIP: UDPManage().host,
|
||||||
userMobile: userMobile,
|
userMobile: userMobile,
|
||||||
userMobileIP: userMobileIP,
|
userMobileIP: userMobileIP,
|
||||||
endData: []);
|
endData: []
|
||||||
})),
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
longPress: (){
|
||||||
|
// 开始长按
|
||||||
|
print("onLongPress");
|
||||||
|
if (state.udpStatus.value == 8) {
|
||||||
|
state.udpStatus.value = 9;
|
||||||
|
}
|
||||||
|
_startRecording();
|
||||||
|
},
|
||||||
|
longPressUp: () async {
|
||||||
|
// 长按结束
|
||||||
|
print("onLongPressUp");
|
||||||
|
if (state.udpStatus.value == 9) {
|
||||||
|
state.udpStatus.value = 8;
|
||||||
|
}
|
||||||
|
_stopRecording();
|
||||||
|
|
||||||
|
_playRecording();
|
||||||
|
}
|
||||||
|
)
|
||||||
|
),
|
||||||
bottomBtnItemWidget(
|
bottomBtnItemWidget(
|
||||||
"images/main/icon_lockDetail_hangUp.png", "挂断", Colors.red, () async {
|
"images/main/icon_lockDetail_hangUp.png", "挂断", Colors.red, () async {
|
||||||
var userMobileIP = await NetworkInfo().getWifiIP();
|
var userMobileIP = await NetworkInfo().getWifiIP();
|
||||||
@ -234,22 +263,12 @@ class _LockMonitoringPageState extends State<LockMonitoringPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget bottomBtnItemWidget(
|
Widget bottomBtnItemWidget(
|
||||||
String iconUrl, String name, Color backgroundColor, Function() onClick) {
|
String iconUrl, String name, Color backgroundColor, Function() onClick, {Function()? longPress, Function()? longPressUp}) {
|
||||||
var wh = 80.w;
|
var wh = 80.w;
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: onClick,
|
onTap: onClick,
|
||||||
onLongPress: () {
|
onLongPress: longPress,
|
||||||
print("onLongPress");
|
onLongPressUp: longPressUp,
|
||||||
if (state.udpStatus.value == 8) {
|
|
||||||
state.udpStatus.value = 9;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLongPressUp: () {
|
|
||||||
print("onLongPressUp");
|
|
||||||
if (state.udpStatus.value == 9) {
|
|
||||||
state.udpStatus.value = 8;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 140.h,
|
height: 140.h,
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -331,29 +350,77 @@ class _LockMonitoringPageState extends State<LockMonitoringPage> {
|
|||||||
|
|
||||||
//开始录音
|
//开始录音
|
||||||
_startRecording() async {
|
_startRecording() async {
|
||||||
filePath = 'your_output_file.wav';
|
getFilePath().then((value) {
|
||||||
|
filePath = value;
|
||||||
|
});
|
||||||
await recorder.startRecorder(
|
await recorder.startRecorder(
|
||||||
toFile: filePath,
|
toFile: filePath,
|
||||||
codec: Codec.pcm16WAV,
|
codec: Codec.pcm16WAV,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//停止录音
|
//停止录音
|
||||||
_stopRecording() async {
|
_stopRecording() async {
|
||||||
await recorder.stopRecorder();
|
await recorder.stopRecorder();
|
||||||
|
|
||||||
|
var userMobileIP = await NetworkInfo().getWifiIP();
|
||||||
|
var userMobile = await Storage.getMobile();
|
||||||
|
|
||||||
|
// final file = File(filePath);
|
||||||
|
File file = File(filePath); // 使用 create 方法创建文件
|
||||||
|
|
||||||
|
print('filePathfilePath:$filePath file:$file await file.exists():${await file.exists()}');
|
||||||
|
if (await file.exists()) {
|
||||||
|
final List<int> bytes = await file.readAsBytes();
|
||||||
|
print('Recorded audio bytes.length:${bytes.length} bytes: $bytes');
|
||||||
|
|
||||||
|
// 刚进来是接听状态,然后改为长按对讲
|
||||||
|
UDPSenderManage.sendMainProtocol(
|
||||||
|
command: 150,
|
||||||
|
commandTypeIsCalling: 1,
|
||||||
|
subCommand: 8,
|
||||||
|
lockID: UDPManage().lockId,
|
||||||
|
lockIP: UDPManage().host,
|
||||||
|
userMobile: userMobile,
|
||||||
|
userMobileIP: userMobileIP,
|
||||||
|
endData: bytes
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//播放录音
|
Future<String> getFilePath() async {
|
||||||
|
final directory = await getApplicationDocumentsDirectory();
|
||||||
|
final filePath = '${directory.path}/recording.wav';
|
||||||
|
|
||||||
|
// 创建文件
|
||||||
|
File file = File(filePath);
|
||||||
|
await file.create(); // 使用 create 方法创建文件
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> _getRecordedAudioBytes() async {
|
||||||
|
final file = File(filePath);
|
||||||
|
if (await file.exists()) {
|
||||||
|
final List<int> bytes = await file.readAsBytes();
|
||||||
|
print('Recorded audio bytes: $bytes');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//播放录音
|
||||||
_playRecording() async {
|
_playRecording() async {
|
||||||
player = FlutterSoundPlayer();
|
player = FlutterSoundPlayer();
|
||||||
await player.startPlayer(
|
await player.startPlayer(
|
||||||
fromURI: filePath,
|
fromURI: filePath,
|
||||||
codec: Codec.pcm16WAV,
|
codec: Codec.pcm16WAV,
|
||||||
);
|
);
|
||||||
|
Toast.show(msg: "储存录音播放了");
|
||||||
|
print('_playRecording() 储存录音播放了');
|
||||||
}
|
}
|
||||||
|
|
||||||
//停止播放
|
//停止播放
|
||||||
_stopPlaying() async {
|
// _stopPlaying() async {
|
||||||
await player.stopPlayer();
|
// await player.stopPlayer();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,11 +43,12 @@ class CallTalk {
|
|||||||
Future<void> getAVData(Uint8List bb, int len) async {
|
Future<void> getAVData(Uint8List bb, int len) async {
|
||||||
// 音频数据
|
// 音频数据
|
||||||
if (bb[61] == 1) {
|
if (bb[61] == 1) {
|
||||||
print('dinglingling音频数据来啦啦啦啦啦啦啦啦啦$bb');
|
print('dinglingling bb.length:${bb.length} 音频数据来:$bb ');
|
||||||
// 用你的711音频数据替换这里的Uint8List
|
// 用你的711音频数据替换这里的Uint8List
|
||||||
// Uint8List rawData = G711Decoder().decodeG711uLaw(bb);
|
// Uint8List rawData = G711Decoder().decodeG711uLaw(bb);
|
||||||
// 示例 G711 数据(u-law 或 a-law)
|
// 示例 G711 数据(u-law 或 a-law)
|
||||||
Uint8List g711Data = bb;
|
|
||||||
|
Uint8List g711Data = bb.sublist(77, bb.length);
|
||||||
// 解码为 PCM 数据
|
// 解码为 PCM 数据
|
||||||
Uint8List pcmData = G711Decoder().g711Decode(g711Data, G711Type.uLaw);
|
Uint8List pcmData = G711Decoder().g711Decode(g711Data, G711Type.uLaw);
|
||||||
// 现在你可以使用 pcmData 进行播放或其他处理
|
// 现在你可以使用 pcmData 进行播放或其他处理
|
||||||
|
|||||||
@ -19,7 +19,7 @@ class CommandUDPReciverManager {
|
|||||||
if (dataSize < 4) {
|
if (dataSize < 4) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
print("appReceiveUDPData:$data");
|
// print("appReceiveUDPData:$data");
|
||||||
|
|
||||||
Uint8List data1 = Uint8List.fromList(data);
|
Uint8List data1 = Uint8List.fromList(data);
|
||||||
if (data1.length == 1) {
|
if (data1.length == 1) {
|
||||||
@ -43,7 +43,7 @@ class CommandUDPReciverManager {
|
|||||||
|
|
||||||
// 对讲命令
|
// 对讲命令
|
||||||
var beiCallType = data[8] & 0xff;
|
var beiCallType = data[8] & 0xff;
|
||||||
print("被呼叫类型$beiCallType");
|
// print("被呼叫类型$beiCallType");
|
||||||
switch (beiCallType) {
|
switch (beiCallType) {
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user