鸿蒙(API 12 Beta2版)媒体开发【使用OHAudio开发音频播放功能(C/C++)】

news2024/9/29 3:33:03

OHAudio是系统在API version 10中引入的一套C API,此API在设计上实现归一,同时支持普通音频通路和低时延通路。仅支持PCM格式,适用于依赖Native层实现音频输出功能的场景。

使用入门

开发者要使用OHAudio提供的播放或者录制能力,需要添加对应的头文件。

在 CMake 脚本中链接动态库

target_link_libraries(sample PUBLIC libohaudio.so)

添加头文件

开发者通过引入<[native_audiostreambuilder.h]>和<[native_audiorenderer.h]>头文件,使用音频播放相关API。

#include <ohaudio/native_audiorenderer.h>
#include <ohaudio/native_audiostreambuilder.h>

音频流构造器

OHAudio提供OH_AudioStreamBuilder接口,遵循构造器设计模式,用于构建音频流。开发者需要根据业务场景,指定对应的[OH_AudioStream_Type] 。

OH_AudioStream_Type包含两种类型:

  • AUDIOSTREAM_TYPE_RENDERER
  • AUDIOSTREAM_TYPE_CAPTURER

使用[OH_AudioStreamBuilder_Create]创建构造器示例:

OH_AudioStreamBuilder* builder;
OH_AudioStreamBuilder_Create(&builder, streamType);

在音频业务结束之后,开发者应该执行[OH_AudioStreamBuilder_Destroy]接口来销毁构造器。

OH_AudioStreamBuilder_Destroy(builder);

开发步骤及注意事项

详细的API说明请参考[OHAudio API参考]

开发者可以通过以下几个步骤来实现一个简单的播放功能。

  1. 创建构造器
OH_AudioStreamBuilder* builder;
OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_RENDERER);
  1. 配置音频流参数

    创建音频播放构造器后,可以设置音频流所需要的参数,可以参考下面的案例。

// 设置音频采样率
OH_AudioStreamBuilder_SetSamplingRate(builder, 48000);
// 设置音频声道
OH_AudioStreamBuilder_SetChannelCount(builder, 2);
// 设置音频采样格式
OH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE);
// 设置音频流的编码类型
OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW);
// 设置输出音频流的工作场景
OH_AudioStreamBuilder_SetRendererInfo(builder, AUDIOSTREAM_USAGE_MUSIC);

注意,播放的音频数据要通过回调接口写入,开发者要实现回调接口,使用OH_AudioStreamBuilder_SetRendererCallback设置回调函数。回调函数的声明请查看[OH_AudioRenderer_Callbacks]) 。

  1. 设置音频回调函数

    多音频并发处理可参考[多音频播放的并发策略],仅接口语言差异。

// 自定义写入数据函数
int32_t MyOnWriteData(
    OH_AudioRenderer* renderer,
    void* userData,
    void* buffer,
    int32_t length)
{
    // 将待播放的数据,按length长度写入buffer
    return 0;
}
// 自定义音频流事件函数
int32_t MyOnStreamEvent(
    OH_AudioRenderer* renderer,
    void* userData,
    OH_AudioStream_Event event)
{
    // 根据event表示的音频流事件信息,更新播放器状态和界面
    return 0;
}
// 自定义音频中断事件函数
int32_t MyOnInterruptEvent(
    OH_AudioRenderer* renderer,
    void* userData,
    OH_AudioInterrupt_ForceType type,
    OH_AudioInterrupt_Hint hint)
{
    // 根据type和hint表示的音频中断信息,更新播放器状态和界面
    return 0;
}
// 自定义异常回调函数
int32_t MyOnError(
    OH_AudioRenderer* renderer,
    void* userData,
    OH_AudioStream_Result error)
{
    // 根据error表示的音频异常信息,做出相应的处理
    return 0;
}

OH_AudioRenderer_Callbacks callbacks;
// 配置回调函数
callbacks.OH_AudioRenderer_OnWriteData = MyOnWriteData;
callbacks.OH_AudioRenderer_OnStreamEvent = MyOnStreamEvent;
callbacks.OH_AudioRenderer_OnInterruptEvent = MyOnInterruptEvent;
callbacks.OH_AudioRenderer_OnError = MyOnError;

//设置输出音频流的回调
OH_AudioStreamBuilder_SetRendererCallback(builder, callbacks, nullptr);

为了避免不可预期的行为,在设置音频回调函数时,请确保[OH_AudioRenderer_Callbacks]的每一个回调都被自定义的回调方法空指针初始化。

