HarmonyOS Developer Native API的相关指导

丶龙八夷
发布于 2023-3-31 16:38
浏览
0收藏

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图形:

  1. 创建Bitmap实例。使用drawing_bitmap.hOH_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);
  1. 创建画布实例。使用drawing_canvas.hOH_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));
  1. 构造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);
  1. 设置画笔和画刷样式。使用drawing_pen.hOH_Drawing_PenCreate接口创建一个画笔实例cPen, 并设置抗锯齿、颜色、线宽等属性,画笔用于形状边框线的绘制。使用drawing_brush.hOH_Drawing_BrushCreate接口创建一个画刷实例cBrush, 并设置填充颜色, 画刷用于形状内部的填充。使用drawing_canvas.hOH_Drawing_CanvasAttachPenOH_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);
  1. 绘制Path形状。使用drawing_canvas.hOH_Drawing_CanvasDrawPath接口将五角星绘制到画布上,绘制完毕后不再使用的实例需要调用对应的接口进行销毁。

// 在画布上画path的形状,五角星的边框样式为pen设置,颜色填充为Brush设置
OH_Drawing_CanvasDrawPath(cCanvas, cPath);
// 销毁创建的对象
OH_Drawing_BrushDestroy(cBrush);
OH_Drawing_PenDestroy(cPen);
OH_Drawing_PathDestroy(cPath);
  1. 获取像素数据。使用drawing_bitmap.hOH_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模块的文字显示功能:

  1. 创建画布和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));
  1. 设置排版风格

// 选择从左到右/左对齐等排版属性
OH_Drawing_TypographyStyle* typoStyle = OH_Drawing_CreateTypographyStyle();
OH_Drawing_SetTypographyTextDirection(typoStyle, TEXT_DIRECTION_LTR);
OH_Drawing_SetTypographyTextAlign(typoStyle, TEXT_ALIGN_LEFT);
  1. 设置文本风格

// 设置文字颜色,例如黑色
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");
  1. 生成最终文本显示效果​

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相关资源。

开发步骤

  1. 添加头文件。

#include "raw_file_manager.h"
  1. 使用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]);
}
  1. 根据NativeResourceManager实例,使用OH_ResourceManager_OpenRawDir接口获取RawDir实例。

RawDir* rawDir = OH_ResourceManager_OpenRawDir(nativeResourceManager, path.c_str());
  1. 根据RawDir实例,使用OH_ResourceManager_GetRawFileCount接口获取对应目录下的rawfile文件总数 。

int count = OH_ResourceManager_GetRawFileCount(rawDir);
  1. 根据RawDir实例,使用OH_ResourceManager_GetRawFileName接口获取目录下对应index的rawfile文件名。

for (int index = 0; index < count; index++) {
    std::string fileName = OH_ResourceManager_GetRawFileName(rawDir, index);
}
  1. 根据NativeResourceManager实例,使用OH_ResourceManager_OpenRawFile接口获取指定文件名的RawFile实例

RawFile* rawFile = OH_ResourceManager_OpenRawFile(nativeResourceManager, fileName.c_str());
  1. 根据RawFile实例,使用OH_ResourceManager_GetRawFileSize接口获取对应rawfile文件大小。

long rawFileSize = OH_ResourceManager_GetRawFileSize(rawFile);
  1. 根据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);
  1. 根据RawFile实例,使用OH_ResourceManager_GetRawFileOffset接口获取rawfile偏移量。

long rawFileOffset = OH_ResourceManager_GetRawFileOffset(rawFile)
  1. 根据RawFile实例,使用OH_ResourceManager_ReadRawFile接口读取rawfile文件内容。

std::unique_ptr<char[]> mediaData = std::make_unique<char[]>(rawFileSize);
long rawFileOffset = OH_ResourceManager_ReadRawFile(rawFile, mediaData.get(), rawFileSize);
  1. 根据RawFile实例,使用OH_ResourceManager_CloseRawFile接口释放rawfile文件相关资源。

OH_ResourceManager_CloseRawFile(rawFile);
  1. 根据RawDir实例,使用OH_ResourceManager_CloseRawDir接口释放rawfile目录相关资源。

OH_ResourceManager_CloseRawDir(rawDir);
  1. 根据RawFile实例,使用OH_ResourceManager_GetRawFileDescriptor接口获取rawfile的RawFileDescriptor。

RawFileDescriptor descriptor;
bool result = OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor);
  1. 根据RawFileDescriptor实例,使用OH_ResourceManager_ReleaseRawFileDescriptor接口关闭rawfile的fd。

OH_ResourceManager_ReleaseRawFileDescriptor(descriptor);
  1. 根据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的相关属性。

  1. 获取NativeWindow实例。使用XComponent组件,可以获取到NativeWindow实例。XComponent的OnSurfaceCreated回调中携带了void*类型的window,可以通过如下方式转换为NativeWindow实例:

OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
  1. 设置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开发音频播放功能:

  1. 添加头文件

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

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

SLEngineItf engineEngine = nullptr;
(*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
  1. 配置播放器信息,创建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. 获取接口SL_IID_OH_BUFFERQUEUEbufferQueueItf实例

SLOHBufferQueueItf bufferQueueItf;
(*pcmPlayerObject)->GetInterface(pcmPlayerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf);
  1. 打开音频文件,注册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. 获取接口SL_PLAYSTATE_PLAYINGplayItf实例,开始播放

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

(*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 开发音频录音功能:

  1. 添加头文件

#include <OpenSLES.h>
#include <OpenSLES_OpenHarmony.h>
#include <OpenSLES_Platform.h>
  1. 使用slCreateEngine接口创建引擎对象和实例化引擎对象engine

SLObjectItf engineObject = nullptr;
slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
(*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
  1. 获取接口SL_IID_ENGINE的引擎接口engineEngine实例

SLEngineItf engineItf = nullptr;
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineItf);
  1. 配置录音器信息(配置输入源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);
  1. 获取录音接口SL_IID_RECORDrecordItf接口实例

SLRecordItf  recordItf;
(*pcmCapturerObject)->GetInterface(pcmCapturerObject, SL_IID_RECORD, &recordItf);
  1. 获取接口SL_IID_OH_BUFFERQUEUEbufferQueueItf实例

SLOHBufferQueueItf bufferQueueItf;
(*pcmCapturerObject)->GetInterface(pcmCapturerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf);
  1. 注册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_);
  1. 开始录音

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;
}
  1. 结束录音

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;
}  



文章转载自:​​https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/opensles-capture-0000001428061596-V3​

分类
标签
已于2023-3-31 16:38:51修改
收藏
回复
举报
回复
    相关推荐