Skip to content

Repository files navigation

AudioWaveView

一个功能强大的Android音频波形视图组件,仿喜马拉雅录音剪切界面,支持音频波形显示、编辑、剪切、缩放等功能。

📋 目录

✨ 功能特性

  • 音频波形显示 - 支持实时显示音频波形数据
  • 编辑模式 - 支持选择音频片段进行编辑操作
  • 音频剪切 - 支持剪切选中的音频片段
  • 整段替换 - 支持替换选中音频片段
  • 波形缩放 - 支持手势缩放波形显示
  • 覆盖录制 - 支持覆盖录制功能
  • 滚动支持 - 支持手势滚动浏览长音频
  • 播放动画 - 支持播放进度动画显示
  • 文字背景 - 支持为时间文字添加背景样式
  • 高度自定义 - 丰富的属性配置,满足各种UI需求

基本使用

1. XML布局中使用

<com.shetj.waveview.AudioWaveView
android:id="@+id/audioWaveView"android:layout_width="match_parent"android:layout_height="300dp"app:wv_rect_level="10"app:wv_one_second_rect_size="25"app:wv_bottom_line_margin="20dp"app:wv_can_scroll="true"app:wv_center_line_width="2dp"app:wv_cut_icon="@mipmap/icon_test_touch"app:wv_cut_icon_size="25dp"app:wv_cut_line_width="1dp"app:wv_cut_time_text_size="12sp"app:wv_time_progress_text_color="@color/black"app:wv_time_progress_text_size="12sp"app:wv_show_text_background="true"app:wv_text_background_color="#80000000"app:wv_text_background_horizontal_padding="8dp"app:wv_text_background_vertical_padding="4dp"app:wv_text_background_corner_radius="4dp" />

2. 代码中使用

val audioWaveView = findViewById<AudioWaveView>(R.id.audioWaveView)
// 设置监听器
audioWaveView.setListener(object:AudioWaveView.OnChangeListener {
overridefunonUpdateCurrentPosition(position:Long, duration:Long) {
// 当前播放位置更新
}
overridefunonUpdateCutPosition(startPosition:Long, endPosition:Long) {
// 剪切位置更新
}
overridesuspendfunonCutAudio(startTime:Long, endTime:Long): Boolean {
// 执行音频剪切操作returntrue
}
})
// 添加音频数据
audioWaveView.addFrame(0.5f, 1000L) // 添加单个帧数据

⚙️ 详细配置

XML属性配置

AudioWaveView 提供了丰富的XML属性配置,按功能分为以下几个部分:

第一部分:顶部和底部线条设置

属性名类型默认值说明
wv_top_line_margindimension30dp顶部线距离顶部的高度
wv_bottom_line_margindimension30dp底部线距离底部的高度
wv_top_bottom_line_colorcolor#c8cad0顶部和底部线的颜色
wv_top_bottom_line_widthdimension3dp顶部和底部线的宽度

第二部分:矩形波形设置

属性名类型默认值说明
wv_rect_scalefloat1.0f缩放级别,范围0.1~1.4
wv_rect_levelinteger10矩形分级数量,决定波形高度层次
wv_one_second_rect_sizefloat25一秒钟包含的矩形数量
wv_rect_widthdimension2dp矩形的宽度
wv_rect_corner_radiusdimension2dp矩形的圆角半径
wv_rect_spacedimension2dp矩形之间的间距
wv_rect_right_colorcolor#c8cad0中线右边矩形的颜色
wv_rect_left_colorcolor#93b3ea中线左边矩形的颜色

第三部分:中线设置

属性名类型默认值说明
wv_center_line_colorcolor#93b3ea中线颜色
wv_center_line_widthdimension2dp中线宽度

第四部分:剪切功能设置

属性名类型默认值说明
wv_cut_iconreference-剪切标记图标资源
wv_cut_icon_sizedimension30dp剪切图标大小
wv_cut_line_colorcolorRED剪切线颜色
wv_cut_line_widthdimension3dp剪切线宽度
wv_cut_time_text_colorcolorRED剪切时间文字颜色
wv_cut_time_text_sizedimension18sp剪切时间文字大小
wv_cut_select_colorcolor#33FFBB22选中区域背景颜色

第五部分:其他设置

属性名类型默认值说明
wv_time_progress_text_colorcolor#c8cad0时间刻度文字颜色
wv_time_progress_text_sizedimension18sp时间刻度文字大小
wv_can_scrollbooleantrue是否可以滚动
wv_show_center_linebooleantrue是否显示中线
wv_show_top_bottom_linebooleantrue是否显示上下线

第六部分:文字背景设置(新功能)

属性名类型默认值说明
wv_show_text_backgroundbooleanfalse是否显示文本背景
wv_text_background_colorcolor#80000000文本背景颜色
wv_text_background_horizontal_paddingdimension8dp文本背景水平内边距
wv_text_background_vertical_paddingdimension4dp文本背景垂直内边距
wv_text_background_corner_radiusdimension4dp文本背景圆角半径

