首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
HarmonyOS
发新帖
0
1
[原创]【FAQ】HarmonyOS SDK 闭源开放能力 — Audio Kit
发表于: 2026-1-22 10:01
8441
[原创]【FAQ】HarmonyOS SDK 闭源开放能力 — Audio Kit
HarmonyOS SDK
2026-1-22 10:01
8441
**1.问题描述:** 如何实现自定义音量调节? **解决方案:** 设置系统音量 应用无法直接调节系统音量,系统提供了ArkTS组件<a href="elink@ee8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1M7X3g2X3k6i4u0W2L8X3y4W2M7#2)9J5c8X3!0Z5L8%4y4Q4x3X3c8E0N6h3I4@1K9h3#2W2k6r3W2S2i4K6u0V1j5i4k6$3L8$3I4#2L8h3g2H3j5h3&6W2L8l9`.`.">AVVolumePanel音量面板</a>,应用可以创建该组件,让用户通过界面操作来调节音量。 设置应用音量 1. 管理应用音量的接口由AudioVolumeManager提供,在使用之前,需要使用getVolumeManager()获取AudioVolumeManager实例,示例代码如下: ```TS import { audio } from '@kit.AudioKit'; let audioManager = audio.getAudioManager(); let audioVolumeManager = audioManager.getVolumeManager(); ``` 2. 设置应用音量。 当<a href="elink@3aeK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1M7X3g2X3k6i4u0W2L8X3y4W2M7#2)9J5c8X3q4J5K9%4c8K6i4K6u0V1j5i4m8A6M7#2)9J5k6r3q4#2k6r3W2G2i4K6u0V1k6g2)9J5x3$3q4#2k6r3W2G2N6X3!0D9N6h3#2W2L8h3!0V1k6e0p5&6">音量模式</a>设置为APP_INDIVIDUAL时,可通过下面示例接口设置应用音量。 ```ts // 设置应用的音量(范围为0到100)。 audioVolumeManager.setAppVolumePercentage(20).then(() => { console.info(`set app volume success.`); }); ``` 设置音频流音量 在ArkTS API端和Native API端分别有对应的API用来设置音频流音量。 使用ArkTS API时,开发者可以使用AVPlayer或AudioRenderer的setVolume()方法。 - 使用<a href="elink@385K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1M7X3g2X3k6i4u0W2L8X3y4W2M7#2)9J5c8X3A6K6i4K6u0V1j5i4m8A6M7#2)9J5k6r3#2W2k6r3W2S2i4K6t1K6L8h3g2V1K9h3q4U0M7X3g2S2N6r3g2S2N6Y4m8D9j5i4W2W2M7U0V1`.">AVPlayer</a>设置音频流音量的示例代码如下: ```ts let volume = 1.0; // 指定的音量大小,取值范围为[0.00-1.00],1表示最大音量 avPlayer.setVolume(volume); ``` - 使用<a href="elink@fbfK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1M7X3g2X3k6i4u0W2L8X3y4W2M7#2)9J5c8X3A6K6i4K6u0V1j5i4m8A6M7#2)9J5k6r3q4#2k6r3W2G2i4K6t1K6j5i4g2V1K9h3!0U0M7X3g2S2N6r3g2S2N6h3c8A6L8%4u0W2L8X3c8W2M7X3g2J5z5l9`.`.">AudioRenderer</a>设置音频流音量的示例代码如下: ```ts import { BusinessError } from '@kit.BasicServicesKit'; audioRenderer.setVolume(0.5).then(() => { // 音量范围为[0.0-1.0] console.info('Invoke setVolume succeeded.'); }).catch((err: BusinessError) => { console.error(`Invoke setVolume failed, code is ${err.code}, message is ${err.message}`); }); ``` - 使用Native API时开发者可使用<a href="elink@59dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1M7X3g2X3k6i4u0W2L8X3y4W2M7#2)9J5c8X3y4S2M7r3W2Q4x3X3c8F1j5i4c8A6N6X3g2Q4x3X3c8S2N6h3c8A6L8%4u0W2L8X3c8W2M7X3g2J5i4K6u0V1K9q4)9J5x3$3!0Z5i4K6g2X3j5i4g2V1K9h3!0J5k6h3&6V1k6i4u0W2M7W2)9#2k6Y4y4W2N6s2k6G2L8s2g2E0k6b7`.`.">OH_AudioRenderer_SetVolume</a>接口设置当前音频流音量值,示例代码如下: ```C++ // 要设置的音量值,音量值的范围是[0.0, 1.0]。 float volume = 0.5f; // 设置当前音频流音量值。 OH_AudioStream_Result OH_AudioRenderer_SetVolume(audioRenderer, volume); ``` 请注意: - **setVolume接口**调整的是音频流本身的音量,不是系统音量,音量条本身不会发生变化,而且音频流本身的音量默认值是1,即以系统音量来播放,应用只可以在系统音量的基础上调到0~1倍,不会超过系统音量,也不会影响系统音量的值(即音量条)。 - 为确保用户能感知音量变化,应用后台不能调节音量,否则系统会做出对应的控制措施,因此音量面板设置volumeLevel初始值是不生效的,只有改变volumeLevel值触发音量面板,才会改变当前系统音量;并且音量面板调节具体音量由系统控制,当前播放什么音频就调节什么音量,没有播放时就会调节媒体音量。 **2.问题描述:** 如何实现支持滑动的视频音量调节功能? **解决方案:** <a href="elink@109K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1k6%4g2A6k6r3g2K6i4K6u0r3N6h3W2Q4x3X3c8B7M7#2)9J5k6r3y4G2L8i4m8G2L8X3g2F1N6s2y4Q4x3X3c8K6L8r3W2V1k6i4t1`.">Slider</a>组件结合音频流音量管理<a href="elink@340K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1M7X3g2X3k6i4u0W2L8X3y4W2M7#2)9J5c8X3A6K6i4K6u0V1j5i4m8A6M7#2)9J5k6r3#2W2k6r3W2S2i4K6t1K6L8h3g2V1K9h3q4U0M7X3g2S2N6r3g2S2N6Y4m8D9j5i4W2W2M7U0V1`.">AVPlayer</a>或<a href="elink@70bK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1M7X3g2X3k6i4u0W2L8X3y4W2M7#2)9J5c8X3A6K6i4K6u0V1j5i4m8A6M7#2)9J5k6r3q4#2k6r3W2G2i4K6t1K6j5i4g2V1K9h3!0U0M7X3g2S2N6r3g2S2N6h3c8A6L8%4u0W2L8X3c8W2M7X3g2J5z5l9`.`.">AudioRenderer</a>实现。Slider组件用于支持用户滑动获取音量值,将获取到的值通过setVolume接口传递给音频音量管理实现音量滑动控制调节。 **3.问题描述:** 集成腾讯云点播实现视频播放,自定义声音按钮实现音量滑动调节有什么比较好的策略? **解决方案:** 使用<a href="elink@863K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1k6%4g2A6k6r3g2K6i4K6u0r3N6h3W2Q4x3X3c8B7M7#2)9J5k6r3y4G2L8i4m8G2L8X3g2F1N6s2y4Q4x3X3c8K6L8r3W2V1k6i4t1`.">Slider</a>组件实现音量控制滑动条,结合腾讯云点播SDK的setAudioPlayoutVolume方法进行实现。实现时,建议默认音量100,即默认系统当前音量播放。 **4.问题描述:** 音乐播放器的音频输出如何增加PCM输出模式,支持数字耳放小尾巴usb独占? **解决方案:** 方案一:使用AudioRenderer直接播放PCM格式的音频数据。 AudioRenderer可以直接播放PCM数据,还可以通过数据预处理来实现更灵活的播放,关键代码如下: 1. 配置文件路径: ```TS let bufferSize: number = 0; let path = getContext().cacheDir; let filePath = path + '/StarWars10s-2C-48000-4SW.wav'; let file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_ONLY); ``` 2. 读取文件数据: ```TS try { fs.readSync(file.fd, buffer, options); bufferSize += buffer.byteLength; // 系统会判定buffer有效,正常播放。 return audio.AudioDataCallbackResult.VALID; } catch (error) { console.error('Error reading file:', error); // 系统会判定buffer无效,不播放。 return audio.AudioDataCallbackResult.INVALID; } ``` 3. 调用start()方法进行音频渲染 ```TS audioRenderer.start((err: BusinessError) => { if (err) { console.error(`Renderer start failed, code is ${err.code}, message is ${err.message}`); } else { console.info('Renderer start success.'); } }); ``` 具体开发步骤以及完整代码可以参考<a href="elink@780K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1k6%4g2A6k6r3g2K6i4K6u0r3N6i4y4A6L8X3N6Q4x3X3c8S2N6h3c8A6L8%4u0W2L8X3c8W2M7X3g2J5i4K6u0V1k6X3!0J5i4K6u0V1M7r3I4S2P5h3u0S2j5$3E0Q4x3U0y4Q4c8e0g2Q4b7V1y4Q4z5o6m8Q4c8e0g2Q4z5p5k6Q4z5e0q4Q4c8e0k6Q4b7f1c8Q4b7e0g2Q4c8e0W2Q4b7f1q4Q4b7e0c8Q4c8e0g2Q4z5p5k6Q4z5p5q4Q4c8e0k6Q4b7U0y4Q4b7e0S2Q4c8e0k6Q4z5o6c8Q4z5p5k6Q4c8e0c8Q4b7V1q4Q4z5p5u0Q4c8e0W2Q4b7e0q4Q4b7U0V1`.">AudioRenderer的开发步骤</a>。 方案二:对PCM数据进行音频转码后使用AVPlayer播放。 AVPlayer无法直接播放PCM格式的音频数据,需要将音频数据转码封装成AVPlayer支持的格式。PCM格式数据是裸流,播放占用内存大,使用AVPlayer播放封装后的音频数据会占用更小的内存。 这里以WAV格式为例,WAV格式是一种无损的格式,可以最好地保存音频质量,如果对音频大小或者格式有其他要求,可以参考<a href="elink@cb7K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1k6%4g2A6k6r3g2K6i4K6u0r3j5i4g2V1K9h3!0Q4x3X3c8W2L8X3y4G2k6r3W2F1k6H3`.`.">音频编码</a>和<a href="elink@35cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1k6%4g2A6k6r3g2K6i4K6u0r3j5i4g2V1K9h3!0Q4x3X3c8$3K9h3c8W2L8#2)9J5k6r3#2#2P5r3g2J5">媒体数据封装</a>进行其他的音频编码格式转化。 现在将PCM数据转码封装成完整的WAV文件再用AVPlayer播放,参考代码如下: 1. 定义PCM转WAV的方法,获取源文件路径和目标文件路径,分别写入WAV文件头和PCM数据,参考代码如下: ```TS public pcmToWav(src:string, dest:string){ const inFile: fs.File = fs.openSync(src, fs.OpenMode.READ_ONLY); const outFile: fs.File = fs.openSync(dest, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); let byteRate = 16 * sampleRate * channel / 8; const inFileStat = fs.statSync(inFile.fd) // 获取源文件信息,包括文件大小等 let audioDataSize = inFileStat.size; let totalDataLen = audioDataSize + 36; console.log('audioDataSize= ', audioDataSize) // 1.wav文件头编写 this.writeWavFileHeader(outFile, audioDataSize, totalDataLen, byteRate); // 2.写入pcm数据 this.writePcmData(inFile, outFile, audioDataSize) } ``` 2. 定义写入WAV头部信息的方法,创建一个大小为44字节的缓冲区,用于存储WAV文件的头部信息,再将其写入输出文件,参考代码如下: ```TS private writeString(dv:DataView, offset:number, str:string){ for (let i = 0; i < str.length; i++) { dv.setUint8(offset + i, str.charCodeAt(i)); } } // 定义写入WAV头文件信息的方法 private writeWavFileHeader(out:fs.File, audioDataSize:number, totalDataLen:number, byteRate:number){ const header = new ArrayBuffer(44); const dv = new DataView(header); const bitsPerSample = 16; // 当前位深是16 // 写入RIFF块 this.writeString(dv, 0, 'RIFF'); dv.setUint32(4, totalDataLen, true); this.writeString(dv, 8, 'WAVE'); // 写入fmt块 this.writeString(dv, 12, 'fmt '); dv.setUint32(16, 16, true); // fmt块大小 dv.setUint16(20, 1, true); // 格式类别(PCM) dv.setUint16(22, channel, true); // 通道数 dv.setUint32(24, sampleRate, true); // 采样率 dv.setUint32(28, byteRate, true); // 比特率 dv.setUint16(32, channel * bitsPerSample / 8, true); // 每个采样点的字节数 dv.setUint16(34, bitsPerSample, true); // 位深 // 写入data块 this.writeString(dv, 36, 'data'); dv.setUint32(40, audioDataSize, true); // 数据块大小 console.log('audioDataSize= ', audioDataSize) // 将头文件信息写入输出文件 fs.writeSync(out.fd, new Uint8Array(header).buffer, { length: 44 }) } ``` 3. 定义读取pcm数据的方法,将PCM数据从输入文件写入输出文件,使用fs.readSync读取输入文件的数据,并写入输出文件,直到读取完毕,参考代码如下: ```TS private writePcmData(inFile:fs.File, outFile:fs.File, audioDataSize:number){ // 写入PCM数据 let readSize = 0 let data = new ArrayBuffer(audioDataSize); let readOptions: ReadOptions = { offset: readSize, length: audioDataSize }; let readLen = fs.readSync(inFile.fd, data, readOptions); while (readLen > 0) { readSize += readLen; fs.writeSync(outFile.fd, data, { length: readLen }); readOptions.offset = readSize; readLen = fs.readSync(inFile.fd, data, readOptions); } fs.closeSync(inFile.fd) fs.closeSync(outFile.fd) } ``` 4. 完成转码后让AVPlayer使用fs文件系统打开沙箱地址获取媒体文件地址并通过dataSrc属性进行播放,AVPlayer的具体开发流程可以参考<a href="elink@505K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3K9r3q4J5L8h3!0F1P5h3!0K6i4K6u0V1k6%4g2A6k6r3g2K6i4K6u0r3N6i4y4A6L8X3N6Q4x3X3c8S2N6Y4m8D9j5i4W2W2M7W2)9J5k6r3k6G2M7W2)9J5k6s2m8D9j5i4W2T1j5h3y4C8i4K6t1K6i4@1f1#2i4@1q4q4i4K6S2o6i4@1f1$3i4K6V1#2i4@1t1@1i4@1f1%4i4@1p5@1i4@1u0m8i4@1f1@1i4@1u0q4i4K6S2n7">AVPlayer播放音频完整示例</a>。
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
收藏
・
0
点赞
・
1
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
AEVE
感谢你分享这么好的资源!
2026-1-22 10:16
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
1
)
mb_eekvgidg
雪 币:
249
活跃值:
(175)
能力值:
( LV2,RANK:10 )
在线值:
发帖
0
回帖
28
粉丝
0
关注
私信
mb_eekvgidg
2
楼
很有内涵,能联系我吗19153616868
2026-4-8 13:28
0
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
HarmonyOS SDK
258
发帖
190
回帖
0
RANK
关注
私信
他的文章
[原创]HarmonyOS智慧多窗,让应用在任意窗口都“恰到好处”
270
[原创]AI 赋能 Push Kit 场景化消息开发,高效完成鸿蒙应用推送能力接入
472
[原创]HarmonyOS Push Kit 自分类权益 Skill,助力提升权益申请通过率
521
[原创]基于增强QUIC协议优化弱网下的直播观看体验
697
[原创]焕新鸿蒙应用权限管理方案,应用授权体验再升级
609
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部