Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MPMusicPlayerController slow to respond when systemMusicPlayer, fast when application

I have a music app that uses the MPMusicPlayerController.

I originally wrote it using the systemMusicPlayer option under iOS 9. I had some trouble with the player not shutting down correctly under certain circumstances so I switched to the appplicationMusicPlayer (see Quitting app causes error "Message from debugger: Terminated due to signal 9")

However, as an application player, I can't get a lot of the benefits like control center handling, bluetooth data display, etc.

So, I switched back to the systemMusicPlayer. I have also changed to Xcode 9.2 and a compile target of iOS 10.3.

Now when I run my app, it can take several seconds for it to respond to controls like play/pause or next/previous. My whole UI is painfully unresponsive.

I tried switching back to applicationMusicPlayer, recompiled, and sure enough - the UI is at normal speed.

So now I'm in a crappy position - with systemMusicPlayer, the app is barely usable, but with applicationMusicPlayer I lose a ton of capabilities.

This seems directly related to either iOS 11.2.2 on my iPhone, or something to do with targeting iOS 10.3+

Does anyone have any information about what is going on and how to fix it

EDIT: I created a very basic player and it seems to work fine in either mode, so now I'm puzzled - I'll be testing other MP commands to see what the issue is but since even my UI slows down I'm not sure.

EDIT 2: I believe I've found the culprit to be NotificationCenter, and also getting States from the MPMusicPlayerController. I've updated my sample code below which shows the problem. Once running, clicking the 'next' button will be slow sometimes, but clicking 'previous' can cause delays of up to two seconds!!

Here is the basic code if you want to create a simple player. Be sure to add three buttons in the storyboard and connect them accordingly.

//
//  ViewController.swift
//  junkplayer
//

import UIKit
import MediaPlayer

let notificationCenter = NotificationCenter.default

let myMP:MPMusicPlayerController = MPMusicPlayerController.systemMusicPlayer
//let myMP:MPMusicPlayerController = MPMusicPlayerController.applicationMusicPlayer()

class ViewController: UIViewController {
    @IBOutlet weak var xxx: UIButton!
    @IBOutlet weak var nextbut: UIButton!
    @IBOutlet weak var prevbut: UIButton!
    var qrySongs = MPMediaQuery()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        myMP.repeatMode = MPMusicRepeatMode.none
        myMP.shuffleMode = MPMusicShuffleMode.off
        myMP.prepareToPlay()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        stopMPNotifications()
        startMPNotifications()
    }

    @IBAction func nextbut(_ sender: Any) {
        myMP.skipToNextItem()
    }
    @IBAction func prevbut(_ sender: Any) {
        myMP.skipToPreviousItem()
    }
    @IBAction func playbut(_ sender: UIButton) {
        qrySongs = MPMediaQuery.songs()
        myMP.setQueue(with: qrySongs)

        myMP.play()
    }
    func startMPNotifications(){
        notificationCenter.addObserver(self, selector: #selector(showNowPlaying), name: .MPMusicPlayerControllerNowPlayingItemDidChange, object: myMP)
        notificationCenter.addObserver(self, selector: #selector(handlePlayState), name: .MPMusicPlayerControllerPlaybackStateDidChange, object: myMP)
        myMP.beginGeneratingPlaybackNotifications()
    }
    func stopMPNotifications(){
        notificationCenter.removeObserver(self, name: .MPMusicPlayerControllerPlaybackStateDidChange, object: myMP)
        notificationCenter.removeObserver(self, name: .MPMusicPlayerControllerNowPlayingItemDidChange, object: myMP)
        myMP.endGeneratingPlaybackNotifications()
    }
    @objc func handlePlayState(){
        if myMP.playbackState == .playing {
            print("handlePlayState playback state = playing")
        }else{
            print("handlePlayState playback state NOT playing")
        }
        print("handlePlayState going to shownowplaying")
        showNowPlaying()
    }
    @objc func showNowPlaying(){
        if myMP.nowPlayingItem != nil {
            print("shownowplaying nowplaying not null")
        }
    }
}
like image 716
wayneh Avatar asked Jan 17 '18 21:01

wayneh


People also ask

How does the system music player work?

The system music player employs the built-in Music app on your behalf. On instantiation, it takes on the current Music app state, such as the identification of the now-playing item. If a user switches away from your app while music is playing, that music continues to play.

How does the music app respond to remote control events?

The Music app receives the remote control events, not your app. However, the Music app responds to remote control events on your behalf. For example, if your app plays audio using the system music player, and you switch from your app to the iOS device’s Now Playing controls, the controls work as expected.

How to fix the slow performance of PC?

1 Restart your PC 2 Upgrade your apps or programs 3 Run Windows Defender or antivirus software to scan for virus or malware 4 Run System file checker to fix the slow issue 5 Repair or reinstall problematic apps 6 Improve computer performance by extending system or upgrading to SSD

What happens when a user switches away from the music player?

If a user switches away from your app while music is playing, that music continues to play. The Music app then has your music player’s most recently-set repeat mode, shuffle mode, playback state, and now-playing item. Creating a new instance of MPMusicPlayerController and not specifying the player type returns a system music player.


1 Answers

The app seems to lock up once you start playing, but if you swipe up to show the Control Centre then dismiss it, the app starts working fine immediately.

like image 193
Ben Thomas Avatar answered Oct 06 '22 07:10

Ben Thomas