代码动态配置

除了XML属性配置外,AudioWaveView还提供了丰富的代码配置方法:

颜色设置

// 设置中线颜色
audioWaveView.setCenterLineColor(Color.BLUE)
// 设置左侧波形颜色
audioWaveView.setLeftPaintColor(Color.GREEN)
// 设置右侧波形颜色
audioWaveView.setRightPaintColor(Color.GRAY)
// 设置剪切标记颜色
audioWaveView.setCutMarkerPointPaintColor(Color.RED)
// 设置选中区域背景颜色
audioWaveView.setCutSelectPaintColor(Color.parseColor("#33FFBB22"))

波形样式设置

// 设置波形宽度
audioWaveView.setWaveWidth(3f)
// 设置波形间距
audioWaveView.setWaveSpace(1f)
// 设置波形圆角
audioWaveView.setWaveCornerRadius(4f)
// 设置缩放比例
audioWaveView.setWaveScale(1.2f)
// 设置时间文字大小
audioWaveView.setTimeSize(14f)

文字背景设置

// 设置是否显示文字背景
audioWaveView.setShowTextBackground(true)
// 设置文字背景颜色
audioWaveView.setTextBackgroundColor(Color.parseColor("#80000000"))
// 设置文字背景内边距
audioWaveView.setTextBackgroundPadding(10f, 6f) // 水平10dp,垂直6dp// 设置文字背景圆角
audioWaveView.setTextBackgroundCornerRadius(6f)

📚 API文档

核心方法

数据操作

// 添加单个音频帧funaddFrame(frame:Float, duration:Long)
// 批量添加音频帧funaddFrames(index:Int, newFrameArray:FrameArray, frameDuration:Long, editModel:Boolean = true)
// 替换音频片段funreplaceFrames(startTime:Long, endTime:Long, newFrameArray:FrameArray, newFrameDuration:Long, editModel:Boolean = true)
// 清空所有数据funclearFrame()
// 获取所有音频帧数据fungetFrames(): ArrayList<Float>
// 获取音频总时长fungetDuration(): Long

播放控制

// 设置当前播放位置funsetCurrentPosition(currentTime:Long)
// 获取当前播放位置fungetCurrentPosition(): Long// 开始播放动画funstartPlayAnim(speed:Float = 1.0f)
// 暂停播放动画funpausePlayAnim()
// 检查是否正在播放funisPlaying(): Boolean

编辑功能

// 开启编辑模式funstartEditModel()
// 开启编辑模式(指定时间范围)funstartEditModel(startTime:Long? = null, endTime:Long? = null)
// 关闭编辑模式funcloseEditModel()
// 检查是否处于编辑模式funisEditModel(): Boolean// 剪切选中片段suspendfuncutSelect(): Boolean// 开始覆盖录制suspendfunstartOverwrite(): Boolean// 获取剪切开始时间fungetCutStartTime(): Long// 获取剪切结束时间fungetCutEndTime(): Long

滚动控制

// 设置是否可以滚动funsetEnableScroll(enable:Boolean, toEnd:Boolean = false)
// 滚动到末尾funscrollToEnd(needAnim:Boolean = true)
// 滚动到开头funscrollToStart(needAnim:Boolean = true)
// 检查是否已滚动到末尾funisScrollEnd(): Boolean

监听器接口

interfaceOnChangeListener {
/** * 当前播放位置更新 * @param position 当前位置(毫秒) * @param duration 总时长(毫秒)*/funonUpdateCurrentPosition(position:Long, duration:Long)
/** * 剪切位置更新 * @param startPosition 开始位置(毫秒) * @param endPosition 结束位置(毫秒)*/funonUpdateCutPosition(startPosition:Long, endPosition:Long)
/** * 执行音频剪切 * @param startTime 开始时间(毫秒) * @param endTime 结束时间(毫秒) * @return 是否剪切成功*/suspendfunonCutAudio(startTime:Long, endTime:Long): Boolean/** * 剪切完成回调*/funonCutFinish()
/** * 缩放级别更新 * @param scale 当前缩放比例*/funonUpdateScale(scale:Float)
/** * 编辑模式状态变化 * @param isEditModel 是否处于编辑模式*/funonEditModelChange(isEditModel:Boolean)
}

🔥 高级功能

编辑模式

编辑模式允许用户选择音频片段进行剪切、替换等操作:

// 开启编辑模式
audioWaveView.startEditModel()
// 开启编辑模式并指定选择范围
audioWaveView.startEditModel(startTime =1000L, endTime =5000L)
// 监听编辑模式状态变化
audioWaveView.setListener(object:AudioWaveView.OnChangeListener {
overridefunonEditModelChange(isEditModel:Boolean) {
if (isEditModel) {
// 进入编辑模式
showEditControls()
} else {
// 退出编辑模式
hideEditControls()
}
}
overridefunonUpdateCutPosition(startPosition:Long, endPosition:Long) {
// 更新选择范围显示
updateSelectionInfo(startPosition, endPosition)
}
})