// 自定义写入数据函数
int32_t MyOnWriteData(
    OH_AudioRenderer* renderer,
    void* userData,
    void* buffer,
    int32_t length)
{
    // 将待播放的数据,按length长度写入buffer
    return 0;
}
// 自定义音频中断事件函数
int32_t MyOnInterruptEvent(
    OH_AudioRenderer* renderer,
    void* userData,
    OH_AudioInterrupt_ForceType type,
    OH_AudioInterrupt_Hint hint)
{
    // 根据type和hint表示的音频中断信息,更新播放器状态和界面
    return 0;
}
OH_AudioRenderer_Callbacks callbacks;

// 配置回调函数,如果需要监听,则赋值
callbacks.OH_AudioRenderer_OnWriteData = MyOnWriteData;
callbacks.OH_AudioRenderer_OnInterruptEvent = MyOnInterruptEvent;

// (必选)如果不需要监听,使用空指针初始化
callbacks.OH_AudioRenderer_OnStreamEvent = nullptr;
callbacks.OH_AudioRenderer_OnError = nullptr;
  1. 构造播放音频流
OH_AudioRenderer* audioRenderer;
OH_AudioStreamBuilder_GenerateRenderer(builder, &audioRenderer);
  1. 使用音频流

    音频流包含下面接口,用来实现对音频流的控制。

    接口说明
    OH_AudioStream_Result OH_AudioRenderer_Start(OH_AudioRenderer* renderer)开始播放
    OH_AudioStream_Result OH_AudioRenderer_Pause(OH_AudioRenderer* renderer)暂停播放
    OH_AudioStream_Result OH_AudioRenderer_Stop(OH_AudioRenderer* renderer)停止播放
    OH_AudioStream_Result OH_AudioRenderer_Flush(OH_AudioRenderer* renderer)释放缓存数据
    OH_AudioStream_Result OH_AudioRenderer_Release(OH_AudioRenderer* renderer)释放播放实例
  2. 释放构造器

    构造器不再使用时,需要释放相关资源。

    OH_AudioStreamBuilder_Destroy(builder);
    

设置低时延模式

当设备支持低时延通路时,开发者可以使用低时延模式创建播放器,获得更高质量的音频体验。

开发流程与普通播放场景一致,仅需要在创建音频流构造器时,调用[OH_AudioStreamBuilder_SetLatencyMode()]设置低时延模式。

开发示例

OH_AudioStreamBuilder_SetLatencyMode(builder, AUDIOSTREAM_LATENCY_MODE_FAST);

设置音频声道布局

播放音频文件时,可以通过设置音频的声道布局信息,指定渲染或播放时的扬声器摆位,使得渲染和播放效果更佳,获得更高质量的音频体验。

开发流程与普通播放场景一致,仅需要在创建音频流构造器时,调用[OH_AudioStreamBuilder_SetChannelLayout()]设置声道布局信息。

当声道布局与声道数不匹配时,创建音频流会失败。建议在设置声道布局时,确认下发的声道布局信息是正确的。

如果不知道准确的声道布局信息,或者开发者需要使用默认声道布局,可以不调用设置声道布局接口,或者下发CH_LAYOUT_UNKNOWN,以使用基于声道数的默认声道布局。

对于HOA格式的音频,想要获得正确的渲染和播放效果,必须指定声道布局信息。

开发示例

OH_AudioStreamBuilder_SetChannelLayout(builder, CH_LAYOUT_STEREO);

播放AudioVivid格式音源

播放AudioVivid格式音频文件时,需要使用与普通播放不同的数据写入回调函数,该回调可以同时写入PCM数据与元数据。

开发流程与普通播放场景一致,仅需要在创建音频流构造器时,调用[OH_AudioStreamBuilder_SetWriteDataWithMetadataCallback()]设置PCM数据与元数据同时写入的回调函数,同时调用[OH_AudioStreamBuilder_SetEncodingType()]设置编码类型为AUDIOSTREAM_ENCODING_TYPE_AUDIOVIVID。

在播放AudioVivid时,帧长是固定的,不可通过[OH_AudioStreamBuilder_SetFrameSizeInCallback()]设置回调帧长。同时,在设置播放声道数和声道布局时,需要将写入音源的声床数和对象数相加后进行设置。

开发示例

// 自定义同时写入PCM数据和元数据函数
int32_t MyOnWriteDataWithMetadata(
    OH_AudioRenderer* renderer,
    void* userData,
    void* audioData,
    int32_t audioDataSize,
    void* metadata,
    int32_t metadataSize)
{
    // 将待播放的PCM数据和元数据,分别按audioDataSize和metadataSize写入buffer
    return 0;
}

