鸿蒙(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

相关文章

使用Python删除Excel中的行列和单元格示例详解

《使用Python删除Excel中的行列和单元格示例详解》在处理Excel数据时,删除不需要的行、列或单元格是一项常见且必要的操作,本文将使用Python脚本实现对Excel表格的高效自动化处理,感兴... 目录开发环境准备使用 python 删除 Excphpel 表格中的行删除特定行删除空白行删除含指定

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

prometheus如何使用pushgateway监控网路丢包

《prometheus如何使用pushgateway监控网路丢包》:本文主要介绍prometheus如何使用pushgateway监控网路丢包问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录监控网路丢包脚本数据图表总结监控网路丢包脚本[root@gtcq-gt-monitor-prome

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

SpringBoot中如何使用Assert进行断言校验

《SpringBoot中如何使用Assert进行断言校验》Java提供了内置的assert机制,而Spring框架也提供了更强大的Assert工具类来帮助开发者进行参数校验和状态检查,下... 目录前言一、Java 原生assert简介1.1 使用方式1.2 示例代码1.3 优缺点分析二、Spring Fr

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected