HarmonyOS Developer Native API的相关指导
Drawing开发指导
场景介绍
Native Drawing模块提供了一系列的接口用于基本图形和字体的绘制。常见的应用场景举例:
- 2D图形绘制。
- 文本绘制。
接口说明
接口名 | 描述 |
OH_Drawing_BitmapCreate (void) | 创建一个位图对象。 |
OH_Drawing_BitmapBuild (OH_Drawing_Bitmap *, const uint32_t width, const uint32_t height, const OH_Drawing_BitmapFormat *) | 初始化位图对象的宽度和高度,并且为该位图设置像素格式。 |
OH_Drawing_CanvasCreate (void) | 创建一个画布对象。 |
OH_Drawing_CanvasBind (OH_Drawing_Canvas *, OH_Drawing_Bitmap *) | 将一个位图对象绑定到画布中,使得画布绘制的内容输出到位图中(即CPU渲染)。 |
OH_Drawing_CanvasAttachBrush (OH_Drawing_Canvas *, const OH_Drawing_Brush *) | 设置画刷给画布,画布将会使用设置的画刷样式和颜色去填充绘制的图形形状。 |
OH_Drawing_CanvasAttachPen (OH_Drawing_Canvas *, const OH_Drawing_Pen *) | 设置画笔给画布,画布将会使用设置画笔的样式和颜色去绘制图形形状的轮廓。 |
OH_Drawing_CanvasDrawPath (OH_Drawing_Canvas *, const OH_Drawing_Path *) | 画一个自定义路径。 |
OH_Drawing_PathCreate (void) | 创建一个路径对象。 |
OH_Drawing_PathMoveTo (OH_Drawing_Path *, float x, float y) | 设置自定义路径的起始点位置。 |
OH_Drawing_PathLineTo (OH_Drawing_Path *, float x, float y) | 添加一条到目标点的线段。 |
OH_Drawing_PathClose (OH_Drawing_Path *) | 闭合路径,会添加一条到路径起点位置的线段。 |
OH_Drawing_PenCreate (void) | 创建一个画笔对象。 |
OH_Drawing_PenSetAntiAlias (OH_Drawing_Pen *, bool) | 设置抗锯齿属性,如果为真则说明画笔会启用抗锯齿功能,在绘制图形时会对图形的边缘像素进行半透明的模糊处理。 |
OH_Drawing_PenSetWidth (OH_Drawing_Pen *, float width) | 设置画笔的厚度属性,厚度属性描述了画笔绘制图形轮廓的宽度。 |
OH_Drawing_BrushCreate (void) | 创建一个画刷对象。 |
OH_Drawing_BrushSetColor (OH_Drawing_Brush *, uint32_t color) | 设置画刷的颜色属性,颜色属性描述了画刷填充图形时使用的颜色,用一个32位(ARGB)的变量表示。 |
OH_Drawing_CreateTypographyStyle (void) | 创建一个排版对象,用于定义排版样式。 |
OH_Drawing_CreateTextStyle (void) | 创建一个文本对象,用于定义文本样式。 |
OH_Drawing_TypographyHandlerAddText (OH_Drawing_TypographyCreate *, const char *) | 设置文本内容。 |
OH_Drawing_TypographyPaint (OH_Drawing_Typography *, OH_Drawing_Canvas *, double, double) | 显示文本。 |
详细的接口说明请参考Drawing。
2D图形绘制开发步骤
以下步骤描述了在HarmonyOS如何使用 Native Drawing 模块的画布画笔绘制一个基本的2D图形:
- 创建Bitmap实例。使用drawing_bitmap.h的OH_Drawing_BitmapCreate接口创建一个Bitmap实例cBitmap,并使用OH_Drawing_BitmapBuild指定其长宽大小和像素格式。
// 创建一个bitmap对象
OH_Drawing_Bitmap* cBitmap = OH_Drawing_BitmapCreate();
// 定义bitmap的像素格式
OH_Drawing_BitmapFormat cFormat {COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUYE};
// 构造对应格式的bitmap
OH_Drawing_BitmapBuild(cBitmap, width, height, &cFormat);
- 创建画布实例。使用drawing_canvas.h的OH_Drawing_CanvasCreate接口创建一个画布实例cCanvas,并使用OH_Drawing_CanvasBind接口将cBitmap实例绑定到cCanvas上,后续在画布上绘制的内容会输出到绑定的cBitmap实例中。
// 创建一个canvas对象
OH_Drawing_Canvas* cCanvas = OH_Drawing_CanvasCreate();
// 将画布与bitmap绑定,画布画的内容会输出到绑定的bitmap内存中
OH_Drawing_CanvasBind(cCanvas, cBitmap);
// 使用白色清除画布内容
OH_Drawing_CanvasClear(cCanvas, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0xFF, 0xFF));
- 构造Path形状。使用drawing_path.h提供的接口完成一个五角星形状的构造cPath。
int len = 300;
float aX = 500;
float aY = 500;
float dX = aX - len * std::sin(18.0f);
float dY = aY + len * std::cos(18.0f);
float cX = aX + len * std::sin(18.0f);
float cY = dY;
float bX = aX + (len / 2.0);
float bY = aY + std::sqrt((cX - dX) * (cX - dX) + (len / 2.0) * (len / 2.0));
float eX = aX - (len / 2.0);
float eY = bY;
// 创建一个path对象,然后使用接口连接成一个五角星形状
OH_Drawing_Path* cPath = OH_Drawing_PathCreate();
// 指定path的起始位置
OH_Drawing_PathMoveTo(cPath, aX, aY);
// 用直线连接到目标点
OH_Drawing_PathLineTo(cPath, bX, bY);
OH_Drawing_PathLineTo(cPath, cX, cY);
OH_Drawing_PathLineTo(cPath, dX, dY);
OH_Drawing_PathLineTo(cPath, eX, eY);
// 闭合形状,path绘制完毕
OH_Drawing_PathClose(cPath);
- 设置画笔和画刷样式。使用drawing_pen.h的OH_Drawing_PenCreate接口创建一个画笔实例cPen, 并设置抗锯齿、颜色、线宽等属性,画笔用于形状边框线的绘制。使用drawing_brush.h的OH_Drawing_BrushCreate接口创建一个画刷实例cBrush, 并设置填充颜色, 画刷用于形状内部的填充。使用drawing_canvas.h的OH_Drawing_CanvasAttachPen和OH_Drawing_CanvasAttachBrush接口将画笔画刷的实例设置到画布实例中。
// 创建一个画笔Pen对象,Pen对象用于形状的边框线绘制
OH_Drawing_Pen* cPen = OH_Drawing_PenCreate();
OH_Drawing_PenSetAntiAlias(cPen, true);
OH_Drawing_PenSetColor(cPen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
OH_Drawing_PenSetWidth(cPen, 10.0);
OH_Drawing_PenSetJoin(cPen, LINE_ROUND_JOIN);
// 将Pen画笔设置到canvas中
OH_Drawing_CanvasAttachPen(cCanvas, cPen);
// 创建一个画刷Brush对象,Brush对象用于形状的填充
OH_Drawing_Brush* cBrush = OH_Drawing_BrushCreate();
OH_Drawing_BrushSetColor(cBrush, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0xFF, 0x00));
// 将Brush画刷设置到canvas中
OH_Drawing_CanvasAttachBrush(cCanvas, cBrush);
- 绘制Path形状。使用drawing_canvas.h的OH_Drawing_CanvasDrawPath接口将五角星绘制到画布上,绘制完毕后不再使用的实例需要调用对应的接口进行销毁。
// 在画布上画path的形状,五角星的边框样式为pen设置,颜色填充为Brush设置
OH_Drawing_CanvasDrawPath(cCanvas, cPath);
// 销毁创建的对象
OH_Drawing_BrushDestroy(cBrush);
OH_Drawing_PenDestroy(cPen);
OH_Drawing_PathDestroy(cPath);
- 获取像素数据。使用drawing_bitmap.h的OH_Drawing_BitmapGetPixels接口获取到画布绑定bitmap实例的像素地址,该地址指向的内存包含画布刚刚绘制的像素数据。
// 画完后获取像素地址,地址指向的内存包含画布画的像素数据
void* bitmapAddr = OH_Drawing_BitmapGetPixels(cBitmap);
auto ret = memcpy_s(addr, addrSize, bitmapAddr, addrSize);
if (ret != EOK) {
LOGI("memcpy_s failed");
}
// 销毁canvas对象
OH_Drawing_CanvasDestroy(cCanvas);
// 销毁bitmap对象
OH_Drawing_BitmapDestroy(cBitmap);
文本绘制开发步骤
以下步骤描述了在HarmonyOS中,如何使用Native Drawing模块的文字显示功能:
- 创建画布和bitmap实例
// 创建bitmap
OH_Drawing_Bitmap* cBitmap = OH_Drawing_BitmapCreate();
OH_Drawing_BitmapFormat cFormat {COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE};
OH_Drawing_BitmapBuild(cBitmap, width, height, &cFormat);
// 创建canvas
OH_Drawing_Canvas* cCanvas = OH_Drawing_CanvasCreate();
OH_Drawing_CanvasBind(cCanvas, cBitmap);
OH_Drawing_CanvasClear(cCanvas, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0xFF, 0xFF));
- 设置排版风格
// 选择从左到右/左对齐等排版属性
OH_Drawing_TypographyStyle* typoStyle = OH_Drawing_CreateTypographyStyle();
OH_Drawing_SetTypographyTextDirection(typoStyle, TEXT_DIRECTION_LTR);
OH_Drawing_SetTypographyTextAlign(typoStyle, TEXT_ALIGN_LEFT);
- 设置文本风格
// 设置文字颜色,例如黑色
OH_Drawing_TextStyle* txtStyle = OH_Drawing_CreateTextStyle();
OH_Drawing_SetTextStyleColor(txtStyle, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0x00, 0x00));
// 设置文字大小、字重等属性
double fontSize = 30;
OH_Drawing_SetTextStyleFontSize(txtStyle, fontSize);
OH_Drawing_SetTextStyleFontWeight(txtStyle, FONT_WEIGHT_400);
OH_Drawing_SetTextStyleBaseLine(txtStyle, TEXT_BASELINE_ALPHABETIC);
OH_Drawing_SetTextStyleFontHeight(txtStyle, 1);
// 设置字体类型等
const char* fontFamilies[] = {"Roboto"};
OH_Drawing_SetTextStyleFontFamilies(txtStyle, 1, fontFamilies);
OH_Drawing_SetTextStyleFontStyle(txtStyle, FONT_STYLE_NORMAL);
OH_Drawing_SetTextStyleLocale(txtStyle, "en");
- 生成最终文本显示效果
OH_Drawing_TypographyCreate* handler = OH_Drawing_CreateTypographyHandler(typoStyle,
OH_Drawing_CreateFontCollection());
OH_Drawing_TypographyHandlerPushTextStyle(handler, txtStyle);
// 设置文字内容
const char* text = "HelloWorld\n";
OH_Drawing_TypographyHandlerAddText(handler, text);
OH_Drawing_TypographyHandlerPopTextStyle(handler);
OH_Drawing_Typography* typography = OH_Drawing_CreateTypography(handler);
// 设置页面最大宽度
double maxWidth = 800.0;
OH_Drawing_TypographyLayout(typography, maxWidth);
// 设置文本在画布上绘制的起始位置
double position[2] = {10.0, 15.0};
// 将文本绘制到画布上
OH_Drawing_TypographyPaint(typography, cCanvas, position[0], position[1]);
Rawfile开发指导
场景介绍
开发者可以通过本指导了解在HarmonyOS应用中,如何使用Native Rawfile接口操作Rawfile目录和文件。功能包括遍历、打开、搜索、读取和关闭Rawfile。
接口说明
接口名 | 描述 |
NativeResourceManager *OH_ResourceManager_InitNativeResourceManager(napi_env env, napi_value jsResMgr) | 初始化native resource manager。 |
RawDir *OH_ResourceManager_OpenRawDir(const NativeResourceManager *mgr, const char *dirName) | 打开指定rawfile目录。 |
int OH_ResourceManager_GetRawFileCount(RawDir *rawDir) | 获取指定rawfile目录下的rawfile文件数量。 |
const char *OH_ResourceManager_GetRawFileName(RawDir *rawDir, int index) | 获取rawfile名字。 |
RawFile *OH_ResourceManager_OpenRawFile(const NativeResourceManager *mgr, const char *fileName) | 打开指定rawfile文件。 |
long OH_ResourceManager_GetRawFileSize(RawFile *rawFile) | 获取rawfile文件大小。 |
int OH_ResourceManager_SeekRawFile(const RawFile *rawFile, long offset, int whence) | 指定rawfile内偏移量。 |
long OH_ResourceManager_GetRawFileOffset(const RawFile *rawFile) | 获取rawfile偏移量。 |
int OH_ResourceManager_ReadRawFile(const RawFile *rawFile, void *buf, size_t length) | 读取rawfile文件内容。 |
void OH_ResourceManager_CloseRawFile(RawFile *rawFile) | 释放rawfile文件相关资源。 |
void OH_ResourceManager_CloseRawDir(RawDir *rawDir) | 释放rawfile目录相关资源。 |
bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor) | 获取rawfile的fd。 |
bool OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor &descriptor) | 释放rawfile的fd。 |
void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr) | 释放native resource manager相关资源。 |
开发步骤
- 添加头文件。
#include "raw_file_manager.h"
- 使用OH_ResourceManager_InitNativeResourceManager(napi_env env, napi_value jsResMgr)接口获取NativeResourceManager实例。
// js侧传递js resource manager。
import resManager from '@ohos.resourceManager'
import rawfileTest from 'librawFileTest.so'
resManager.getResourceManager().then(resmgr => {
rawfileTest.testRawFile("test", resmgr, (error, value) => {
console.log("test rawFile");
})
});
// C++侧获取解析js侧传递的参数。
NativeResourceManager* nativeResourceManager = nullptr;
std::string path;
if (i == 0 && valueType == napi_string) {
// 解析第一个参数,参数为相对rawfile目录的文件/目录路径。
......
path = buf.data();
} else if (i == 1 && valueType == napi_object) {
// 解析第二个参数,参数为js resource manager。
nativeResourceManager = OH_ResourceManager_InitNativeResourceManager(env, argv[i]);
}
- 根据NativeResourceManager实例,使用OH_ResourceManager_OpenRawDir接口获取RawDir实例。
RawDir* rawDir = OH_ResourceManager_OpenRawDir(nativeResourceManager, path.c_str());
- 根据RawDir实例,使用OH_ResourceManager_GetRawFileCount接口获取对应目录下的rawfile文件总数 。
int count = OH_ResourceManager_GetRawFileCount(rawDir);
- 根据RawDir实例,使用OH_ResourceManager_GetRawFileName接口获取目录下对应index的rawfile文件名。
for (int index = 0; index < count; index++) {
std::string fileName = OH_ResourceManager_GetRawFileName(rawDir, index);
}
- 根据NativeResourceManager实例,使用OH_ResourceManager_OpenRawFile接口获取指定文件名的RawFile实例
RawFile* rawFile = OH_ResourceManager_OpenRawFile(nativeResourceManager, fileName.c_str());
- 根据RawFile实例,使用OH_ResourceManager_GetRawFileSize接口获取对应rawfile文件大小。
long rawFileSize = OH_ResourceManager_GetRawFileSize(rawFile);
- 根据RawFile实例,使用OH_ResourceManager_SeekRawFile接口指定rawfile偏移量。
int position = OH_ResourceManager_SeekRawFile(rawFile, 10, 0);
int position = OH_ResourceManager_SeekRawFile(rawFile, 0 , 1);
int position = OH_ResourceManager_SeekRawFile(rawFile, -10, 2);
- 根据RawFile实例,使用OH_ResourceManager_GetRawFileOffset接口获取rawfile偏移量。
long rawFileOffset = OH_ResourceManager_GetRawFileOffset(rawFile)
- 根据RawFile实例,使用OH_ResourceManager_ReadRawFile接口读取rawfile文件内容。
std::unique_ptr<char[]> mediaData = std::make_unique<char[]>(rawFileSize);
long rawFileOffset = OH_ResourceManager_ReadRawFile(rawFile, mediaData.get(), rawFileSize);
- 根据RawFile实例,使用OH_ResourceManager_CloseRawFile接口释放rawfile文件相关资源。
OH_ResourceManager_CloseRawFile(rawFile);
- 根据RawDir实例,使用OH_ResourceManager_CloseRawDir接口释放rawfile目录相关资源。
OH_ResourceManager_CloseRawDir(rawDir);
- 根据RawFile实例,使用OH_ResourceManager_GetRawFileDescriptor接口获取rawfile的RawFileDescriptor。
RawFileDescriptor descriptor;
bool result = OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor);
- 根据RawFileDescriptor实例,使用OH_ResourceManager_ReleaseRawFileDescriptor接口关闭rawfile的fd。
OH_ResourceManager_ReleaseRawFileDescriptor(descriptor);
- 根据NativeResourceManager实例,使用OH_ResourceManager_ReleaseNativeResourceManager接口释放native resource manager。
OH_ResourceManager_ReleaseNativeResourceManager(nativeResourceManager);
NativeWindow 开发指导
场景介绍
NativeWindow是HarmonyOS本地平台化窗口,表示图形队列的生产者端。接口能力包括从Surface构建NativeWindow的能力,设置NativeWindow属性的能力等。
针对NativeWindow,常见的开发场景如下:
- 结合XComponent组件获取到NativeWindow实例,设置NativeWindow的属性,基于此Native Window进行opengl绘制。
接口说明
接口名 | 描述 |
OH_NativeWindow_CreateNativeWindowFromSurface (void *pSurface) | 创建NativeWindow实例,每次调用都会产生一个新的NativeWindow实例。 |
OH_NativeWindow_DestroyNativeWindow (OHNativeWindow *window) | 将NativeWindow对象的引用计数减1,当引用计数为0的时候,该NativeWindow对象会被析构掉。 |
OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer (void *pSurfaceBuffer) | 创建NativeWindowBuffer实例,每次调用都会产生一个新的NativeWindowBuffer实例。 |
OH_NativeWindow_DestroyNativeWindowBuffer (OHNativeWindowBuffer *buffer) | 将NativeWindowBuffer对象的引用计数减1,当引用计数为0的时候,该NativeWindowBuffer对象会被析构掉。 |
OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow *window, OHNativeWindowBuffer **buffer, int *fenceFd) | 通过NativeWindow对象申请一块NativeWindowBuffer,用以内容生产。 |
OH_NativeWindow_NativeWindowFlushBuffer (OHNativeWindow *window, OHNativeWindowBuffer *buffer, int fenceFd, Region region) | 通过NativeWindow将生产好内容的NativeWindowBuffer放回到Buffer队列中,用以内容消费。 |
OH_NativeWindow_NativeWindowAbortBuffer (OHNativeWindow *window, OHNativeWindowBuffer *buffer) | 通过NativeWindow将之前申请出来的NativeWindowBuffer返还到Buffer队列中,供下次再申请。 |
OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow *window, int code,...) | 设置/获取NativeWindow的属性,包括设置/获取宽高、内容格式等。 |
OH_NativeWindow_GetBufferHandleFromNative (OHNativeWindowBuffer *buffer) | 通过NativeWindowBuffer获取该buffer的BufferHandle指针。 |
OH_NativeWindow_NativeObjectReference (void *obj) | 增加一个NativeObject的引用计数。 |
OH_NativeWindow_NativeObjectUnreference (void *obj) | 减少一个NativeObject的引用计数,当引用计数减少为0时,该NativeObject将被析构掉。 |
OH_NativeWindow_GetNativeObjectMagic (void *obj) | 获取NativeObject的MagicId。 |
OH_NativeWindow_NativeWindowSetScalingMode (OHNativeWindow *window, uint32_t sequence, OHScalingMode scalingMode) | 设置NativeWindow的缩放模式。 |
OH_NativeWindow_NativeWindowSetMetaData(OHNativeWindow *window, uint32_t sequence, int32_t size, const OHHDRMetaData *metaData) | 设置NativeWindow的HDR静态元数据。 |
OH_NativeWindow_NativeWindowSetMetaDataSet(OHNativeWindow *window, uint32_t sequence, OHHDRMetadataKey key, int32_t size, const uint8_t *metaData) | 设置NativeWindow的HDR静态元数据集。 |
OH_NativeWindow_NativeWindowSetTunnelHandle(OHNativeWindow *window, const OHExtDataHandle *handle) | 设置NativeWindow的TunnelHandle。 |
详细的接口说明请参考NativeWindow。
开发步骤
以下步骤描述了在HarmonyOS中如何使用NativeWindow提供的NAPI接口,设置NativeWindow的相关属性。
- 获取NativeWindow实例。使用XComponent组件,可以获取到NativeWindow实例。XComponent的OnSurfaceCreated回调中携带了void*类型的window,可以通过如下方式转换为NativeWindow实例:
OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
- 设置NativeWindowBuffer的属性。使用OH_NativeWindow_NativeWindowHandleOpt设置NativeWindowBuffer的属性。
// 设置 NativeWindowBuffer 的读写场景
int code = SET_USAGE;
int32_t usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA;
int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, usage);
// 设置 NativeWindowBuffer 的宽高
code = SET_BUFFER_GEOMETRY;
int32_t width = 0x100;
int32_t height = 0x100;
ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height);
// 设置 NativeWindowBuffer 的步长
code = SET_STRIDE;
int32_t stride = 0x8;
ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, stride);
// 设置 NativeWindowBuffer 的格式
code = SET_FORMAT;
int32_t format = PIXEL_FMT_RGBA_8888;
ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, format);
OpenSL ES音频播放开发指导
简介
开发者可以通过本文档了解在HarmonyOS中如何使用OpenSL ES进行音频播放相关操作;当前仅实现了部分OpenSL ES接口,因此调用未实现接口后会返回SL_RESULT_FEATURE_UNSUPPORTED
开发指导
以下步骤描述了在HarmonyOS如何使用OpenSL ES开发音频播放功能:
- 添加头文件
#include <OpenSLES.h>
#include <OpenSLES_OpenHarmony.h>
#include <OpenSLES_Platform.h>
- 使用slCreateEngine接口和获取engine实例
SLObjectItf engineObject = nullptr;
slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
(*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
- 获取接口SL_IID_ENGINE的engineEngine实例
SLEngineItf engineEngine = nullptr;
(*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
- 配置播放器信息,创建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);
- 获取接口SL_IID_OH_BUFFERQUEUE的bufferQueueItf实例
SLOHBufferQueueItf bufferQueueItf;
(*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf);
- 打开音频文件,注册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_);
- 获取接口SL_PLAYSTATE_PLAYING的playItf实例,开始播放
SLPlayItf playItf = nullptr;
(*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_PLAY, &playItf);
(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
- 结束音频播放
(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
(*pcmPlayerObject)->Destroy(pcmPlayerObject);
(*engineObject)->Destroy(engineObject);
OpenSL ES音频录制开发指导
简介
开发者可以通过本文档了解在HarmonyOS中如何使用OpenSL ES进行录音相关操作;当前仅实现了部分OpenSL ES接口,因此调用未实现接口后会返回SL_RESULT_FEATURE_UNSUPPORTED。
开发指导
以下步骤描述了在HarmonyOS如何使用 OpenSL ES 开发音频录音功能:
- 添加头文件
#include <OpenSLES.h>
#include <OpenSLES_OpenHarmony.h>
#include <OpenSLES_Platform.h>
- 使用slCreateEngine接口创建引擎对象和实例化引擎对象engine
SLObjectItf engineObject = nullptr;
slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
(*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
- 获取接口SL_IID_ENGINE的引擎接口engineEngine实例
SLEngineItf engineItf = nullptr;
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineItf);
- 配置录音器信息(配置输入源audiosource、输出源audiosink),创建录音对象
pcmCapturerObject
SLDataLocator_IODevice io_device = {
SL_DATALOCATOR_IODEVICE,
SL_IODEVICE_AUDIOINPUT,
SL_DEFAULTDEVICEID_AUDIOINPUT,
NULL
};
SLDataSource audioSource = {
&io_device,
NULL
};
SLDataLocator_BufferQueue buffer_queue = {
SL_DATALOCATOR_BUFFERQUEUE,
3
};
//具体参数需要根据音频文件格式进行适配
SLDataFormat_PCM format_pcm = {
SL_DATAFORMAT_PCM,
OHOS::AudioStandard::AudioChannel::MONO,
OHOS::AudioStandard::AudioSamplingRate::SAMPLE_RATE_44100,
OHOS::AudioStandard::AudioSampleFormat::SAMPLE_S16LE,
0,
0,
0
};
SLDataSink audioSink = {
&buffer_queue,
&format_pcm
};
SLObjectItf pcmCapturerObject = nullptr;
result = (*engineItf)->CreateAudioRecorder(engineItf, &pcmCapturerObject,
&audioSource, &audioSink, 0, nullptr, nullptr);
(*pcmCapturerObject)->Realize(pcmCapturerObject, SL_BOOLEAN_FALSE);
- 获取录音接口SL_IID_RECORD的recordItf接口实例
SLRecordItf recordItf;
(*pcmCapturerObject)->GetInterface(pcmCapturerObject, SL_IID_RECORD, &recordItf);
- 获取接口SL_IID_OH_BUFFERQUEUE的bufferQueueItf实例
SLOHBufferQueueItf bufferQueueItf;
(*pcmCapturerObject)->GetInterface(pcmCapturerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf);
- 注册BufferQueueCallback回调
static void BufferQueueCallback(SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size)
{
AUDIO_INFO_LOG("BufferQueueCallback");
FILE *wavFile = (FILE *)pContext;
if (wavFile != nullptr) {
SLuint8 *buffer = nullptr;
SLuint32 pSize = 0;
(*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, pSize);
if (buffer != nullptr) {
fwrite(buffer, 1, pSize, wavFile);
(*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, size);
}
}
return;
}
//wavFile_ 需要设置为用户想要录音的文件描述符
(*bufferQueueItf)->RegisterCallback(bufferQueueItf, BufferQueueCallback, wavFile_);
- 开始录音
static void CaptureStart(SLRecordItf recordItf, SLOHBufferQueueItf bufferQueueItf, FILE *wavFile)
{
AUDIO_INFO_LOG("CaptureStart");
(*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_RECORDING);
if (wavFile != nullptr) {
SLuint8* buffer = nullptr;
SLuint32 pSize = 0;
(*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, pSize);
if (buffer != nullptr) {
AUDIO_INFO_LOG("CaptureStart, enqueue buffer length: %{public}lu.", pSize);
fwrite(buffer, 1, pSize, wavFile);
(*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, pSize);
} else {
AUDIO_INFO_LOG("CaptureStart, buffer is null or pSize: %{public}lu.", pSize);
}
}
return;
}
- 结束录音
static void CaptureStop(SLRecordItf recordItf)
{
AUDIO_INFO_LOG("Enter CaptureStop");
fflush(wavFile_);
(*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_STOPPED);
(*pcmCapturerObject)->Destroy(pcmCapturerObject);
fclose(wavFile_);
wavFile_ = nullptr;
return;
}