// 设置编码类型
OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_AUDIOVIVID);
// 配置回调函数
OH_AudioRenderer_WriteDataWithMetadataCallback metadataCallback = MyOnWriteDataWithMetadata;
// 设置同时写入PCM数据和元数据的回调
OH_AudioStreamBuilder_SetWriteDataWithMetadataCallback(builder, metadataCallback, nullptr);

最后呢

很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

在这里插入图片描述

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细鸿蒙(OpenHarmony )手册(共计1236页)与鸿蒙(OpenHarmony )开发入门视频,帮助大家在技术的道路上更进一步。

  • 《鸿蒙 (OpenHarmony)开发学习视频》
  • 《鸿蒙生态应用开发V2.0白皮书》
  • 《鸿蒙 (OpenHarmony)开发基础到实战手册》
  • OpenHarmony北向、南向开发环境搭建
  • 《鸿蒙开发基础》
  • 《鸿蒙开发进阶》
  • 《鸿蒙开发实战》

在这里插入图片描述

总结

鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1992018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

根据 IP 地址配置子网示例(下挂 hub 接不同 vlan 终端)

我们一般根据端口配置子网比较简单&#xff0c;但是如果换接口&#xff0c;就又要到交换机上重新配置端口所属 vlan 了&#xff0c;紧急情况下&#xff0c;还是比较耽误时间的。但如果根据IP地址配置 vlan&#xff0c;则可以插在交换机上任意端口&#xff0c;排障时比较节省时间…

部分PC制造商不会帮助英特尔第13/14代酷睿延保 对用户来说可能是个问题

早前英特尔已经宣布大部分第 13/14 代酷睿桌面处理器将可以获得延长保修服务&#xff0c;即后续使用出现非人为损坏的问题后&#xff0c;用户都可以联系英特尔换一颗新处理器。然而英特尔承担责任不代表对用户来说就高枕无忧&#xff0c;例如只有盒装版处理器才能直接联系英特尔…

MySQL数据库分区

