Swift: 在锁定屏幕上添加 forward/backward 15 秒按钮
Swift: add forward/backward 15 seconds buttons on lock screen
我有AVAudioPlayer
。我想在锁定屏幕上添加 15 秒倒带按钮,如下图所示:
但我得到的结果就像这张图片:
我的代码:
var audioPlayer: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try? AVAudioSession.sharedInstance().setActive(true)
UIApplication.shared.beginReceivingRemoteControlEvents()
...
audioPlayer = try AVAudioPlayer(contentsOf: soundURL!)
audioPlayer.delegate = self
audioPlayer.prepareToPlay()
play(sender:AnyObject.self as AnyObject)
restorePlayerCurrentTime()
}
override func remoteControlReceived(with event: UIEvent?) {
guard let event = event else {
print("no event\n")
return
}
guard event.type == UIEventType.remoteControl else {
print("received other event type\n")
return
}
switch event.subtype {
case UIEventSubtype.remoteControlBeginSeekingBackward:
audioPlayer.play()
case UIEventSubtype.remoteControlBeginSeekingForward:
audioPlayer.pause()
case UIEventSubtype.remoteControlPlay:
print("received remote play\n")
audioPlayer.play()
case UIEventSubtype.remoteControlPause:
print("received remote pause\n")
audioPlayer.pause()
/*case UIEventSubtype.remoteControlTogglePlayPause:
print("received toggle\n")*/
default:
print("received \(event.subtype) which we did not process\n")
}
}
如何解决?
播放和停止按钮工作正常,但倒带不起作用。
我是这样做的
import MediaPlayer
func setupMediaPlayerNotificationView() {
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.skipForwardCommand.addTarget { [weak self] event in
print("You Pressed skipForward")
return .success
}
commandCenter.skipBackwardCommand.addTarget { [weak self] event in
print("You Pressed skipBackward")
return .success
}
}
这将为您提供跳过按钮。
从
调用它
override func viewDidLoad() {
super.viewDidLoad()
self.setupMediaPlayerNotificationView()
}
回答你的问题2;
您需要更新 MPNowPlayingInfoPropertyElapsedPlaybackTime 以匹配 CMTimeGetSeconds(player.currentTime() ),更新此值的最佳位置是为 KeyPath 添加观察者:“timeControlStatus”并更新 .waitingToPlaySpecifieldRate / .paused 和.playing
创建一个名为 nowPlayingInfo 的全局字典
https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter/1615903-nowplayinginfo
示例:
nowPlayingInfo = nil
nowPlayingInfo = [String: Any]()
self.nowPlayingInfo?[MPMediaItemPropertyTitle] = data[0].currentTrackTitle
self.nowPlayingInfo?[MPMediaItemPropertyArtist] = data[0].currentArtist
self.nowPlayingInfo?[MPMediaItemPropertyAlbumTitle] = data[0].currentAlbumName
self.nowPlayingInfo?[MPNowPlayingInfoPropertyDefaultPlaybackRate] = NSNumber(value: 1)
self.nowPlayingInfo?[MPMediaItemPropertyPlaybackDuration] = CMTimeGetSeconds((player!.currentItem?.asset.duration)!)
self.nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(player.currentTime() )
let image = data[0].currentArtwork
self.nowPlayingInfo?[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size, requestHandler: { (size) -> UIImage in
return image
})
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
在 timeControlStatus oberver 中更新 nowPlayingInfo 全局字典的`self.nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(player.currentTime() )
您还需要在搜索(15 秒)之前将 MPNowPlayingInfoPropertyDefaultPlaybackRate 更新为 0,然后在搜索完成后将此值设置回 1。
示例;
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
guard context == &playerItemContext else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
if keyPath == "timeControlStatus" {
let statusNumber = change?[.newKey] as? NSNumber
// Switch over status value
switch statusNumber {
case 0:
//print("paused")
self.nowPlayingInfo?[MPNowPlayingInfoPropertyDefaultPlaybackRate] = NSNumber(value: 0)
self.nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(player.currentTime() )
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
case 1:
self.nowPlayingInfo?[MPNowPlayingInfoPropertyDefaultPlaybackRate] = NSNumber(value: 0)
self.nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(player.currentTime() )
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
case 2:
//print("playing")
self.nowPlayingInfo?[MPNowPlayingInfoPropertyDefaultPlaybackRate] = NSNumber(value: 1)
self.nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(player.currentTime() )
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
}
default:
fatalError() //this is never called in this scenario
}
}
}
我有AVAudioPlayer
。我想在锁定屏幕上添加 15 秒倒带按钮,如下图所示:
但我得到的结果就像这张图片:
我的代码:
var audioPlayer: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try? AVAudioSession.sharedInstance().setActive(true)
UIApplication.shared.beginReceivingRemoteControlEvents()
...
audioPlayer = try AVAudioPlayer(contentsOf: soundURL!)
audioPlayer.delegate = self
audioPlayer.prepareToPlay()
play(sender:AnyObject.self as AnyObject)
restorePlayerCurrentTime()
}
override func remoteControlReceived(with event: UIEvent?) {
guard let event = event else {
print("no event\n")
return
}
guard event.type == UIEventType.remoteControl else {
print("received other event type\n")
return
}
switch event.subtype {
case UIEventSubtype.remoteControlBeginSeekingBackward:
audioPlayer.play()
case UIEventSubtype.remoteControlBeginSeekingForward:
audioPlayer.pause()
case UIEventSubtype.remoteControlPlay:
print("received remote play\n")
audioPlayer.play()
case UIEventSubtype.remoteControlPause:
print("received remote pause\n")
audioPlayer.pause()
/*case UIEventSubtype.remoteControlTogglePlayPause:
print("received toggle\n")*/
default:
print("received \(event.subtype) which we did not process\n")
}
}
如何解决?
播放和停止按钮工作正常,但倒带不起作用。
我是这样做的
import MediaPlayer
func setupMediaPlayerNotificationView() {
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.skipForwardCommand.addTarget { [weak self] event in
print("You Pressed skipForward")
return .success
}
commandCenter.skipBackwardCommand.addTarget { [weak self] event in
print("You Pressed skipBackward")
return .success
}
}
这将为您提供跳过按钮。
从
调用它 override func viewDidLoad() {
super.viewDidLoad()
self.setupMediaPlayerNotificationView()
}
回答你的问题2;
您需要更新 MPNowPlayingInfoPropertyElapsedPlaybackTime 以匹配 CMTimeGetSeconds(player.currentTime() ),更新此值的最佳位置是为 KeyPath 添加观察者:“timeControlStatus”并更新 .waitingToPlaySpecifieldRate / .paused 和.playing
创建一个名为 nowPlayingInfo 的全局字典 https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfocenter/1615903-nowplayinginfo
示例:
nowPlayingInfo = nil
nowPlayingInfo = [String: Any]()
self.nowPlayingInfo?[MPMediaItemPropertyTitle] = data[0].currentTrackTitle
self.nowPlayingInfo?[MPMediaItemPropertyArtist] = data[0].currentArtist
self.nowPlayingInfo?[MPMediaItemPropertyAlbumTitle] = data[0].currentAlbumName
self.nowPlayingInfo?[MPNowPlayingInfoPropertyDefaultPlaybackRate] = NSNumber(value: 1)
self.nowPlayingInfo?[MPMediaItemPropertyPlaybackDuration] = CMTimeGetSeconds((player!.currentItem?.asset.duration)!)
self.nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(player.currentTime() )
let image = data[0].currentArtwork
self.nowPlayingInfo?[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size, requestHandler: { (size) -> UIImage in
return image
})
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
在 timeControlStatus oberver 中更新 nowPlayingInfo 全局字典的`self.nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(player.currentTime() )
您还需要在搜索(15 秒)之前将 MPNowPlayingInfoPropertyDefaultPlaybackRate 更新为 0,然后在搜索完成后将此值设置回 1。
示例;
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
guard context == &playerItemContext else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
if keyPath == "timeControlStatus" {
let statusNumber = change?[.newKey] as? NSNumber
// Switch over status value
switch statusNumber {
case 0:
//print("paused")
self.nowPlayingInfo?[MPNowPlayingInfoPropertyDefaultPlaybackRate] = NSNumber(value: 0)
self.nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(player.currentTime() )
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
case 1:
self.nowPlayingInfo?[MPNowPlayingInfoPropertyDefaultPlaybackRate] = NSNumber(value: 0)
self.nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(player.currentTime() )
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
case 2:
//print("playing")
self.nowPlayingInfo?[MPNowPlayingInfoPropertyDefaultPlaybackRate] = NSNumber(value: 1)
self.nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(player.currentTime() )
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
}
default:
fatalError() //this is never called in this scenario
}
}
}