--- description: 原生模块集成指南 globs: ["**/cpp/**/*", "**/napi/**/*", "**/ijkplayer/**/*", "**/lib/**/*"] alwaysApply: false --- # 原生模块集成指南 ## ijkplayer播放器集成 ### 基本使用 ```typescript import { IjkMediaPlayer } from '@ohos/ijkplayer'; // 创建播放器实例 private player: IjkMediaPlayer = new IjkMediaPlayer(); // 设置数据源 async setDataSource(path: string) { try { await this.player.setDataSource(path); await this.player.prepare(); } catch (err: Error) { Logger.error(`设置数据源失败: ${err.message}`); } } ``` ### 播放控制 ```typescript // 播放 async play() { try { await this.player.start(); this.playStatus = PlayStatus.PLAY; } catch (err: Error) { Logger.error(`播放失败: ${err.message}`); } } // 暂停 async pause() { try { await this.player.pause(); this.playStatus = PlayStatus.PAUSE; } catch (err: Error) { Logger.error(`暂停失败: ${err.message}`); } } // 停止 async stop() { try { await this.player.stop(); this.playStatus = PlayStatus.STOP; } catch (err: Error) { Logger.error(`停止失败: ${err.message}`); } } ``` ### 播放状态监听 ```typescript // 设置播放状态监听器 setupPlayerListener() { this.player.on('stateChange', (state: string) => { switch (state) { case 'prepared': // 准备完成 break; case 'playing': this.playStatus = PlayStatus.PLAY; break; case 'paused': this.playStatus = PlayStatus.PAUSE; break; case 'completed': this.playStatus = PlayStatus.DONE; this.playNext(); // 播放下一首 break; case 'error': this.handlePlaybackError(new Error('播放器错误')); break; } }); this.player.on('timeUpdate', (currentTime: number, duration: number) => { this.currentTime = currentTime; this.duration = duration; this.updateProgress(); }); } ``` ### 音频焦点处理 ```typescript import { avSession } from '@kit.ArkAVSessionKit'; // 请求音频焦点 async requestAudioFocus() { try { const audioSession = await avSession.createAVSession(getContext(this), 'audio', 'music'); await audioSession.activate(); this.audioSession = audioSession; } catch (err: Error) { Logger.error(`获取音频焦点失败: ${err.message}`); } } // 释放音频焦点 async releaseAudioFocus() { if (this.audioSession) { try { await this.audioSession.deactivate(); await this.audioSession.destroy(); this.audioSession = null; } catch (err: Error) { Logger.error(`释放音频焦点失败: ${err.message}`); } } } ``` ## 歌词库集成 ### LyricHelper使用 ```typescript import { LyricHelper } from '@lib/LyricHelper'; // 解析歌词文件 async parseLyricFile(filePath: string): Promise { try { const lyrics = await LyricHelper.parseLyricFile(filePath); return lyrics; } catch (err: Error) { Logger.error(`解析歌词文件失败: ${err.message}`); return []; } } // 解析歌词文本 parseLyricText(lyricText: string): LyricLine[] { try { return LyricHelper.parseLyricText(lyricText); } catch (err: Error) { Logger.error(`解析歌词文本失败: ${err.message}`); return []; } } ``` ### 歌词同步 ```typescript // 获取当前时间对应的歌词行 getCurrentLyric(currentTime: number): LyricLine | null { if (!this.lyrics || this.lyrics.length === 0) { return null; } for (let i = 0; i < this.lyrics.length; i++) { if (this.lyrics[i].time > currentTime) { return i > 0 ? this.lyrics[i - 1] : null; } } return this.lyrics[this.lyrics.length - 1]; } // 获取下一句歌词 getNextLyric(currentTime: number): LyricLine | null { if (!this.lyrics || this.lyrics.length === 0) { return null; } for (let i = 0; i < this.lyrics.length; i++) { if (this.lyrics[i].time > currentTime) { return this.lyrics[i]; } } return null; } ``` ## NAPI开发指南 ### 基本NAPI模块结构 ```cpp // napi_init.cpp #include "napi/native_api.h" static napi_value Init(napi_env env, napi_value exports) { // 导出函数 napi_property_descriptor desc[] = { {"createPlayer", nullptr, CreatePlayer, nullptr, nullptr, nullptr, napi_default, nullptr}, {"destroyPlayer", nullptr, DestroyPlayer, nullptr, nullptr, nullptr, napi_default, nullptr}, }; napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); return exports; } static napi_module demoModule = { .nm_version = 1, .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = Init, .nm_modname = "entry", .nm_priv = ((void*)0), .reserved = {0}, }; extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); } ``` ### 异步操作处理 ```cpp // 异步操作结构体 struct AsyncData { napi_async_work work; napi_deferred deferred; napi_ref callback; std::string result; std::string error; }; // 异步执行函数 static void ExecuteCallback(napi_env env, void* data) { AsyncData* asyncData = (AsyncData*)data; try { // 执行耗时操作 asyncData->result = performOperation(); } catch (const std::exception& e) { asyncData->error = e.what(); } } // 完成回调函数 static void CompleteCallback(napi_env env, napi_status status, void* data) { AsyncData* asyncData = (AsyncData*)data; napi_value callback; napi_get_reference_value(env, asyncData->callback, &callback); napi_value result; if (asyncData->error.empty()) { napi_create_string_utf8(env, asyncData->result.c_str(), NAPI_AUTO_LENGTH, &result); napi_call_function(env, nullptr, callback, 1, &result, nullptr); } else { napi_value error; napi_create_string_utf8(env, asyncData->error.c_str(), NAPI_AUTO_LENGTH, &error); napi_call_function(env, nullptr, callback, 1, &error, nullptr); } // 清理资源 napi_delete_async_work(env, asyncData->work); napi_delete_reference(env, asyncData->callback); delete asyncData; } ``` ## 性能优化建议 ### 播放器优化 1. 使用对象池管理播放器实例,避免频繁创建和销毁 2. 预加载下一首歌曲,减少切换歌曲时的延迟 3. 使用硬件解码加速,降低CPU占用 4. 合理设置缓冲区大小,平衡播放流畅度和内存占用 ### 内存管理 1. 及时释放不再使用的资源,如播放器实例、音频会话等 2. 使用弱引用避免循环引用导致的内存泄漏 3. 监控内存使用情况,及时处理内存警告 ### 线程管理 1. 将耗时操作放在工作线程中执行,避免阻塞UI线程 2. 使用线程池管理并发任务,避免创建过多线程 3. 合理使用同步机制,避免死锁和竞态条件 ## 错误处理 ### 播放器错误处理 ```typescript // 播放器错误处理 handlePlayerError(error: Error) { Logger.error(`播放器错误: ${error.message}`); // 根据错误类型采取不同处理策略 if (error.message.includes('网络')) { // 网络错误,尝试重试或使用本地缓存 this.retryWithCache(); } else if (error.message.includes('解码')) { // 解码错误,尝试使用备用解码器 this.switchToBackupDecoder(); } else { // 其他错误,显示错误提示并停止播放 this.showErrorMessage(error.message); this.stop(); } } ``` ### NAPI错误处理 ```cpp // NAPI错误处理 static napi_value SomeFunction(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value args[1]; napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); if (status != napi_ok || argc < 1) { napi_throw_error(env, nullptr, "Invalid arguments"); return nullptr; } // 参数验证 bool isString; napi_is_string(env, args[0], &isString); if (!isString) { napi_throw_type_error(env, nullptr, "Expected string"); return nullptr; } // 执行操作... return result; } ```