gpt4 book ai didi

ios - 如何在 iOS 中使用 CoreMotion 和 AVAudioPlayer 播放短音频文件?

转载 作者:行者123 更新时间:2023-11-28 06:52:06 25 4
gpt4 key购买 nike

当我在 X 轴上移动 iPhone 时(我正在使用 CoreMotionAVAudioPlayer),我试图播放短声音(1 到 4 秒)。我想为每个运动方向变化播放一种声音。

我写了下面的代码,但是当我移动 iPhone 时,声音播放了很多次,但移动方向没有改变。下面的 print 调用显示了许多 DownUp,例如 Down Down Down Up Down Down Up Up... .如果我评论两个 play 回调,print 会显示我期望的交替:Down Up Down Up Down Up...

为什么AVAudioPlayer.play在移动方向改变时被多次调用?

override func viewDidLoad() {
super.viewDidLoad()

// Audio
audioURL = NSBundle.mainBundle().URLForResource("shortSound", withExtension: "wav")!
do {
try audioPlayer = AVAudioPlayer(contentsOfURL: audioURL)
audioPlayer.prepareToPlay()
} catch {
print("audioPlayer failure")
}

// Sensor
lastDirection = 0
threshold = 2.1

motionManager = CMMotionManager()
if motionManager.accelerometerAvailable {
let queue = NSOperationQueue()
motionManager.startAccelerometerUpdatesToQueue(queue, withHandler: {
data, error in

guard let data = data else{
return
}

// Get the acceleration
let xAccel = data.acceleration.x
let xPositive = xAccel > 0

// Run if the acceleration is higher than theshold
if abs(xAccel) > self.threshold {

// Run only if the direction is changed
if self.lastDirection != 1 && xPositive {
print("Up")
self.play()
self.lastDirection = 1
} else if self.lastDirection != -1 && !xPositive {
print("Down")
self.play()
self.lastDirection = -1
}
}
})
}
}

func play() {
audioPlayer.currentTime = 0
audioPlayer.play()
}

最佳答案

您可能遇到线程问题。您在后台队列(queue,一个任意的 NSOperationQueue,顺便说一句,您也未能保留)上运行更新,但随后您正在与 self.lastDirection 并在同一个后台队列上调用 self.play(),而不考虑这些事件的线程安全性。

我建议至少重写此部分:

            if self.lastDirection != 1 && xPositive {
print("Up")
self.play()
self.lastDirection = 1
} else if self.lastDirection != -1 && !xPositive {
print("Down")
self.play()
self.lastDirection = -1
}

...更像这样:

           dispatch_async(dispatch_get_main_queue()) {
if self.lastDirection != 1 && xPositive {
self.lastDirection = 1
print("Up")
self.play()
} else if self.lastDirection != -1 && !xPositive {
self.lastDirection = -1
print("Down")
self.play()
}
}

请注意,我做了两处更改:我已经跳转到主线程进行整个 check-print-play-toggle 舞蹈,并且我颠倒了事件的顺序以便它进入 check-toggle-打印播放。

此外,我还建议进行另外两项更改:保留操作队列(即使其成为属性而不是本地属性),并降低运动管理器更新的频率(通过设置较低的 accelerometerUpdateInterval)。

关于ios - 如何在 iOS 中使用 CoreMotion 和 AVAudioPlayer 播放短音频文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34597669/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com