当用户点按视图时,我希望播放声音的延迟可以忽略不计。我已经同时使用AVAudioPlayer
和AudioServices尝试过此操作,但我遇到了同样的问题:如果点击之间的时间间隔超过一秒,则会略有延迟。换句话说,这里发生了什么:
我们所谈论的延迟很短,可能只有100毫秒左右,但足以使播放不像其他人那样立即感觉/发出声音。这是代码的AVAudioPlayer
版本:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var player:AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
let soundUrl = Bundle.main.url(forResource: "short_sound", withExtension: "wav")!
player = try! AVAudioPlayer(contentsOf: soundUrl)
player.volume = 0 // "Prime the pump"
player.play()
let r = TouchDownGestureRecognizer(target: self, action: #selector(tapped(_:)))
self.view.addGestureRecognizer(r)
}
func tapped(_ gesture: TouchDownGestureRecognizer){
player.volume = 1
player.play()
}
}
这是AudioServices版本。在这种情况下,有other posts表示在初始化期间可以播放静音,然后启动泵#34;但这只会解决第一个声音。此问题会影响1秒延迟后发生的所有声音。
import UIKit
import AudioToolbox
class ViewController: UIViewController {
var soundID:SystemSoundID = 0
override func viewDidLoad() {
super.viewDidLoad()
let soundUrl = Bundle.main.url(forResource: "short_sound", withExtension: "wav")!
AudioServicesCreateSystemSoundID(soundUrl as CFURL, &soundID)
let r = TouchDownGestureRecognizer(target: self, action: #selector(tapped(_:)))
self.view.addGestureRecognizer(r)
}
func tapped(_ gesture: TouchDownGestureRecognizer){
AudioServicesPlaySystemSound(soundID)
}
}
在这两种情况下,这"触地"使用识别器(by @le-sang):
import Foundation
import UIKit.UIGestureRecognizerSubclass
class TouchDownGestureRecognizer: UIGestureRecognizer {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
if self.state == .possible {
self.state = .recognized
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
self.state = .failed
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
self.state = .failed
}
}
我还尝试使用UILongPressGestureRecognizer
和minimumPressDuration=0
同样的事情发生了。同样,如果我用UIView
替换UIControl
并设置目标/操作,也是如此。非常感谢任何见解,感谢阅读。
答案 0 :(得分:0)
这是我发现的修复方法。我对这个解决方案并不完全满意(仍然不确定为什么这种情况发生),但它确实对两个玩家都有效。
这个想法很简单:如果你让任何一个玩家独自停留一秒左右,它就会开始打盹,然后在你需要的时候花点时间醒来。因此,解决方案是定期“轻推”玩家,这样就不会开始打盹。
对于AVAudioPlayer
案例:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var player:AVAudioPlayer!
var ghostPlayer:AVAudioPlayer!
var timer:Timer!
override func viewDidLoad() {
super.viewDidLoad()
let soundUrl = Bundle.main.url(forResource: "short_sound", withExtension: "wav")!
player = try! AVAudioPlayer(contentsOf: soundUrl)
ghostPlayer = try! AVAudioPlayer(contentsOf: soundUrl)
ghostPlayer.volume = 0
ghostPlayer.play()
timer = Timer.scheduledTimer(timeInterval: 0.5,
target: self,
selector: #selector(nudgeAudio),
userInfo: nil,
repeats: true)
let r = TouchDownGestureRecognizer(target: self, action: #selector(tapped(_:)))
self.view.addGestureRecognizer(r)
}
func tapped(_ gesture: TouchDownGestureRecognizer){
player.play()
}
func nudgeAudio() {
ghostPlayer.play()
}
}
对于AudioServices:
import UIKit
import AudioToolbox
class ViewController: UIViewController {
var soundID:SystemSoundID = 0
var ghostID:SystemSoundID = 1
var timer:Timer!
override func viewDidLoad() {
super.viewDidLoad()
let soundUrl = Bundle.main.url(forResource: "short_sound", withExtension: "wav")!
AudioServicesCreateSystemSoundID(soundUrl as CFURL, &soundID)
let ghostUrl = Bundle.main.url(forResource: "silence", withExtension: "wav")!
AudioServicesCreateSystemSoundID(ghostUrl as CFURL, &ghostID)
timer = Timer.scheduledTimer(timeInterval: 0.5,
target: self,
selector: #selector(nudgeAudio),
userInfo: nil,
repeats: true)
let r = TouchDownGestureRecognizer(target: self, action: #selector(tapped(_:)))
self.view.addGestureRecognizer(r)
}
func tapped(_ gesture: TouchDownGestureRecognizer){
AudioServicesPlaySystemSound(soundID)
}
func nudgeAudio() {
AudioServicesPlaySystemSound(ghostID)
}
}