SwiftUI中的AVAudioPlayer延迟
我正在做一个非常简单的ABC应用,每个字母都有一个按钮。点击其中一个按钮,对应的mp3就会播放。这是按钮的代码:
struct KeyCell: View {
@State private var player: AVAudioPlayer?
let character: Character
let color: Color
let onTap: (Character) -> Void
var body: some View {
Button(action: keypressed) {
Circle()
.fill(color)
.frame(width: 80, height: 80)
.padding()
.overlay {
Text(character.character)
.font(Font.system(size: 60))
.fontWeight(.medium)
}
}
.buttonStyle(.plain)
}
private func keypressed() {
onTap(character)
guard let soundURL = Bundle.main.url(forResource: character.file, withExtension: "mp3") else {
return
}
do {
player = try AVAudioPlayer(contentsOf: soundURL)
} catch {
print("Failed to load the sound: \(error)")
}
player?.play()
}
}
我发现一个问题:A按钮会立刻播放。B会有一点延迟,C的延迟更长,依此类推,直到Z 需要好几秒才播放完毕。
我尝试过的方法:
- 将AVAudioPlayer的创建移到.task中:
@State private var player: AVAudioPlayer?
.
.
.
Button(action: keypressed) {...}
.task {
guard let soundURL = Bundle.main.url(forResource: character.file, withExtension: "mp3") else { return }
player = try? AVAudioPlayer(contentsOf: soundURL)
}
private func keypressed() {
player?.play()
}
- 使用这个示例创建一个声音播放器类 示例:
class Sounds {
static var audioPlayer:AVAudioPlayer?
static func playSounds(soundfile: String) {
if let path = Bundle.main.path(forResource: soundfile, ofType: "mp3") {
do{
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer?.prepareToPlay()
audioPlayer?.play()
}catch {
print("Error")
}
}
}
}
然后就像这样播放:
private func keypressed() {
Sounds.playSounds(soundfile: character.file)
}
以上方法都没有解决问题。有什么建议吗?
解决方案
尝试使用一个单例(SoundManager)来管理字符声音的播放。
示例代码,请根据你的需求调整逻辑:
import SwiftUI
import AVFoundation
struct ContentView: View {
let characters = [
Character(character: "A", file: "testA"),
Character(character: "B", file: "testB"),
Character(character: "C", file: "testC")
]
let color: Color = Color.green
var body: some View {
ForEach(characters) { character in
KeyCell(character: character, color: color)
}
}
}
struct KeyCell: View {
let character: Character
let color: Color
var body: some View {
Button {
SoundManager.shared.togglePlay(character: character)
} label: {
Circle()
.fill(color)
.frame(width: 80, height: 80)
.padding()
.overlay {
Text(character.character)
.font(.system(size: 60, weight: .medium))
}
}
.buttonStyle(.plain)
}
}
struct Character: Identifiable {
let id = UUID()
var character: String
var file: String
}
class SoundManager {
static let shared = SoundManager()
private var player: AVAudioPlayer?
private var currentFile: String?
func togglePlay(character: Character) {
if player?.isPlaying == true {
player?.stop()
return // <--- adjust
}
// Only re-create if needed
if currentFile != character.file {
guard let url = Bundle.main.url(forResource: character.file, withExtension: "mp3") else {
return
}
do {
player = try AVAudioPlayer(contentsOf: url)
currentFile = character.file
} catch {
print("Error: \(error)")
return
}
}
player?.play()
}
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。