AVPlayer.addPeriodicTimeObserver 相当于 AVAudioPlayerNode
AVPlayer.addPeriodicTimeObserver equivalent on AVAudioPlayerNode
我正在将使用 AVPlayer 的 react-native 包重构为 AVAudioEngine 和 AVAudioPlayerNode。但是我混淆了如何使用 AVAudioPlayerNode 来转 AVPlayer.addPeriodicTimeObserver。这个想法是我需要在播放音乐时获取时间数据,因此在这个 addPeriodicTimeObserver 闭包中需要间隔发送,所以在这方面如何在 AVAudioPlayerNode 上使用它,谢谢!
func addPeriodicTimeObserver() {
let timeScale = CMTimeScale(NSEC_PER_SEC)
let time = CMTime(seconds: subscriptionDuration, preferredTimescale: timeScale)
timeObserverToken = audioPlayer.addPeriodicTimeObserver(forInterval: time,
queue: .main) {_ in
if (self.audioPlayer != nil) {
self.sendEvent(withName: "rn-playback", body: [
"isMuted": self.audioPlayer.isMuted,
"currentPosition": self.audioPlayerItem.currentTime().seconds * 1000,
"duration": self.audioPlayerItem.duration.seconds * 1000,
])
}
}
}
请试试这个,可能会解决你的问题,currentTime 会告诉 avplayer 当前位置
let timeScale = CMTimeScale(NSEC_PER_SEC)
let time = CMTime(seconds: 0.01, preferredTimescale: timeScale)
timeObserverToken = player.addPeriodicTimeObserver(forInterval: time,
queue: .main) {_ in
if (self.player != nil) {
let currentTime = self.player.currentTime().seconds
print("currentTime",currentTime)
}
}
最后我用定时器来观察。
@objc(setupPlayer:rejecter:)
func setupPlayer(
resolve: @escaping RCTPromiseResolveBlock,
rejecter reject: @escaping RCTPromiseRejectBlock
) {
...
do {
try engine.start()
startPlaybackTimer()
} catch let err {
...
}
}
@objc(updatePlaybackProgress:)
public func updatePlaybackProgress(timer: Timer) -> Void {
if player.isPlaying {
let status = [
"currentPosition": getCurrentPos(),
"duration": getCurrentDuration(),
] as [String : Any];
self.sendEvent(withName: "playbackData", body: status)
}
}
@objc(startPlaybackTimer)
func startPlaybackTimer() -> Void {
DispatchQueue.main.async {
self.timer = Timer.scheduledTimer(
timeInterval: self.subscriptionDuration,
target: self,
selector: #selector(self.updatePlaybackProgress),
userInfo: nil,
repeats: true
)
}
}
我正在将使用 AVPlayer 的 react-native 包重构为 AVAudioEngine 和 AVAudioPlayerNode。但是我混淆了如何使用 AVAudioPlayerNode 来转 AVPlayer.addPeriodicTimeObserver。这个想法是我需要在播放音乐时获取时间数据,因此在这个 addPeriodicTimeObserver 闭包中需要间隔发送,所以在这方面如何在 AVAudioPlayerNode 上使用它,谢谢!
func addPeriodicTimeObserver() {
let timeScale = CMTimeScale(NSEC_PER_SEC)
let time = CMTime(seconds: subscriptionDuration, preferredTimescale: timeScale)
timeObserverToken = audioPlayer.addPeriodicTimeObserver(forInterval: time,
queue: .main) {_ in
if (self.audioPlayer != nil) {
self.sendEvent(withName: "rn-playback", body: [
"isMuted": self.audioPlayer.isMuted,
"currentPosition": self.audioPlayerItem.currentTime().seconds * 1000,
"duration": self.audioPlayerItem.duration.seconds * 1000,
])
}
}
}
请试试这个,可能会解决你的问题,currentTime 会告诉 avplayer 当前位置
let timeScale = CMTimeScale(NSEC_PER_SEC)
let time = CMTime(seconds: 0.01, preferredTimescale: timeScale)
timeObserverToken = player.addPeriodicTimeObserver(forInterval: time,
queue: .main) {_ in
if (self.player != nil) {
let currentTime = self.player.currentTime().seconds
print("currentTime",currentTime)
}
}
最后我用定时器来观察。
@objc(setupPlayer:rejecter:)
func setupPlayer(
resolve: @escaping RCTPromiseResolveBlock,
rejecter reject: @escaping RCTPromiseRejectBlock
) {
...
do {
try engine.start()
startPlaybackTimer()
} catch let err {
...
}
}
@objc(updatePlaybackProgress:)
public func updatePlaybackProgress(timer: Timer) -> Void {
if player.isPlaying {
let status = [
"currentPosition": getCurrentPos(),
"duration": getCurrentDuration(),
] as [String : Any];
self.sendEvent(withName: "playbackData", body: status)
}
}
@objc(startPlaybackTimer)
func startPlaybackTimer() -> Void {
DispatchQueue.main.async {
self.timer = Timer.scheduledTimer(
timeInterval: self.subscriptionDuration,
target: self,
selector: #selector(self.updatePlaybackProgress),
userInfo: nil,
repeats: true
)
}
}