DSWaveformImage - iOS、macOS 和 visionOS 实时音频波形渲染

Swift Package Manager compatible

DSWaveformImage 提供了原生接口,用于在 iOSiPadOSmacOSvisionOS 或通过 Catalyst 绘制音频数据的包络波形。为此,您可以使用

此外,您还可以通过创建 WaveformAnalyzer 的实例,直接获取波形的(归一化)[Float] 样本。

示例 UI(包含在存储库中)

有关 SwiftUI 实时音频录制波形渲染的实际示例用法,请参见 RecordingIndicatorView

Audio Recorder Example

更多相关的 iOS 控件

您可能还会发现以下用 Swift 编写的 iOS 控件很有趣

如果您真的很喜欢这个库(即赞助)

我做这一切都是为了乐趣和喜悦,并且我坚信开源的力量。但是,万一使用我的库给您带来了快乐,并且您只是想说“谢谢”,如果您通过其中一个赞助按钮支持我,我会像一个 4 岁的孩子得到一个巨大的冰淇淋甜筒一样微笑☺️💕

或者,考虑下载我的一个副项目 iOS 应用程序来支持我。如果您想向其他人发送一份可爱的感谢之情,也许可以查看我的 iOS 应用程序 💌 SoundCard 向他们发送一张带有个人音频信息的真实明信片。或者下载我的支持广告的免费游戏 🕹️ Snekris for iOS

Buy Me A Coffee Play Snekris

安装

import DSWaveformImage // for core classes to generate `UIImage` / `NSImage` directly
import DSWaveformImageViews // if you want to use the native UIKit / SwiftUI views

用法

DSWaveformImage 提供了 3 种工具可供使用

核心渲染器和处理器以及 SwiftUI 视图原生支持 iOS 和 macOS,分别使用 UIImageNSImage

SwiftUI

WaveformView - 从音频文件渲染一次性波形

@State var audioURL = Bundle.main.url(forResource: "example_sound", withExtension: "m4a")!
WaveformView(audioURL: audioURL)

如果您有更复杂的要求,可以覆盖默认样式

@State var audioURL = Bundle.main.url(forResource: "example_sound", withExtension: "m4a")!
WaveformView(audioURL: audioURL) { waveformShape in
    waveformShape
        .stroke(LinearGradient(colors: [.red, [.green, red, orange], startPoint: .zero, endPoint: .topTrailing), lineWidth: 3)
}

AsyncImage 类似,可以设置一个占位符,直到加载和渲染操作成功完成。感谢 @alfogrillo

WaveformView(audioURL: audioURL) { waveformShape in
    waveformShape
        .stroke(LinearGradient(colors: [.red, [.green, red, orange], startPoint: .zero, endPoint: .topTrailing), lineWidth: 3)
} placeholder: {
    ProgressView()
}

WaveformLiveCanvas - 从 (0...1) 归一化样本渲染实时波形

@StateObject private var audioRecorder: AudioRecorder = AudioRecorder() // just an example
WaveformLiveCanvas(samples: audioRecorder.samples)

UIKit

WaveformImageView - 从音频文件渲染一次性波形

let audioURL = Bundle.main.url(forResource: "example_sound", withExtension: "m4a")!
waveformImageView = WaveformImageView(frame: CGRect(x: 0, y: 0, width: 500, height: 300)
waveformImageView.waveformAudioURL = audioURL

WaveformLiveView - 从 (0...1) 归一化样本渲染实时波形

示例项目的 RecordingViewController 中找到一个完整的示例。

let waveformView = WaveformLiveView()

// configure and start AVAudioRecorder
let recorder = AVAudioRecorder()
recorder.isMeteringEnabled = true // required to get current power levels

// after all the other recording (omitted for focus) setup, periodically (every 20ms or so):
recorder.updateMeters() // gets the current value
let currentAmplitude = 1 - pow(10, recorder.averagePower(forChannel: 0) / 20)
waveformView.add(sample: currentAmplitude)

原始 API

配置

注意: 计算始终在后台线程上执行和返回,因此请务必在执行任何 UI 工作之前返回到主线程。

WaveformImageTypes 中查看 Waveform.Configuration,了解各种配置选项。

WaveformImageDrawer - 从音频文件创建 UIImage 波形

let waveformImageDrawer = WaveformImageDrawer()
let audioURL = Bundle.main.url(forResource: "example_sound", withExtension: "m4a")!
let image = try await waveformImageDrawer.waveformImage(
    fromAudioAt: audioURL,
    with: .init(size: topWaveformView.bounds.size, style: .filled(UIColor.black)),
    renderer: LinearWaveformRenderer()
)

// need to jump back to main queue
DispatchQueue.main.async {
    self.topWaveformView.image = image
}

WaveformAnalyzer - 计算音频文件的波形样本

let audioURL = Bundle.main.url(forResource: "example_sound", withExtension: "m4a")!
waveformAnalyzer = WaveformAnalyzer()
let samples = try await waveformAnalyzer.samples(fromAudioAt: audioURL, count: 200)
print("samples: \(samples)")

播放进度指示

如果您正在播放音频文件并希望向用户指示播放进度,您可以在示例应用程序中找到灵感。 提供了 UIKit 和 SwiftUI 示例。

两种方法都会产生如下所示的图像。

playback progress waveform

目前没有计划将其作为一流的公民集成到库本身中,因为每个应用程序都会有不同的设计要求,并且 WaveformImageDrawerWaveformAnalyzer 与视图本身一样易于使用,正如您在示例中看到的那样。

从 URL 加载远程音频文件

有关一种在远程 URL 上显示音频文件波形的示例方法,请参见 #22

它看起来像什么

波形可以以 2 种不同的方式和 5 种不同的样式渲染。

默认情况下,使用 LinearWaveformRenderer,它绘制线性 2D 幅度包络。

CircularWaveformRenderer 可用作替代方案,可以分别传递给 WaveformViewWaveformLiveView。它绘制一个圆形 2D 幅度包络。

您可以通过实现 WaveformRenderer 来实现您自己的渲染器。

以下样式可以应用于任何渲染器

Screenshot

实时波形渲染

live-recording.mov

迁移

在 14.0.0 中

在 13.0.0 中

在 12.0.0 中

在 11.0.0 中

该库已分为两个:DSWaveformImageDSWaveformImageViews。 如果您之前使用过任何本机视图,只需添加额外的 import DSWaveformImageViews。 SwiftUI 视图已从采用 Binding 更改为采用各自的纯值。

在 9.0.0 中

一些公共 API 略有更改,以使其更加简洁。 所有类型也已在 Waveform 枚举命名空间下分组。 意味着例如 WaveformConfiguration 已变为 Waveform.Configuration,依此类推。

在 7.0.0 中

颜色已移至相应 style 枚举上的关联值。

WaveformUIImage 类别已在 6.0.0 中删除,以简化 API。 请参见 Usage 以了解当前用法。

观看它的实际运行

SoundCard - 带有声音的明信片 让您可以发送带有音频信息的真实物理明信片。 直接从您的 iOS 设备。

DSWaveformImage 用于绘制音频信息的波形,这些波形会打印在由 SoundCard - 带有音频的明信片 发送的明信片上。

 

Download SoundCard

在 App Store 上下载 SoundCard。

 

Screenshot