文章目录 1. 分区的基本概念2. 分区的类型3. 在 MySQL 中实现分区3.1 创建分区表3.2 插入数据3.3 查询数据3.4 修改分区3.5 查看分区信息 4. 具体示例4.1 范围分区 (Range Partitioning)4.2 列表分区 (List Partitioning)4.3 哈希分区 (Hash Partitioning)4.4 键分区 (Key Part…

Win32注册表操作

注册表的概念 注册表是一个存储计算机配置信息的数据库&#xff0c;用于存储计算机上的硬件、安装的软件、系统设置以及用户账户配置等重要信息。对注册表的编辑不当可能会影响计算机的正常运行。应用程序可以调用API函数来对注册表进行增、删等操作。 注册表结构 运行Regedi…

【Redis 进阶】Redis 典型应用 —— 分布式锁

一、什么是分布式锁 在一个分布式的系统中&#xff0c;也会涉及到多个节点访问同一个公共资源的情况&#xff0c;此时就需要通过锁来做互斥控制, 避免出现类似于 “线程安全” 的问题。 而 Java 的 synchronized 或者 C 的 std::mutex&#xff0c;这样的锁都是只能在当前进程…

Embedding技术之Word Embedding

Word Embedding是什么&#xff1f; Word Embedding——词嵌入是将单词映射为数值向量&#xff0c;以捕捉单词间的语义和句法关系&#xff0c;为自然语言处理任务提供有效的特征表示。——自然语言处理——Word2Vec、GloVe、FastText。 Word Embedding属于静态向量&#xff0c…

深度学习入门(四):激活函数与LSTM

激活函数 激活函数在神经网络中扮演着至关重要的角色。它们的主要功能是引入非线性因素&#xff0c;这使得神经网络能够学习和近似任何非线性函数&#xff0c;从而处理复杂的数据模式和决策边界。如果没有激活函数&#xff0c;即使网络拥有很多层&#xff0c;其表达能力仍然只…

青岛国真携手图扑软件共建青岛西海岸区一网统管平台

为深入贯彻关于垃圾分类的重要指示精神&#xff0c;积极响应住房和城乡建设部开展的全国城市生活垃圾分类宣传周活动&#xff0c;5 月 25 - 27 日&#xff0c;以“发挥行业协会新动能 助力垃圾分类新时尚”为主题的“ 2023 垃圾分类高峰论坛”在青岛西海岸成功举办。 青岛国真智…

使用影子凭证进行域权限维持

本文来源无问社区&#xff0c;更对实战内容&#xff0c;渗透思路可前往查看http://wwlib.cn/index.php/artread/artid/15293.html Microsoft 推出了 Windows Hello 企业版 &#xff08;WHfB&#xff09;&#xff0c;以使用基于密钥的信任模型替换传统的基于密码的身份验证。此…

【Material-UI】按钮组:尺寸与颜色详解

文章目录 一、按钮组概述1. 组件介绍2. 基本用法 二、按钮组的尺寸&#xff08;Sizes&#xff09;1. 小尺寸&#xff08;Small&#xff09;2. 中等尺寸&#xff08;Medium&#xff09;3. 大尺寸&#xff08;Large&#xff09; 三、按钮组的颜色&#xff08;Colors&#xff09;1…

gitea docker 快捷安装部署

前言 在前一篇博文&#xff08;什么是 Gitea&#xff1f;&#xff09;中&#xff0c;我们详细介绍了gitea的功能特性&#xff0c;以及其与其它git服务器之间的特性多维度对比。 在本文中&#xff0c;我们将详细介绍gitea的快捷安装部署&#xff0c;docker方式&#xff01; 1…

qt客户端与服务端通信

服务器要一处于监听状态 客户端主动连接服务器 服务器的ui界面 客户端的ui界面 很简陋 服务端listen 按钮的槽函数 QHostAddress::Any,port 监听任何端口 void MainWindow::on_listen_clicked() {if(ui->lineEdit->text().isEmpty()){return ;}int port ui->li…

【第九节】python中xml解析和json编解码

目录 一、Python XML 解析 1.1 什么是XML 1.2 Python 对 XML 的解析方法 1.3 SAX解析xml 1.4 xml.dom解析xml 1.6 ElementTree解析XML 二、Python编解码json 2.1 什么是json 2.2 使用json 库 2.3 使用第三方库Demjson 一、Python XML 解析 1.1 什么是XML XML&#x…

Python新手错误集锦(PyCharm)

# 自学Python&#xff0c;用Pycharm作环境。我这个手新到这时我学习的第一个编程软件&#xff0c;且本人专业是化学&#xff0c;以前对电脑最高级的使用是玩扫雷游戏。所以这里集合的错误都是小透明错误&#xff0c;大部分人请绕道。不断更新中...... 缩进错误 记住“indent”…

Jmeter之BeanShell使用(全网最详细的介绍)-第九天

一.什么是BeanShell Java写成的⼩型、免费的Java源代码解释器可以执⾏标准Java语句和表达式,完全符合java语法的java脚本语⾔&#xff08;需要会javase语⾔&#xff09;包括⼀些脚本命令&#xff0c;有⾃⼰的⼀些语法和⽅法&#xff0c;是⼀种松散类型的脚本语⾔&#xff08;这…

静电消除器的产品功能介绍

省维护&#xff1a;超高等级 冲击波可引起空间隔断&#xff0c;从而将外部空气的进入降至最低。与以往的针尖保护构造相比&#xff0c;通过形成绝对的空气屏障&#xff0c;实现了低流量且惊人的省维护性能。 大范围消除静电 配备了 Hi-Power I.C.C. 系统&#xff0c;除了可根据…

普通话水平测试证书真的有用吗?

对于部分考生而言报名普通话水平测试只是随大流&#xff0c;看周围同学都考了&#xff0c;自己也来报名。还有一些呢是看到博主总结哪些证好考有用&#xff0c;先拿下再说但是并不知道具体有什么用。那么&#xff0c;普通话水平测试证书&#xff0c;究竟能为我们带来什么呢&…

MyBatis Generator 代码生成器数据库表新增字段,不覆盖原文件

1.数据库窜库&#xff0c;配置了覆盖插件他会找其他库中同名的表 修改数据库链接 添加 &amp;nullCatalogMeansCurrenttrue <!-- 配置数据源&#xff0c;需要根据自己的项目修改 --><jdbcConnection driverClass"com.mysql.cj.jdbc.Driver"connect…

钡铼技术防水分线盒M12双通道4路DIN智能建筑自动化

钡铼技术的DB系列4路M12双通道预铸线缆分线盒是专为智能建筑自动化和工业自动化设备设计的先进解决方案。其工业级设计和耐酸碱腐蚀材料壳体&#xff0c;使其能够在恶劣环境下稳定运行&#xff0c;并且具备IP67和IP69K防护等级&#xff0c;保证了在高压高温水流清洗条件下的可靠…

python学习自制彩色,自定义格式日志打印制作LLoghelper

python学习自制彩色&#xff0c;自定义格式日志打印LLoghelper python print(xxx) 打印出来只显示白色黑底&#xff0c;没有时间&#xff0c;路径&#xff0c;不同的控制台颜色&#xff0c;对一个没有错误崩溃的python项目来说这样调试起一些逻辑非常不方便 目标&#xff1a; …