william-weng/wwnormalizeaudioplayer
一個支援 音量正規化 與 順序播放 的音訊播放器,可讓多個音檔在播放時維持較一致的音量表現。
📖 簡介
WWNormalizeAudioPlayer 可用來播放一組音訊檔,並在需要時根據目標分貝值進行音量調整。 它適合用在需要連續播放多段音檔,或希望避免不同來源音檔音量忽大忽小的情境。
✨ 特色
- 支援從
Bundle以檔名直接播放音檔。 - 支援
URL陣列播放。 - 支援多段音檔依序播放。
- 支援音量正規化,可指定
targetDB。 - 支援播放進度通知、單曲播放完成通知與錯誤回報。
- 支援暫停、恢復與停止播放。
📦 安裝方式
Swift Package Manager
dependencies: [
.package(url: "https://github.com/William-Weng/WWNormalizeAudioPlayer.git", .upToNextMajor(from: "1.5.3"))
]🚀 使用方式
直接播放 Bundle 內音檔
import WWNormalizeAudioPlayer
let player = WWNormalizeAudioPlayer()
let filenames = ["do-re-mi-re-do.m4a", "audio.mp3"]
Task {
try audioPlayer.configure(delegate: self)
await audioPlayer.play(filenames: filenames)
}播放 URL 陣列
let urls: [URL] = [
Bundle.main.url(forResource: "do-re-mi-re-do", withExtension: "m4a")!,
Bundle.main.url(forResource: "audio", withExtension: "mp3")!
]
Task {
try audioPlayer.configure(delegate: self)
await audioPlayer.play(filenames: filenames)
}⚙️ 可用參數
| 參數 | 說明 | |---|---| | equalizer | 音訊等化器封裝。 | | volume | 調整播放器音量,範圍為 0.0 ~ 1.0。 | | audioNode | 目前播放音訊所對應的節點,可用於安裝 tap 取得即時音訊資料。 |
🧩 可用方法
| 方法 | 說明 | |---|---| | configure(delegate:preferredFrameRateRange:options:) | 設定代理與更新頻率,並初始化音訊引擎。 | | play(at:filenames:targetDB:callbackType:loop:shuffle:) | 播放指定 Bundle 中的音訊檔案列表。 | | play(with:targetDB:callbackType:loop:shuffle:) | 播放音訊 URL 陣列,支援順序播放與音量正規化。 | | stop() | 停止播放並重置狀態。 | | resume() | 從暫停狀態繼續播放。 | | pause() | 暫停播放並保留目前進度。 |
⚠️ 錯誤類型
| 錯誤 | 說明 | |---|---| | currentTimeUnavailable | 目前時間無法取得。 | | playerNodeNotReady | 播放節點尚未準備好。 | | audioSessionConfigurationFailed | 音訊 Session 設定失敗。 |
📝 Delegate
| 方法 | 說明 | |---|---| | audioPlayer(:trackIndex:didStartTracks:totalDuration:) | 當音訊播放器開始播放一組音軌時呼叫。 | | audioPlayer(:trackIndex:currentTime:tracTime:) | 音訊播放進度更新時呼叫。 | | audioPlayer(:didFinishTrackIndex:callbackType:) | 單一軌道播放完成時呼叫。 | | audioPlayer(:error:) | 播放過程發生錯誤時呼叫。 |
💡 範例
import UIKit
import AVFoundation
import WWNormalizeAudioPlayer
final class ViewController: UIViewController {
private let audioPlayer = WWNormalizeAudioPlayer()
private let filenames = ["do-re-mi-re-do.m4a", "audio.mp3"]
override func viewDidLoad() {
super.viewDidLoad()
Task {
audioPlayer.configure(delegate: self)
await audioPlayer.play(filenames: filenames)
}
}
}
extension ViewController: WWNormalizeAudioPlayer.Delegate {
func audioPlayer(_ player: WWNormalizeAudioPlayer, didStartTracks tracks: [URL], totalDuration: TimeInterval) {
tracks.forEach { print($0) }
print("total = \(totalDuration) sec")
}
func audioPlayer(_ player: WWNormalizeAudioPlayer, trackIndex: Int, currentTime: TimeInterval, trackTime: TimeInterval) {
let audio = filenames[trackIndex]
print("time (\(audio)) = \(currentTime) of \(trackTime)")
}
func audioPlayer(_ player: WWNormalizeAudioPlayer, didFinishTrackIndex trackIndex: Int, callbackType: AVAudioPlayerNodeCompletionCallbackType) {
let audio = filenames[trackIndex]
print("finish = \(audio)")
}
func audioPlayer(_ player: WWNormalizeAudioPlayer, error: Error) {
print("error = \(error)")
}
}Package Metadata
Repository: william-weng/wwnormalizeaudioplayer
Default branch: main
README: README.md