Why when AVPlayer is taking part in with the display locked and I pause taking part in, it execute solely after few milliseconds? In my English studying software the audio will play and pause managed by a timer. However after I shut the display off the AVPlayer is not going to pause as scheduled (it’s managed by lyrics that are correct), however is delayed by a whole bunch of milliseconds.
Why and the way can I clear up it? My code runs effectively when the display is on even with the display locked or when the app is operating within the background. My iPhone isn’t in low battery mode. The audio file is saved on the iPhone itself.
Observer in AVPlayer subclass:
if observer == nil {
weak var wself = self;
observer = self.addPeriodicTimeObserver(forInterval: CMTime(seconds: 0.05, preferredTimescale: CMTimeScale(NSEC_PER_SEC)), queue: nil, utilizing: {cmtime in
if wself != nil {
wself!.onTimerTick(cmTime: cmtime);
}
})
}
onTimerTick()
methodology:
@objc func onTimerTick(cmTime:CMTime) {
if self.openAutoPlayAndReadTimer == false {
if self.autoPlayAndReadTimer != nil {
if self.autoPlayAndReadTimer!.isValid {
self.autoPlayAndReadTimer?.invalidate();
}
self.autoPlayAndReadTimer = nil;
}
return
}
let index = UserDefaults.getAL_WhiteCircleTime_In_ReadAndFollowView();
if index == 0 {
return
}
var i = 0;
for merchandise in self.realPlayTimeList! {
if merchandise.time < cmTime.seconds && abs(merchandise.time - cmTime.seconds) < 0.5 {
break
}
i = i + 1;
}
if i >= self.realPlayTimeList!.rely {
return
}
let matchItem = self.realPlayTimeList![i];
let time = matchItem.time;
if time == lastTickTime {
return
}
//If the duation is zero, break
if matchItem.stopDuration * matchItem.scale < 0.05 {
return
}
self.pause();
if self.delegate != nil {
self.delegate?.onSongPauseByAutoPlayAndReadTimer();
}
lastTickTime = time;
autoPlayAndReadTimer?.invalidate();
autoPlayAndReadTimer = nil;
if autoPlayAndReadTimer == nil || autoPlayAndReadTimer?.isValid == false {
let length = matchItem.stopDuration * matchItem.scale;
autoPlayAndReadTimer = Timer.scheduledTimer(timeInterval: length, goal: self, selector: #selector(onAutoPlayAndReadTimerTick), userInfo: nil, repeats: true);
}
autoPlayAndReadTimer?.hearth()
}
Timer onAutoPlayAndReadTimerTick()
methodology:
@objc func onAutoPlayAndReadTimerTick() {
if hasEnter == false {
hasEnter = true
return
} else {
hasEnter = false
}
self.play();
if self.delegate != nil {
self.delegate?.onSongPlayByAutoPlayAndReadTimer();
}
autoPlayAndReadTimer?.invalidate();
autoPlayAndReadTimer = nil;
}
Code in AppDelegate:
let audioSession = AVAudioSession.sharedInstance();
do {
attempt audioSession.setCategory(.playback, mode: .default, choices: []) // 或者使用 .ambient
attempt audioSession.setActive(true)
} catch {
print("Setting class to AVAudioSessionCategoryPlayback failed.")
}