鸿蒙(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使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

MyBatis ParameterHandler的具体使用

《MyBatisParameterHandler的具体使用》本文主要介绍了MyBatisParameterHandler的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一、概述二、源码1 关键属性2.setParameters3.TypeHandler1.TypeHa

Spring 中的切面与事务结合使用完整示例

《Spring中的切面与事务结合使用完整示例》本文给大家介绍Spring中的切面与事务结合使用完整示例,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录 一、前置知识:Spring AOP 与 事务的关系 事务本质上就是一个“切面”二、核心组件三、完