## 1. 原生层 PCM 环形缓冲区 - [x] 1.1 在 `ijksdl_equalizer.h` 或新建头文件中定义 `SpectrumBuffer` 结构体(data、write_pos、has_data、sample_rate、channels 字段) - [x] 1.2 在 `SDL_Aout_Opaque` 结构体中新增 `SpectrumBuffer spectrum_buffer` 成员 - [x] 1.3 在 `AoutOpenAudio` 函数中,初始化 `spectrum_buffer` 并写入 `sample_rate` 和 `channels` - [x] 1.4 在 `AudioRendererOnWriteData` 函数末尾(均衡器处理之后),添加 `memcpy` 将 PCM 数据写入环形缓冲区,更新 `write_pos` 和 `has_data` ## 2. NAPI 接口层 - [x] 2.1 在 `ijkplayer_napi.h` 中声明 `getSpectrumData` 静态方法 - [x] 2.2 在 `ijkplayer_napi.cpp` 中实现 `getSpectrumData`:从 `spectrum_buffer` 读取 1024 个样本,立体声转单声道,构建 `napi_value` 数组返回 - [x] 2.3 在 `ijkplayer_napi_audio_init.cpp` 中注册 `_getSpectrumData` NAPI 函数(DECLARE_NAPI_FUNCTION) - [x] 2.4 在 `ijkplayer_napi_init.cpp` 的视频播放器模块中也注册 `_getSpectrumData`(如需要) - [x] 2.5 在 NAPI 代理层 `ijkplayer_napi_proxy.cpp` 中添加获取 `spectrum_buffer` 指针的辅助函数 ## 3. ArkTS 接口声明 - [x] 3.1 在 `IjkPlayerNapi.d.ets` 类型声明中新增 `_getSpectrumData(xcomponentId: string): number[]` - [x] 3.2 在 `IjkMediaPlayer.ets` 中新增公开方法 `getSpectrumData(): number[]`,封装对原生 `_getSpectrumData` 的调用 ## 4. FFT 分析器模块 - [x] 4.1 新建 `entry/src/main/ets/common/util/FFTAnalyzer.ets`,实现 Cooley-Tukey 基 2 FFT 算法(1024 点) - [x] 4.2 实现 Hann 窗函数,预计算窗系数数组并缓存 - [x] 4.3 实现 `SpectrumData` 类:存储 512 个频率 bin 的幅值,提供 `getBands(bandCount)` 对数频率映射方法和 `getEnergy()` 能量计算方法 - [x] 4.4 实现指数平滑处理逻辑:上升系数 0.7、下降系数 0.3,首帧直通 ## 5. 频谱渲染器接口与特效实现 - [x] 5.1 新建 `entry/src/main/ets/view/spectrum/SpectrumRenderer.ets`,定义渲染器接口(render 方法签名、reset 方法) - [x] 5.2 实现 `BarSpectrumRenderer.ets`:柱状频谱特效(fillRect、频段渐变色、峰值下落指示器) - [x] 5.3 实现 `WaveSpectrumRenderer.ets`:波形频谱特效(贝塞尔曲线、半透明渐变填充、线宽随能量变化) - [x] 5.4 实现 `CircleSpectrumRenderer.ets`:圆形频谱特效(极坐标放射线、缓慢旋转、色相环颜色映射) - [x] 5.5 实现 `ParticleSpectrumRenderer.ets`:粒子频谱特效(200 粒子池、频段驱动属性、透明度衰减回收) ## 6. SpectrumView 组件 - [x] 6.1 新建 `entry/src/main/ets/view/spectrum/SpectrumView.ets`,创建 Canvas 容器组件 - [x] 6.2 实现 30fps 定时器逻辑:获取 PCM → FFT 分析 → 调用当前渲染器 render - [x] 6.3 实现生命周期控制:可见性监听(aboutToAppear/aboutToDisappear)、播放状态监听,不可见或暂停时停止定时器 - [x] 6.4 实现特效切换逻辑:切换时清空 Canvas、重置渲染器、启动新渲染 - [x] 6.5 实现特效选择偏好持久化(AppStorage 存储用户上次选择的特效模式) ## 7. 特效切换 UI - [x] 7.1 在 SpectrumView 中添加特效切换按钮(频谱页面右上角或底部) - [x] 7.2 实现特效选择面板:显示 4 种特效名称(柱状、波形、圆形、粒子),用户点击选择 ## 8. 播放界面 Swiper 集成 - [x] 8.1 在 `LocalMusic.ets` 的 Swiper 中,在 `CoverInfo()` 和 `PlayerLyrics()` 之间插入 `SpectrumView` 组件 - [x] 8.2 更新 Swiper 的 `onChange` 回调,index=1 时通知 SpectrumView 可见,其他 index 时通知不可见 - [x] 8.3 调整 `currentSwiperIndex` 相关逻辑,适配三页 Swiper(原有的模糊效果、背景样式等条件判断) ## 9. 主题色适配 - [x] 9.1 在各渲染器中读取当前主题的品牌色 `$r('app.color.brand')`,作为频谱特效的基础色调 - [x] 9.2 实现基于主色的配色生成逻辑(HSL 色相偏移生成互补色和渐变色)