Recorder录音机应用bug修复与增加选择麦克风功能
社区录音机样例Recorder
修复一些bug以及增加选择麦克风功能,提供适用于API23的hap包,见文末
1、修复横屏状态下分屏布局问题
问题现象
录音结束后返回主页面,主页面和播放页面同时显示(一左一右),无法正常交互,必须重启应用才能恢复

问题原因
Index.ets 中的 onPortrait 方法监听屏幕方向变化,当检测到横屏时设置 this.isLand = true ,触发了系统的分屏布局模式。
修复方案
文件 : Index.ets
onPortrait = (mediaQueryResult: mediaQuery.MediaQueryResult) => {
// this.isLand = mediaQueryResult.matches;// 注释此行禁用横屏分屏
Logger.info(TAG, `onPortrait: isLand=${this.isLand}`);
}
2、修复路由栈增长导致多次返回问题
问题现象
播放录音页面点击左上角返回键返回到首页后,播放过几次就需要点击系统返回键几次才能退出到桌面。但在播放界面点击系统返回键返回到首页后,只需点击一次即可返回桌面。
问题原因
TitleWithBack.ets 中的返回按钮使用 router.replaceUrl({ url: 'pages/Index' }) ,每次都会在路由栈上添加一个新的 Index 页面,导致路由栈不断增长。
修复方案
文件 : TitleWithBack.ets
// 修改前
.onClick(() => {
router.replaceUrl({ url: 'pages/Index' });
})
// 修改后
.onClick(() => {
router.back();
})
3、添加麦克风选择功能
功能需求
在录音机应用中增加麦克风设备选择功能,支持切换内置麦克风、USB耳机麦等设备。
注:麦克风需要系统层支持才能识别;有些麦克风识别到了,采样率可能未适配也无法录音
实现方案
(1)在 RecordModel.ts 中添加麦克风管理方法
新增成员变量 :
private audioRoutingManager: audio.AudioRoutingManager | null = null;
private micDevices: audio.AudioDeviceDescriptors = [];
private selectedMicDevice: audio.AudioDeviceDescriptor | null = null;
private deviceChangeListener: ((deviceChanged: audio.DeviceChangeAction) => void) | null = null;
新增方法 :
|
方法名 |
功能说明 |
|
initAudioRoutingManager() |
初始化音频路由管理器 |
|
getAvailableMicDevices() |
获取可用麦克风设备列表 |
|
selectMicDevice(device) |
选择指定麦克风设备 |
|
getSelectedMicDevice() |
获取当前选中的麦克风设备 |
|
registerDeviceChangeListener(callback) |
注册设备变化监听器 |
|
unregisterDeviceChangeListener() |
注销设备变化监听器 |
核心代码 :
async initAudioRoutingManager() {
try {
const audioManager = audio.getAudioManager();
this.audioRoutingManager = audioManager.getRoutingManager();
Logger.info(TAG, 'init audio routing manager success');
} catch (error) {
Logger.error(TAG, `init audio routing manager failed: ${error}`);
}
}
async getAvailableMicDevices(): Promise<audio.AudioDeviceDescriptors> {
if (!this.audioRoutingManager) {
Logger.error(TAG, 'audio routing manager is not initialized');
return [];
}
try {
const devices = await this.audioRoutingManager.getDevices(audio.DeviceFlag.INPUT_DEVICES_FLAG);
this.micDevices = devices.filter((device: audio.AudioDeviceDescriptor) => {
return device.deviceType === audio.DeviceType.MIC ||
device.deviceType === audio.DeviceType.WIRED_HEADSET ||
device.deviceType === audio.DeviceType.BLUETOOTH_SCO ||
device.deviceType === audio.DeviceType.USB_HEADSET ||
device.deviceType === 31;
});
if (this.micDevices.length > 0) {
if (!this.selectedMicDevice || !this.micDevices.some((d: audio.AudioDeviceDescriptor) => d.id === this.selectedMicDevice!.id)) {
this.selectedMicDevice = this.micDevices[0];
try {
await this.audioRoutingManager.selectInputDevice([this.selectedMicDevice]);
Logger.info(TAG, `default select mic: ${this.getDeviceDisplayName(this.selectedMicDevice)}`);
} catch (error) {
Logger.error(TAG, `default select mic failed: ${error}`);
}
}
} else {
this.selectedMicDevice = null;
}
Logger.info(TAG, `available mic devices: ${this.micDevices.length}`);
return this.micDevices;
} catch (error) {
Logger.error(TAG, `get available mic devices failed: ${error}`);
return [];
}
}
async selectMicDevice(device: audio.AudioDeviceDescriptor): Promise<boolean> {
if (!this.audioRoutingManager) {
Logger.error(TAG, 'audio routing manager is not initialized');
return false;
}
try {
await this.audioRoutingManager.selectInputDevice([device]);
this.selectedMicDevice = device;
Logger.info(TAG, `select mic device success: ${this.getDeviceDisplayName(device)}`);
return true;
} catch (error) {
let err = error as BusinessError.BusinessError;
Logger.error(TAG, `select mic device failed: ${err.code} - ${err.message}`);
return false;
}
}
(2) 在 RecordPage.ets 中添加麦克风选择 UI
新增状态变量 :
@State micDevices: audio.AudioDeviceDescriptors = [];
@State selectedMicDevice: audio.AudioDeviceDescriptor | null = null;
页面生命周期处理 :
async aboutToAppear() {
await this.recordModel.initAudioRoutingManager();
await this.refreshMicDevices();
this.recordModel.registerDeviceChangeListener(() => {
this.refreshMicDevices();
});
}
async refreshMicDevices() {
this.micDevices = await this.recordModel.getAvailableMicDevices();
this.selectedMicDevice = this.recordModel.getSelectedMicDevice();
}
麦克风选择 UI :
Text('选择麦克风')
.fontColor(Color.Black)
.fontSize(22)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 16 })
Row({ space: 8 }) {
ForEach(this.micDevices, (device: audio.AudioDeviceDescriptor) => {
Button(this.recordModel.getDeviceDisplayName(device))
.layoutWeight(1)
.height(48)
.fontSize(16)
.backgroundColor(this.selectedMicDevice?.id === device.id ? '#007DFF' : '#E0E0E0')
.fontColor(this.selectedMicDevice?.id === device.id ? '#FFFFFF' : '#333333')
.borderRadius(8)
.onClick(() => this.selectMicDevice(device))
}, (device: audio.AudioDeviceDescriptor) => device.id.toString())
}
.width('100%')
if (this.micDevices.length === 0) {
Text('未检测到麦克风设备')
.fontColor(Color.Gray)
.fontSize(18)
.margin({ top: 16 })
}
修改文件清单
|
文件路径 |
修改内容 |
|
entry/src/main/ets/pages/Index.ets |
注释横屏分屏布局控制代码 |
|
entry/src/main/ets/common/TitleWithBack.ets |
返回按钮改用 router.back() |
|
entry/src/main/ets/pages/RecordPage.ets |
添加麦克风选择 UI 和返回键拦截 |
|
entry/src/main/ets/model/RecordModel.ts |
添加麦克风设备管理方法 |
hap文件下载地址:
Recorder6.1.hap · 阿伟/hap - 码云 - 开源中国
联系方式2968675576@qq.com
更多推荐



所有评论(0)