前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HarmonyOS NEXT 语音录制和声音动效实现

HarmonyOS NEXT 语音录制和声音动效实现

原创
作者头像
小帅聊鸿蒙
发布2024-08-16 20:59:05
1210
发布2024-08-16 20:59:05
举报
文章被收录于专栏:鸿蒙开发笔记

介绍

本示例使用AVrecord录制音频和AVrecord的getAudioCapturerMaxAmplitude接口获取振幅实现UI动效;使用AVplayer播放音频

效果图预览

使用说明

  1. 按住按钮开始录音。
  2. 上划取消录制。
  3. 录制完成后点击消息框可播放录音。

实现思路

  1. 利用组合手势来实现音频录制与取消录制。build() { Column() { Button($r('app.string.button')) .gesture( GestureGroup(GestureMode.Sequence, LongPressGesture() .onAction( () => { this.AVrecord.startRecordingProcess(); }) .onActionEnd( () => { this.AVrecord.stopRecordingProcess(); }), PanGesture() .onActionStart( () => { clearInterval(this.count); }) .onActionEnd( () => { this.AVrecord.stopRecordingProcess(); }) ) .onCancel( () => { this.AVrecord.startRecordingProcess(); }) ) } }async startRecordingProcess() { if (this.avRecorder !== undefined) { await this.avRecorder.release(); this.avRecorder = undefined; } // 1.创建录制实例 this.avRecorder = await media.createAVRecorder(); this.setAudioRecorderCallback(); // 2.获取录制文件fd赋予avConfig里的url;参考FilePicker文档 const context = getContext(this); const path = context.filesDir; const filepath = path + '01.mp3'; const file = fs.openSync(filepath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); const fdNumber = file.fd; this.avConfig.url = 'fd://' + fdNumber; // 3.配置录制参数完成准备工作 await this.avRecorder.prepare(this.avConfig); // 4.开始录制 await this.avRecorder.start(); // 获取最大振幅 this.time = setInterval(() => { this.avRecorder!.getAudioCapturerMaxAmplitude((_: BusinessError, amplitude: number) => { this.maxAmplitude = amplitude; }); }, Const.COLUMN_HEIGHT); } Button($r('app.string.button')) .gesture( GestureGroup(GestureMode.Sequence, LongPressGesture() .onAction(() => { // 获取时间戳 this.timeStart = Math.floor(new Date().getTime() / Const.ANIMATION_DURATION); this.flag2 = Const.OPACITY_FALSE; this.isListening = !this.isListening; this.flag = Const.OPACITY_TRUE; this.AVrecord.startRecordingProcess(); // 每隔100ms获取一次振幅 this.count = setInterval(() => { if (this.AVrecord.maxAmplitude > Const.MIN_AMPLITUDE) { this.maxNumber = (this.AVrecord.maxAmplitude) / Const.MAX_AMPLITUDE * Const.COLUMN_HEIGHT; this.minNumber = (this.AVrecord.maxAmplitude) / Const.MAX_AMPLITUDE * Const.COLUMN_HEIGHT - Const.HEIGHT_MIN; } else { this.maxNumber = Const.OPACITY_FALSE; this.minNumber = Const.OPACITY_FALSE; } if (this.isListening) { animateTo({ duration: Const.ANIMATION_DURATION, curve: Curve.EaseInOut }, () => { this.yMax = this.maxNumber; this.yMin = this.minNumber; }) } }, Const.SET_INTERVAL_TIME); }) .onActionEnd(() => { clearInterval(this.count); this.flag2 = Const.OPACITY_TRUE; this.yMax = Const.OPACITY_FALSE; this.yMin = Const.OPACITY_FALSE; this.AVrecord.stopRecordingProcess(); }), // 上划取消 PanGesture() .onActionStart(() => { clearInterval(this.count); }) .onActionEnd(() => { this.isListening = false; animateTo({ duration: Const.OPACITY_FALSE }, () => { this.yMax = Const.OPACITY_FALSE; this.yMin = Const.OPACITY_FALSE; }) this.flag = Const.OPACITY_FALSE; this.flag2 = Const.OPACITY_FALSE; this.AVrecord.stopRecordingProcess(); }) ) .onCancel(() => { // 获取结束时间戳并计算出手势持续时间 this.timeEnd = Math.floor(new Date().getTime() / Const.ANIMATION_DURATION); this.timeAv = this.timeEnd - this.timeStart; clearInterval(this.count); this.isListening = false; animateTo({ duration: Const.OPACITY_FALSE }, () => { this.yMax = Const.OPACITY_FALSE; this.yMin = Const.OPACITY_FALSE; }); this.flag = Const.OPACITY_FALSE; this.flag2 = Const.OPACITY_TRUE; this.AVrecord.startRecordingProcess(); }) ) build() { Row ({ space: 5 }) { ForEach(this.arr, (_:number) => { Column() .width(this.x) .height(Math.floor(Math.random() * (this.yMin - this.yMax + Const.ONE) + this.yMax)) }, (index: number) => index.toString()) } ... }Image($r('app.media.icon')) .width($r('app.integer.width_image')) .height($r('app.integer.height_image')) .onClick( () => { this.AVplaer.avPlayerUrlDemo(); } )工程结构&模块类型
  2. 在音频录制的时候通过getAudioCapturerMaxAmplitude获取声音振幅使UI变化。
  3. 使用AVplayer播放已录制的音频。
代码语言:shell
复制
normalcaptu                                      // har类型
|---src
|   |---main
|   |     |---ets
|   |     |  |---common                        
|   |        |    |---CommonConstants.ets       // 常量定义 
|   |     |  |---pages                          
|   |        |    |---Index.ets                 // 主页面

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力;
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识;
  • 想要获取更多完整鸿蒙最新学习知识点,可关注B站:码牛课堂;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 效果图预览
  • 实现思路
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档