鸿蒙(API 12 Beta3版)【使用AVPlayer开发音频播放功能(C/C++)】音视播放与录制

本文主要是介绍鸿蒙(API 12 Beta3版)【使用AVPlayer开发音频播放功能(C/C++)】音视播放与录制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

使用AVPlayer可以实现端到端播放原始媒体资源,本开发指导将以完整地播放一首音乐作为示例,向开发者讲解AVPlayer音频播放相关功能。

播放的全流程包含:创建AVPlayer,设置播放资源,设置播放参数(音量/倍速/焦点模式),播放控制(播放/暂停/跳转/停止),重置,销毁资源。

在进行应用开发的过程中,开发者可以通过AVPlayer的callback主动获取播放过程信息。如果应用在音频播放器处于错误状态时执行操作,系统可能会抛出异常或生成其他未定义的行为。

图1 播放状态变化示意图

1

状态的详细说明请参考[AVPlayerState]。当播放处于prepared / playing / paused / completed状态时,播放引擎处于工作状态,这需要占用系统较多的运行内存。当客户端暂时不使用播放器时,调用reset()或release()回收内存资源,做好资源利用。

开发建议

当前指导仅介绍如何实现媒体资源播放,在应用开发过程中可能会涉及后台播放、播放冲突等情况,请根据实际需要参考以下说明。

  • 如果要实现后台播放或熄屏播放,需要接入[AVSession(媒体会话)]和[申请长时任务],避免播放被系统强制中断。此功能仅提供ArkTS API。
  • 应用在播放过程中,若播放的媒体数据涉及音频,根据系统音频管理策略(参考[处理音频焦点事件]),可能会被其他应用打断,建议应用通过[OH_AVPlayer_SetPlayerCallback()]主动监听音频打断事件[AV_INFO_TYPE_INTERRUPT_EVENT],根据其内容提示,做出相应的处理,避免出现应用状态与预期效果不一致的问题。
  • 面对设备同时连接多个音频输出设备的情况,应用可以通过[OH_AVPlayer_SetPlayerCallback()]主动监听音频输出设备改变事件[AV_INFO_TYPE_AUDIO_OUTPUT_DEVICE_CHANGE],从而做出相应处理。

开发步骤及注意事项

在 CMake 脚本中链接动态库

target_link_libraries(sample PUBLIC libavplayer.so)

开发者通过引入[avplayer.h]、[avpalyer_base.h]和[native_averrors.h]头文件,使用音频播放相关API。

  1. 创建实例OH_AVPlayer_Create(),AVPlayer初始化idle状态。

  2. 设置业务需要的监听事件OH_AVPlayer_SetPlayerCallback(),搭配全流程场景使用。支持的监听事件包括:

    事件类型说明
    OH_AVPlayerOnInfo必要事件,监听播放器的过程信息。
    OH_AVPlayerOnError必要事件,监听播放器的错误信息。
  3. 设置资源:调用OH_AVPlayer_SetURLSource(),设置属性url,AVPlayer进入initialized状态。

  4. (可选)设置音频流类型:调用OH_AVPlayer_SetAudioRendererInfo(),设置AVPlayer音频流类型。

  5. (可选)设置音频打断模式:调用OH_AVPlayer_SetAudioInterruptMode(),设置AVPlayer音频流打断模式。

  6. 准备播放:调用OH_AVPlayer_Prepare(),AVPlayer进入prepared状态,此时可以获取时长,设置音量。

  7. (可选)设置音频音效模式:调用OH_AVPlayer_SetAudioEffectMode(),设置AVPlayer音频音效模式。

  8. 音频播控:播放OH_AVPlayer_Play(),暂停OH_AVPlayer_Pause(),跳转OH_AVPlayer_Seek(),停止OH_AVPlayer_Stop() 等操作。

  9. (可选)更换资源:调用OH_AVPlayer_Reset()重置资源,AVPlayer重新进入idle状态,允许更换资源url。

  10. 退出播放:调用OH_AVPlayer_Release()销毁实例,AVPlayer进入released状态,退出播放。

完整示例

