Swift:在锁定屏幕上添加前进/后退 15 秒按钮

Posted

技术标签:

【中文标题】Swift:在锁定屏幕上添加前进/后退 15 秒按钮【英文标题】:Swift: add forward/backward 15 seconds buttons on lock screen 【发布时间】:2021-05-21 13:14:00 【问题描述】:

我有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")
        
    

如何解决?

播放和停止按钮可以正常工作,但倒带不起作用。

【问题讨论】:

【参考方案1】:

我是这样做的

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()

【讨论】:

我将它添加到我的代码中并在此函数中添加断点。但是这个函数没有被调用。为什么? 导入MediaPlayer并从viewDidLoad调用函数 工作正常。但我有一些问题。 1. 在锁定屏幕上,我看到按钮图标后退到 +10 或 -10。怎么改成15? 2.我还添加了changePlaybackPositionCommand,但是当我点击按钮倒带时,曲目倒带很好。但滑块不会改变位置 我解决了第一个问题。但没有解决 2.【参考方案2】:

回答你的问题2;

您需要更新 MPNowPlayingInfoPropertyElapsedPlaybackTime 以匹配 CMTimeGetSeconds(player.currentTime() ),更新此值的最佳位置是添加观察者 forKeyPath: "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
                
        

    

【讨论】:

以上是关于Swift:在锁定屏幕上添加前进/后退 15 秒按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 上使用 swift 防止我的​​应用程序屏幕锁定

在幻灯片中添加后退和前进功能

滑动时禁用网页导航(后退和前进)

求HTML网页点击UE浏览器上的后退按钮后能回到上一次浏览的网页的代码!

用iframe后 点后退按钮时总是在潜套框里后退,如何让整个父页面整体后退呢?

如何用jQuery禁用浏览器的前进后退按钮