覆盖录制

覆盖录制功能允许从当前位置开始覆盖后续的音频内容:

// 开始覆盖录制
lifecycleScope.launch {
val success = audioWaveView.startOverwrite()
if (success) {
// 覆盖录制开始成功
startRecording()
}
}

文字背景

新增的文字背景功能可以为时间显示文字添加背景,提高可读性:

XML配置方式

<com.shetj.waveview.AudioWaveView
...
app:wv_show_text_background="true"app:wv_text_background_color="#80000000"app:wv_text_background_horizontal_padding="8dp"app:wv_text_background_vertical_padding="4dp"app:wv_text_background_corner_radius="4dp" />

代码配置方式

// 启用文字背景
audioWaveView.setShowTextBackground(true)
// 设置背景颜色(半透明黑色)
audioWaveView.setTextBackgroundColor(Color.parseColor("#80000000"))
// 设置内边距
audioWaveView.setTextBackgroundPadding(8f, 4f)
// 设置圆角
audioWaveView.setTextBackgroundCornerRadius(4f)

🔧 实现原理

1. 滚动实现

本质是通过偏移量的变化来实现滚动效果:

  • 使用 Scroller + DecelerateInterpolator 实现手势阻尼效果
  • 通过 mOffsetX 变量控制整体内容的偏移

2. 缩放声波

  • 使用 ScaleGestureDetector 检测缩放手势
  • 通过 mScaleFactor 变量控制缩放比例
  • 重新计算并绘制UI元素

3. 覆盖模式实现

  • 剪切中线以后的数据(触发剪切回调)
  • 在末端开始添加新的音频数据
  • 实现无缝的覆盖录制体验

4. 替换整段实现

  • 剪切选中部分的数据
  • 在指定位置插入新的音频数据
  • 文件操作需要使用者自行实现

5. 颜色分割效果

使用 PorterDuffXfermodeSRC_ATOP 模式:

  • 给左边一半画一个大矩形
  • 只绘制重叠部分,实现精确的颜色分割效果

6. 文字背景绘制

  • 计算文字的实际尺寸
  • 根据内边距计算背景矩形范围
  • 使用 drawRoundRect 绘制圆角背景

📱 示例项目

项目包含完整的示例应用,展示了所有功能的使用方法:

  • demo-record - 完整的录音、剪切、播放示例
    • ✅ 真实录音功能
    • ✅ 音频剪切功能
    • ✅ 音频播放功能
    • ✅ 覆盖录制功能

运行示例

  1. 克隆项目到本地
  2. 使用 Android Studio 打开项目
  3. 运行 demo-record 模块
  4. 体验完整的音频编辑功能

❓ 常见问题

Q: 如何设置音频数据?

A: AudioWaveView 只处理UI交互逻辑,不直接支持PCM数据。你需要:

  1. 将音频文件转换为PCM格式
  2. 从PCM数据中提取分贝值
  3. 根据 wv_rect_levelwv_one_second_rect_size 设置合适的数据
  4. 使用 addFrame()addFrames() 添加数据

Q: 如何配置波形显示参数?

A: 关键参数说明:

  • wv_rect_level="10" - 波形分为10个高度级别
  • wv_one_second_rect_size="25" - 一秒显示25个矩形
  • 示例:一个矩形表示40ms(1000ms ÷ 25 = 40ms)

Q: 为什么手势操作没有响应?

A: 检查以下设置:

  • 确保 wv_can_scroll="true"
  • 确保没有在播放状态(播放时会禁用手势)
  • 检查是否正确设置了监听器

Q: 如何自定义剪切图标?

A: 使用 wv_cut_icon 属性:

app:wv_cut_icon="@mipmap/your_custom_icon"
app:wv_cut_icon_size="30dp"

Q: 文字背景功能不显示?

A: 确保正确配置:

app:wv_show_text_background="true"
app:wv_text_background_color="#80000000"

📝 更新日志

最新版本

  • 新增文字背景功能 - 支持为时间文字添加背景样式
  • 优化渲染性能 - 减少不必要的遍历,直接计算索引范围
  • 完善API文档 - 提供更详细的使用说明和示例

已完成功能

  • ✅ 音频波形显示
  • ✅ 编辑模式支持
  • ✅ 音频剪切功能
  • ✅ 整段替换功能
  • ✅ 波形缩放功能
  • ✅ 覆盖录制功能
  • ✅ 滚动浏览支持
  • ✅ 播放动画效果
  • ✅ 文字背景样式
  • ✅ 性能优化

📄 许可证

本项目采用 MIT 许可证,详情请查看 LICENSE 文件。

🤝 贡献

欢迎提交 Issue 和 Pull Request 来帮助改进这个项目!

📞 联系方式

如果你有任何问题或建议,请通过以下方式联系:


⭐ 如果这个项目对你有帮助,请给个Star支持一下!

About

仿喜马拉雅录音剪切的view

Resources

Stars

15 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages