OpenSL ES音频播放开发指导


OpenSL ES音频播放开发指导

简介

开发者可以通过本文档了解在OpenHarmony中如何使用OpenSL ES进行音频播放相关操作;当前仅实现了部分OpenSL ES接口,因此调用未实现接口后会返回SL_RESULT_FEATURE_UNSUPPORTED

开发指导

以下步骤描述了在OpenHarmony如何使用OpenSL ES开发音频播放功能:

  1. 添加头文件

    #include <OpenSLES.h>
    #include <OpenSLES_OpenHarmony.h>
    #include <OpenSLES_Platform.h>
    
    1
    2
    3
  2. 使用 slCreateEngine 接口和获取 engine 实例

    SLObjectItf engineObject = nullptr;
    slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
    (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
    
    1
    2
    3
  3. 获取接口 SL_IID_ENGINEengineEngine 实例

    SLEngineItf engineEngine = nullptr;
    (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
    
    1
    2
  4. 配置播放器信息,创建 AudioPlayer

    SLDataLocator_BufferQueue slBufferQueue = {
        SL_DATALOCATOR_BUFFERQUEUE,
        0
    };
    
    // 具体参数需要根据音频文件格式进行适配
    SLDataFormat_PCM pcmFormat = {
        SL_DATAFORMAT_PCM,
        2,
        48000,
        16,
        0,
        0,
        0
    };
    SLDataSource slSource = {&slBufferQueue, &pcmFormat};
    
    SLObjectItf pcmPlayerObject = nullptr;
    (*engineEngine)->CreateAudioPlayer(engineEngine, &pcmPlayerObject, &slSource, null, 0, nullptr, nullptr);
    (*pcmPlayerObject)->Realize(pcmPlayerObject, SL_BOOLEAN_FALSE);
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
  5. 获取接口 SL_IID_OH_BUFFERQUEUEbufferQueueItf 实例

    SLOHBufferQueueItf bufferQueueItf;
    (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf);
    
    1
    2
  6. 打开音频文件,注册 BufferQueueCallback 回调

    FILE *wavFile_ = nullptr;
    
    static void BufferQueueCallback (SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size)
    {
        FILE *wavFile = (FILE *)pContext;
        if (!feof(wavFile)) {
            SLuint8 *buffer = nullptr;
            SLuint32 pSize = 0;
            (*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, pSize);
            //从文件读取数据
            fread(buffer, 1, size, wavFile);
            (*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, size);
        }
        return;
    }
    
    // wavFile_ 需要设置为用户想要播放的文件描述符
    wavFile_ = fopen(path, "rb");
    (*bufferQueueItf)->RegisterCallback(bufferQueueItf, BufferQueueCallback, wavFile_);
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
  7. 获取接口 SL_PLAYSTATE_PLAYINGplayItf 实例,开始播放

    SLPlayItf playItf = nullptr;
    (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_PLAY, &playItf);
    (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
    
    1
    2
    3
  8. 结束音频播放

    (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
    (*pcmPlayerObject)->Destroy(pcmPlayerObject);
    (*engineObject)->Destroy(engineObject);
    
    1
    2
    3