当前位置: 首页 > news >正文

android系统使用FFmpeng集成OpenSL音频录制和播放

目录

一、背景

二、方案

三、代码实现

3.1 初始化OpenSL

3.2 设置播放回掉

3.3 使用FFmpeg计算出转换后的样本数目

 


一、背景

FFmpeg不能够操作Android的硬件设备,所以要在Android系统上面播放音频的话需要另找办法

二、方案

Android 环境下音频播放通常有两种方式—— AudioTrack 和 OpenSLES。AudioTrack 本身是Java实现,另外一种实现方式就是OpenSL ES 播放音频。


三、代码实现

3.1 初始化OpenSL

void AudioChannel::initOpenSL() {//创建引擎SLresult result;// 创建引擎engineObjectresult = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);if (SL_RESULT_SUCCESS != result) {return;}// 初始化引擎engineObjectresult = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);if (SL_RESULT_SUCCESS != result) {return;}// 获取引擎接口engineEngineresult = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE,&engineInterface);if (SL_RESULT_SUCCESS != result) {return;}// 创建混音器outputMixObjectresult = (*engineInterface)->CreateOutputMix(engineInterface, &outputMixObject, 0, 0, 0);if (SL_RESULT_SUCCESS != result) {return;}// 初始化混音器outputMixObjectresult = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);if (SL_RESULT_SUCCESS != result) {return;}/*** 配置输入声音信息*///创建buffer缓冲类型的队列 2个队列SLDataLocator_AndroidSimpleBufferQueue android_queue = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,2};//pcm数据格式SLDataFormat_PCM pcm = {SL_DATAFORMAT_PCM, 2, SL_SAMPLINGRATE_44_1, SL_PCMSAMPLEFORMAT_FIXED_16,SL_PCMSAMPLEFORMAT_FIXED_16,SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,SL_BYTEORDER_LITTLEENDIAN};//数据源 将上述配置信息放到这个数据源中SLDataSource slDataSource = {&android_queue, &pcm};//设置混音器SLDataLocator_OutputMix outputMix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};SLDataSink audioSnk = {&outputMix, NULL};//需要的接口const SLInterfaceID ids[1] = {SL_IID_BUFFERQUEUE};const SLboolean req[1] = {SL_BOOLEAN_TRUE};//创建播放器(*engineInterface)->CreateAudioPlayer(engineInterface, &bqPlayerObject, &slDataSource,&audioSnk, 1,ids, req);//初始化播放器(*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);//    得到接口后调用  获取Player接口(*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerInterface);//    获得播放器接口(*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,&bqPlayerBufferQueue);//设置回调(*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, this);
//    设置播放状态(*bqPlayerInterface)->SetPlayState(bqPlayerInterface, SL_PLAYSTATE_PLAYING);bqPlayerCallback(bqPlayerBufferQueue, this);
}

3.2 设置播放回掉

//第一次主动调用在调用线程
//之后在新线程中回调
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) {AudioChannel *audioChannel = static_cast<AudioChannel *>(context);int datalen = audioChannel->getPcm();if (datalen > 0) {(*bq)->Enqueue(bq, audioChannel->buffer, datalen);}
}

3.3 使用FFmpeg计算出转换后的样本数目

uint64_t dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, frame->sample_rate) + frame->nb_samples,out_sample_rate,frame->sample_rate,AV_ROUND_UP);// 转换,返回值为转换后的sample个数int nb = swr_convert(swr_ctx, &buffer, dst_nb_samples,(const uint8_t **) frame->data, frame->nb_samples);//转换后多少数据data_size = nb * out_channels * out_samplesize;//音频的时间clock = frame->best_effort_timestamp * av_q2d(time_base);if (javaCallHelper) {javaCallHelper->onProgress(THREAD_CHILD, clock);}



 

相关文章:

  • 深度剖析:GPT-3.5与GPT-4的主要区别及架构解析
  • 摄影跟拍预定|基于java+vue的摄影跟拍预定管理系统(源码+数据库+文档)
  • list的模拟实现和反向迭代器的底层
  • PcVue助力立讯:精密制造的智能化管控实践!
  • 一篇讲完自动化测试基础-Python【万字详细讲解】12
  • PostgreSQL连接管理深度解析
  • 鸿蒙API15 “一多开发”适配:解锁黄金三角法则,开启高效开发新旅程
  • 实战|使用环信Flutter SDK构建鸿蒙HarmonyOS应用及推送配置
  • 首席人工智能官(Chief Artificial Intelligence Officer,CAIO)的详细解析
  • 【Linux】第九章 控制服务和守护进程
  • 常见的低代码策略整理
  • Hbuilder 上的水印相机实现方案 (vue3 + vite + hbuilder)
  • Unity URP Moblie AR示例工程,真机打包出来,没阴影
  • iOS15描述文件在哪下载?iOS15测试版描述文件下载与升级教程
  • 笔试专题(十)
  • 再论火车实验-11
  • 合成数据赋能AI:从生成到闭环的全景图谱
  • SAP HANA使用命令行快速导出导入
  • 设计模式入门:从 GoF 分类到 SOLID 原则实战
  • 08软件测试需求分析案例-删除用户
  • 特朗普与普京就俄乌问题通话
  • 事关中国,“英伟达正游说美国政府”
  • 家庭医生可提前5天预约三甲医院号源,上海常住人口签约率达45%,
  • 以色列媒体:哈马斯愿意释放部分人员换取两个月停火
  • 以军称已开始在加沙的新一轮大规模攻势
  • 《五行令》《攻守占》,2个月后国博见