Android播放器-OpenSLES使用流程

  1. 创建并设置SL引擎
  2. 创建并设置混音器
  3. 创建并设置播放器(有数据队列),设置回调并写入缓存队列

enqueue()->Buffer Queue->slBufferQueueCallback

初始化引擎

SLObjectltf engineObject = NULL; // 相当于引擎上下文
SLEngineltf engineEngine = NULL; // 引擎对象接口

slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);

(*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); // 阻塞方法,也可以用其他的回调方法
(*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);

具体函数参数

// 创建对象
SL_API SLresult SLAPIENTRY slCreateEngine(
SLObjectltf *pEngine,
SLuint32 numOptions,
const SLEngineOption *pEngineOptions, // 选择项目 默认参数
SLuint32 numInterfaces,
const SLInterfaceID *pInterfaceIds, // 支持的接口
const SLboolean *pInterceRequired // 接口标识数值,是否支持
)

// 实例化
SLresult (*Realize)(
SLObjectltf self,
SLboolean async
)
对象已实现状态(false阻塞)

// 获取接口
SLresult (*GetInterface)(
SLObjectltf self,
const SLInterfaceID id,
void *pInterface
)

创建输出设备

SLEngineltf engineEngine = NULL;
SLObjectltf outputMixObject = NULL;

(*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0);
// 实例化
(*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); // 阻塞

// 输出对象
SLDataLocator_OutputMix outputMix = {
SL_DATALOCATOR_OUTPUT_MIX,
outputMixObject
};

SLDataSink audioSnk = {&outputMix, NULL}

配置PCM格式信息

// 缓存队列配置信息
SLDataLocator_AndroidSimpleBufferQueue android_queue = {
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
2
};
// 播放的音频的格式信息
SLDataFormat_PCM pcm = {
SL_DATAFORMAT_PCM, // 播放pcm格式的数据
2, // 2个声道
SL_SAMPLINGRATE_44_1, // 44100hz的频率
SL_PCMSAMPLEFORMAT_FIXED_16, // 位数 16位
SL_PCMSAMPLEFORMAT_FIXED_16, // 和位数一致就行
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_PRONT_RIGHT, // 立体声(前左前右)
SL_BYTEORDER_LITTLEENDIAN // 字节序 小端模式
}

SLDataSource slDataSource = {
&android_queue,
&pcm
};

初始化播放器

const SLInterfaceID ids[1] = {SL_IID_BUFFERQUEUE};
const SLboolean req[1] = {SL_BOOLEAN_TRUE};

// 创建
(*engineEngine)->CreateAudioPlayer(
engineEngine,
&pcmPlayerObject,
&slDataSource,
&audioSnk,
1,
ids,
req);

// 初始化
(*pcmPlayerObject)->Realize(pcmPlayerObject, SL_BOOLEAN_FALSE);

// 得到接口后调用 获取Player接口
(*pcmPlayerObject)->GetInterface(
pcmPlayerObject,
SL_IID_PLAY,
&pcmPlayerPlay);

播放和缓存队列

注册回调缓冲区

// 获取缓冲区队列接口
(*pcmPlayerObject)->GetInterface(
pcmPlayerObject,
SL_IID_BUFFERQUEUE,
&pcmBufferQueue);

// 在缓冲区读完之后,回调函数就会调用
(*pcmBufferQueue)->RegisterCallback(
pcmBufferQueue,
pcmBufferCallBack,
NULL);
// 回调函数被调用后,需要立刻往缓冲队列里加数据,否则会出现断音

(*pcmPlayerPlay)->SetPlayState(pcmPlayerPlay, SL_PLAYSTATE_PLAYING);

// 发一个空数据""={\0} (0是不会发声的),激活回调
(*pcmBufferQueue)->Enqueue(pcmBufferQueue, "", 1);


打赏