1

我有一个简单的 MIDI 播放器(Swift 5、SwiftUI、iOS14),想用 MPRemoteCommandCenter 切换播放/暂停命令。锁定屏幕的控制在以下设置下工作正常,但我正在努力寻找如何在从应用程序内部而不是锁定屏幕切换播放/暂停时通知 MPRemoteCommandCenter 我的播放器状态。在我的应用程序中播放或暂停不会更改锁定屏幕上的播放/暂停图标,但是我可以通过将播放速率设置为 0 来停止显示的播放位置和锁定屏幕上的进度。换句话说,唯一的问题是锁定屏幕上的播放/暂停图标不同步。

我觉得我应该在这里发出通知,但我没有找到文档。我有一个类似的使用 AVAudioPlayer 的音频媒体播放器,这只是神奇的工作,我猜 AVAudioPlayer 正在吐出所需的通知。有没有人有关于如何使用我自己的不使用 AVAudioPlayer 的播放器执行此操作的教程或建议?谢谢。

//  ContentView.swift

import SwiftUI
import AudioKit
import MediaPlayer

struct ContentView: View {
    let engine: AudioEngine
    let sampler: MIDISampler
    let sequencer: AppleSequencer
    @State var playing: Bool = false

    init() {
        self.engine = AudioEngine()
        self.sampler = MIDISampler()
        self.sequencer = AppleSequencer()
        let url = Bundle.main.url(forResource: "mytrack", withExtension: "mid")!
        sequencer.loadMIDIFile(fromURL: url)
        sequencer.setGlobalMIDIOutput(sampler.midiIn)
        engine.output = sampler
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
            try AVAudioSession.sharedInstance().setActive(true)
            try engine.start()
        } catch let error {
            print(error)
        }
        
    }

    var body: some View {
        Text("Play a MIDI file")
            .padding()

        Button(action: {
            self.togglePlayPause()
        }) {
            if playing {
                Text("Pause")
            } else {
                Text("Play")
            }
        }.onAppear {
            self.setupRemoteTransportControls()
        }
    }

    func togglePlayPause() {
        if playing {
            sequencer.stop()
        } else {
            sequencer.play()
        }
        self.playing = playing ? false : true
        self.setupNowPlayingInfo()
    }

    func setupNowPlayingInfo() {
        var nowPlayingInfo = [String: Any]()
        nowPlayingInfo[MPMediaItemPropertyTitle] = "My track"
        nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = sequencer.currentPosition.seconds
        nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = sequencer.length.seconds
        nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = NSNumber(value: self.playing ? 1 : 0)
        MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
    }

    func setupRemoteTransportControls() {
        let commandCenter = MPRemoteCommandCenter.shared()

        commandCenter.togglePlayPauseCommand.addTarget { [self] _ in
            self.togglePlayPause()
            return .success
        }

        commandCenter.togglePlayPauseCommand.isEnabled = true
    }

}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
4

0 回答 0