当前位置: 首页 > news >正文

赛事竞猜网站开发好的做网站公司

赛事竞猜网站开发,好的做网站公司,网站建设丷金手指专业十五,网站权限分配 数据库实现关键词#xff1a;audio、音频录制、音频播放、权限申请、文件管理 在app的开发过程中时常会遇见一些需要播放一段音频或进行语音录制的场景#xff0c;那么本期将介绍如何利用鸿蒙 audio 模块实现音频写入和播放的功能。本次依赖的是 ohos.multimedia.audio 音频管理模块audio、音频录制、音频播放、权限申请、文件管理 在app的开发过程中时常会遇见一些需要播放一段音频或进行语音录制的场景那么本期将介绍如何利用鸿蒙 audio 模块实现音频写入和播放的功能。本次依赖的是 ohos.multimedia.audio 音频管理模块核心逻辑为利用 AudioCapturer  创建音频采集器收集音频并写入文件至沙箱利用 AudioRenderer 播放沙箱中写入的音频文件确定目标那么开始。 本期文章的完整demo代码已经提交至Giteehttps://gitee.com/luvi/sound-recording 1. 添加权限 需要录音必不可少的是麦克风权限需要在 module.json5 中添加 ohos.permission.MICROPHONE 权限。 2. 引导用户授权 在第一步添加完麦克风权限后app开启后并不能直接使用该权限用户需要手动确认麦克风权限的开启在用户手动确认后麦克风权限则开始在当前app生效。 所以在代码中我们需要进行访问权限控制弹窗的拉起操作在这里使用 requestPermissionsFromUser 即可。需要注意的是若用户拒绝权限后下次需要引导用户前往设置页手动打开该权限此处就不做过多逻辑处理默认用户会同意该权限。 // 此处需要导入权限控制模块 import { abilityAccessCtrl, Permissions,PermissionRequestResult } from kit.AbilityKit;let permissionList: Permissions[] [ohos.permission.MICROPHONE] // 获取访问控制模块对象 let atManager: abilityAccessCtrl.AtManager abilityAccessCtrl.createAtManager(); let context: Context getContext(this) as common.UIAbilityContext; atManager.requestPermissionsFromUser(context, permissionList, (err: BusinessError, data: PermissionRequestResult) {if (err) {console.error(luvi requestPermissionsFromUser fail, err-${JSON.stringify(err)});} else {// 权限获取成功console.info(luvi data: JSON.stringify(data));} }); 3. 创建 AudioCapturer 音频采集器准备录音 在第2部授权操作完成后才可进行 AudioCapturer 音频采集器的创建不然没有权限是会报系统异常的错误。 // 此audioCapturer是写在struct中自行修改位置 audioCapturer: audio.AudioCapturer | null null...let audioCapturerOptions: audio.AudioCapturerOptions {// 音频流信息streamInfo: {samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100,channels: audio.AudioChannel.CHANNEL_2,sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW},// 采集器信息capturerInfo: {source: audio.SourceType.SOURCE_TYPE_MIC,capturerFlags: 0} }// 创建音频采集器 audio.createAudioCapturer(audioCapturerOptions, (err, data) {if (err) {console.error(luvi AudioCapturer Created : Error: ${err});} else {console.info(luvi AudioCapturer Created : Success.);// 音频采集器对象this.audioCapturer data;} });4. 开始录音 在第3步的操作后我们已经拿到了 audioCapturer 对象后续需要通过该对象进行音频录制与取消。 在录音过程中需要不断的写入声音数据到文件中所以我们需要订阅音频数据读入回调事件 后触发 start 操作开始录音在文件数据写入前需要增加 fs.OpenMode.READ_WRITE 权限。此处需要注意的是 MyVoice.wav 文件本身并不存在与沙箱文件中但是我们使用文件管理的 open 方法配置 fs.OpenMode.CREATE 权限则会自动创建出该文件。 // 导入文件管理模块 import { fileIo as fs, ReadOptions } from kit.CoreFileKit;...// struct中 destFile: fs.File | null null...Button(开始采集语音).onClick(() {let path getContext().getApplicationContext().filesDir;let bufferSize: number 0;let filePath path /MyVoice.wav;this.destFile fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.READ_ONLY | fs.OpenMode.CREATE | fs.OpenMode.TRUNC);let readDataCallback (buffer: ArrayBuffer) {let options: ReadOptions {offset: bufferSize,length: buffer.byteLength}fs.writeSync(this.destFile?.fd, buffer, options);bufferSize buffer.byteLength;}this.audioCapturer?.on(readData, readDataCallback);this.audioCapturer?.start((err: BusinessError) {if (err) {console.error(luvi Capturer start failed.);} else {console.info(luvi Capturer start success.);}}); }) 5. 结束录音 录音结束后关闭文件操作避免资源占用。 Button(结束采集音频).onClick(() {this.audioCapturer?.stop((err: BusinessError) {if (err) {console.error(luvi Capturer stop failed);} else {console.info(luvi Capturer stopped.);}});fs.close(this.destFile) }) 此时录制的音频已经保存至了沙箱中。 6. 创建音频渲染器 audioRenderer 是写在 struct 中需要保存音频渲染器对象供后续使用。 // 此audioRenderer是写在struct中自行修改位置 audioRenderer: audio.AudioRenderer| null null... let audioRendererOptions: audio.AudioRendererOptions {streamInfo: {samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_48000, // 采样率channels: audio.AudioChannel.CHANNEL_2, // 通道sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, // 采样格式encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW // 编码格式},rendererInfo: {content: audio.ContentType.CONTENT_TYPE_MUSIC, // 媒体类型usage: audio.StreamUsage.STREAM_USAGE_MEDIA, // 音频流使用类型rendererFlags: 0 // 音频渲染器标志} }audio.createAudioRenderer(audioRendererOptions, (err, renderer) { // 创建AudioRenderer实例if (!err) {console.info(luvi creating AudioRenderer success);// 音频渲染器对象this.audioRenderer renderer;} else {console.info(luvi creating AudioRenderer failed, error: ${err.message});} }); 7.播放音频 播放第5步保存的音频文件需要使用音频渲染器对象创建的渲染器本身无音频对象所以需要在启动音频渲染器后不断地在音频渲染器中写入音频文件的缓冲数据从而达到播放效果当播放完毕后关闭文件和渲染器。 Button(播放音频采集结果).onClick(async () {if (!this.audioRenderer){return}let stateGroup [audio.AudioState.STATE_PREPARED, audio.AudioState.STATE_PAUSED, audio.AudioState.STATE_STOPPED];if (stateGroup.indexOf(this.audioRenderer.state) -1) { // 当且仅当状态为prepared、paused和stopped之一时才能启动渲染console.error(luvi start failed);return;}await this.audioRenderer.start(); // 启动渲染const bufferSize await this.audioRenderer.getBufferSize();let context getContext(this).getApplicationContext();let path context.filesDir;const filePath path /MyVoice.wav; // 使用沙箱路径获取文件实际路径为/data/storage/el2/base/haps/entry/files/test.wavlet file fs.openSync(filePath, fs.OpenMode.READ_ONLY);let stat await fs.stat(filePath);let buf new ArrayBuffer(bufferSize);let len stat.size % bufferSize 0 ? Math.floor(stat.size / bufferSize) : Math.floor(stat.size / bufferSize 1);for (let i 0; i len; i) {let options: ReadOptions {offset: i * bufferSize,length: bufferSize};let readsize await fs.read(file.fd, buf, options);// buf是要写入缓冲区的音频数据在调用AudioRenderer.write()方法前可以进行音频数据的预处理实现个性化的音频播放功能AudioRenderer会读出写入缓冲区的音频数据进行渲染let writeSize: number await new Promise((resolve, reject) {this.audioRenderer?.write(buf, (err, writeSize) {if (err) {reject(err);} else {resolve(writeSize);}});});if (this.audioRenderer.state audio.AudioState.STATE_RELEASED) { // 如果渲染器状态为released停止渲染fs.close(file);await this.audioRenderer.stop();}if (this.audioRenderer.state audio.AudioState.STATE_RUNNING) {if (i len - 1) { // 如果音频文件已经被读取完停止渲染fs.close(file);await this.audioRenderer.stop();}}} }) 此时我们就已经完成了音频录制与播放的一整套功能若在开发中遇到问题可连接设备点击 IDE 右下角的 Device File Browser 文件浏览器查看音频文件写入是否正确还有最重要的就算别忘记添加权限。 完整代码已经提交至了Gitee中可回顶部查看。
http://www.yingshimen.cn/news/41373/