#include "napi/native_api.h"#include <multimedia/player_framework/avplayer.h>
#include <multimedia/player_framework/avplayer_base.h>
#include <multimedia/player_framework/native_averrors.h>static char *Url;void OnInfo(OH_AVPlayer *player, AVPlayerOnInfoType type, int32_t extra)
{int32_t ret;switch (type) {case AV_INFO_TYPE_STATE_CHANGE:switch (extra) {case AV_IDLE: // 成功调用reset接口后触发该状态机上报
//                    ret = OH_AVPlayer_SetURLSource(player, url); // 设置url
//                    if (ret != AV_ERR_OK) {
//                    // 处理异常
//                    }break;case AV_INITIALIZED: ret = OH_AVPlayer_Prepare(player); //设置播放源后触发该状态上报if (ret != AV_ERR_OK) {// 处理异常}break;case AV_PREPARED:            
//                    ret = OH_AVPlayer_SetAudioEffectMode(player, EFFECT_NONE); // 设置音频音效模式
//                    if (ret != AV_ERR_OK) {
//                    //处理异常    
//                    }  ret = OH_AVPlayer_Play(player); // 调用播放接口开始播放if (ret != AV_ERR_OK) {// 处理异常}break;case AV_PLAYING:  
//                    ret = OH_AVPlayer_Pause(player); //调用暂停接口暂停播放
//                    if (ret != AV_ERR_OK) {
//                    // 处理异常
//                    }break;case AV_PAUSED:  
//                    ret = OH_AVPlayer_Play(player); // 再次播放接口开始播放
//                    if (ret != AV_ERR_OK) {
//                    // 处理异常
//                    }break;case AV_STOPPED:  ret = OH_AVPlayer_Release(player); //调用reset接口初始化avplayer状态if (ret != AV_ERR_OK) {// 处理异常}break;case AV_COMPLETED:  ret = OH_AVPlayer_Stop(player);// 调用播放结束接口if (ret != AV_ERR_OK) {// 处理异常}break;default:break;}break;case AV_INFO_TYPE_POSITION_UPDATE:// do somethingbreak;default:break;}
}void OnError(OH_AVPlayer *player, int32_t errorCode, const char *errorMsg)
{// do something
}// 调用播放方法时,需要在index.d.ts文件内描述映射的play方法,需要传入一个string类型的参数
// ets文件调用播放方法时,传入文件路径 testNapi.play("/data/test/test.mp3")
static napi_value Play(napi_env env, napi_callback_info info)
{size_t argc = 1;napi_value args[1] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 获取参数类型napi_valuetype stringType;if (napi_ok != napi_typeof(env, args[0], &stringType)) {// 处理异常return nullptr;}// 参数校验if (napi_null == stringType) {// 处理异常return nullptr;}// 获取传递的string长度size_t length = 0;if (napi_ok != napi_get_value_string_utf8(env, args[0], nullptr, 0, &length)) {// 处理异常return nullptr;}// 如果传入的是"",则直接返回if (length == 0) {// 处理异常return nullptr;}// 读取传入的string放入buffer中char *url = new char[length + 1];if (napi_ok != napi_get_value_string_utf8(env, args[0], url, length + 1, &length)) {delete[] url;url = nullptr;// 处理异常return nullptr;}Url = url;// 创建播放实例OH_AVPlayer *player = OH_AVPlayer_Create();AVPlayerCallback callback;callback.onInfo = OnInfo;callback.onError = OnError;// 设置回调,监听信息int32_t ret = OH_AVPlayer_SetPlayerCallback(player, callback);if (ret != AV_ERR_OK) {// 处理异常}ret = OH_AVPlayer_SetURLSource(player, url); // 设置urlif (ret != AV_ERR_OK) {// 处理异常}// 设置音频流类型OH_AudioStream_Usage streamUsage = OH_AudioStream_Usage::AUDIOSTREAM_USAGE_UNKNOWN;ret = OH_AVPlayer_SetAudioRendererInfo(player, streamUsage);if (ret != AV_ERR_OK) {//处理异常    }// 设置音频流打断模式OH_AudioInterrupt_Mode interruptMode = OH_AudioInterrupt_Mode::AUDIOSTREAM_INTERRUPT_MODE_INDEPENDENT;ret = OH_AVPlayer_SetAudioInterruptMode(player, interruptMode);if (ret != AV_ERR_OK) {//处理异常    }napi_value value;napi_create_int32(env, 0, &value);return value;
}EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{napi_property_descriptor desc[] = {{ "play", nullptr, Play, nullptr, nullptr, nullptr, napi_default, nullptr }};napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);return exports;
}
EXTERN_C_ENDstatic napi_module demoModule = {.nm_version =1,.nm_flags = 0,.nm_filename = nullptr,.nm_register_func = Init,.nm_modname = "entry",.nm_priv = ((void*)0),.reserved = { 0 },
};extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
{napi_module_register(&demoModule);
}

最后呢

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

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙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 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿
1

这篇关于鸿蒙(API 12 Beta3版)【使用AVPlayer开发音频播放功能(C/C++)】音视播放与录制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1107544

相关文章

java图像识别工具类(ImageRecognitionUtils)使用实例详解

《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

python管理工具之conda安装部署及使用详解

《python管理工具之conda安装部署及使用详解》这篇文章详细介绍了如何安装和使用conda来管理Python环境,它涵盖了从安装部署、镜像源配置到具体的conda使用方法,包括创建、激活、安装包... 目录pytpshheraerUhon管理工具:conda部署+使用一、安装部署1、 下载2、 安装3

Mysql虚拟列的使用场景

《Mysql虚拟列的使用场景》MySQL虚拟列是一种在查询时动态生成的特殊列,它不占用存储空间,可以提高查询效率和数据处理便利性,本文给大家介绍Mysql虚拟列的相关知识,感兴趣的朋友一起看看吧... 目录1. 介绍mysql虚拟列1.1 定义和作用1.2 虚拟列与普通列的区别2. MySQL虚拟列的类型2

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

关于@MapperScan和@ComponentScan的使用问题

《关于@MapperScan和@ComponentScan的使用问题》文章介绍了在使用`@MapperScan`和`@ComponentScan`时可能会遇到的包扫描冲突问题,并提供了解决方法,同时,... 目录@MapperScan和@ComponentScan的使用问题报错如下原因解决办法课外拓展总结@

mysql数据库分区的使用

《mysql数据库分区的使用》MySQL分区技术通过将大表分割成多个较小片段,提高查询性能、管理效率和数据存储效率,本文就来介绍一下mysql数据库分区的使用,感兴趣的可以了解一下... 目录【一】分区的基本概念【1】物理存储与逻辑分割【2】查询性能提升【3】数据管理与维护【4】扩展性与并行处理【二】分区的

使用Python实现在Word中添加或删除超链接

《使用Python实现在Word中添加或删除超链接》在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能,本文将为大家介绍一下Python如何实现在Word中添加或... 在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能。通过添加超

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,