1# OpenSL ES音频播放开发指导 2 3## 简介 4 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 7## 开发指导 8 9以下步骤描述了在**OpenHarmony**如何使用**OpenSL ES**开发音频播放功能: 10 111. 添加头文件 12 13 ```c++ 14 #include <OpenSLES.h> 15 #include <OpenSLES_OpenHarmony.h> 16 #include <OpenSLES_Platform.h> 17 ``` 18 192. 使用 **slCreateEngine** 接口和获取 **engine** 实例 20 21 ```c++ 22 SLObjectItf engineObject = nullptr; 23 slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr); 24 (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 25 ``` 26 273. 获取接口 **SL_IID_ENGINE** 的 **engineEngine** 实例 28 29 ```c++ 30 SLEngineItf engineEngine = nullptr; 31 (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 32 ``` 33 344. 配置播放器信息,创建 **AudioPlayer** 35 36 ```c++ 37 SLDataLocator_BufferQueue slBufferQueue = { 38 SL_DATALOCATOR_BUFFERQUEUE, 39 0 40 }; 41 42 // 具体参数需要根据音频文件格式进行适配 43 SLDataFormat_PCM pcmFormat = { 44 SL_DATAFORMAT_PCM, 45 2, 46 48000, 47 16, 48 0, 49 0, 50 0 51 }; 52 SLDataSource slSource = {&slBufferQueue, &pcmFormat}; 53 54 SLObjectItf pcmPlayerObject = nullptr; 55 (*engineEngine)->CreateAudioPlayer(engineEngine, &pcmPlayerObject, &slSource, null, 0, nullptr, nullptr); 56 (*pcmPlayerObject)->Realize(pcmPlayerObject, SL_BOOLEAN_FALSE); 57 ``` 58 595. 获取接口 **SL_IID_OH_BUFFERQUEUE** 的 **bufferQueueItf** 实例 60 61 ```c++ 62 SLOHBufferQueueItf bufferQueueItf; 63 (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf); 64 ``` 65 666. 打开音频文件,注册 **BufferQueueCallback** 回调 67 68 ```c++ 69 FILE *wavFile_ = nullptr; 70 71 static void BufferQueueCallback (SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size) 72 { 73 FILE *wavFile = (FILE *)pContext; 74 if (!feof(wavFile)) { 75 SLuint8 *buffer = nullptr; 76 SLuint32 pSize = 0; 77 (*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, pSize); 78 //从文件读取数据 79 fread(buffer, 1, size, wavFile); 80 (*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, size); 81 } 82 return; 83 } 84 85 // wavFile_ 需要设置为用户想要播放的文件描述符 86 wavFile_ = fopen(path, "rb"); 87 (*bufferQueueItf)->RegisterCallback(bufferQueueItf, BufferQueueCallback, wavFile_); 88 ``` 89 907. 获取接口 **SL_PLAYSTATE_PLAYING** 的 **playItf** 实例,开始播放 91 92 ```c++ 93 SLPlayItf playItf = nullptr; 94 (*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_PLAY, &playItf); 95 (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING); 96 ``` 97 988. 结束音频播放 99 100 ```c++ 101 (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); 102 (*pcmPlayerObject)->Destroy(pcmPlayerObject); 103 (*engineObject)->Destroy(engineObject); 104 ```