opensles-playback.md 3.3 KB
Newer Older
Mr-YX's avatar
Mr-YX 已提交
1
# OpenSL ES音频播放开发指导 
2

Z
zengyawen 已提交
3
## 简介
4

Z
zengyawen 已提交
5
开发者可以通过本文档了解在**OpenHarmony**中如何使用**OpenSL ES**进行音频播放相关操作;当前仅实现了部分[**OpenSL ES**接口](https://gitee.com/openharmony/third_party_opensles/blob/master/api/1.0.1/OpenSLES.h),因此调用未实现接口后会返回**SL_RESULT_FEATURE_UNSUPPORTED**
6
 
Z
zengyawen 已提交
7
## 开发指导
8

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

1. 添加头文件
12 13 14 15 16 17 18

    ```c++
    #include <OpenSLES.h>
    #include <OpenSLES_OpenHarmony.h>
    #include <OpenSLES_Platform.h>
    ```

Mr-YX's avatar
Mr-YX 已提交
19
2. 使用 **slCreateEngine** 接口和获取 **engine** 实例
20 21 22 23 24 25 26 27 28 29 30 31 32 33

    ```c++
    SLObjectItf engineObject = nullptr;
    slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
    (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
    ```

3. 获取接口 **SL_IID_ENGINE****engineEngine** 实例

    ```c++
    SLEngineItf engineEngine = nullptr;
    (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
    ```

Mr-YX's avatar
Mr-YX 已提交
34
4. 配置播放器信息,创建 **AudioPlayer** 
35 36 37 38 39 40 41

    ```c++
    SLDataLocator_BufferQueue slBufferQueue = {
        SL_DATALOCATOR_BUFFERQUEUE,
        0
    };
    
42
    // 具体参数需要根据音频文件格式进行适配
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
    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);
    ```

5. 获取接口 **SL_IID_OH_BUFFERQUEUE****bufferQueueItf** 实例

Z
zengyawen 已提交
61
    ```c++
62 63 64 65
    SLOHBufferQueueItf bufferQueueItf;
    (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf);
    ```

66
6. 打开音频文件,注册 **BufferQueueCallback** 回调
67 68 69 70

    ```c++
    FILE *wavFile_ = nullptr;
    
71
    static void BufferQueueCallback (SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size)
72 73 74 75 76 77 78 79 80 81 82 83 84
    {
        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;
    }
    
85
    // wavFile_ 需要设置为用户想要播放的文件描述符
86
    wavFile_ = fopen(path, "rb");
87
    (*bufferQueueItf)->RegisterCallback(bufferQueueItf, BufferQueueCallback, wavFile_);
88 89 90 91 92 93 94 95 96 97
    ```

7. 获取接口 **SL_PLAYSTATE_PLAYING****playItf** 实例,开始播放

    ```c++
    SLPlayItf playItf = nullptr;
    (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_PLAY, &playItf);
    (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
    ```

98
8. 结束音频播放
99 100 101 102 103

    ```c++
    (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
    (*pcmPlayerObject)->Destroy(pcmPlayerObject);
    (*engineObject)->Destroy(engineObject);
Mr-YX's avatar
Mr-YX 已提交
104
    ```