相关文章:

  • 网站域名查询ip地址网店培训班
  • 宁夏网站建设哪个好保定网站建设公司排名
  • wordpress数据库下载备份站长工具seo综合查询方法
  • dw个人网站制作火币网站怎么做空
  • 新网网站制作企业做年度公示在哪个网站
  • 地方门户网站如何宣传网站提交网址
  • 做链接哪个网站好在互联网上如何赚钱
  • 做电脑系统哪个网站wordpress wp_register
  • 网站建设步骤的论文怎么做起泡胶
  • 成都访问公司网站查看注册过的网站
  • 网站优化 无需定金河北网站排名
  • 可以放友情链接的网站网站建设的主要情况说明
  • 公司做网站是com好还是cn好专业的团队网站建设
  • 重庆市建设领域农民工工资专户网站广东专业做网站排名公司哪家好
  • 优化设计官方网站吴江城乡住房和城乡建设局网站
  • c 2015 做网站建立自己的网站用花钱吗
  • 做免费的视频网站可以赚钱吗flash网站源文件下载
  • 网络推广和网站推广平台学习电子商务网站建设与管理
  • 织梦网站上传步骤奢侈品商城网站建设方案
  • 做爰网站视屏凡科网小程序
  • 网站添加百度搜索网页搜索框设计
  • 网站制作价格 上海网站说明怎么写
  • 使用循环视频做背景的网站临河网站建设
  • 南昌旅游网站建设方案做网站建设怎么赚钱
  • 营销型网站的公司都什么企业需要网站吗
  • 新手学做网站 视频百度网盘电工学高等教育出版社久久建筑网
  • 盛锡福网站wordpress口语主题
  • 青岛网站排名哪家公司好基础建站如何提升和优化
  • 在互联网上建设网站可选择的方案有织梦网站栏目增加
  • 公司做网站怎么赚钱西安app定制开发公司