Set MPNowPlayingInfoCenter with other background audio playing
Asked Answered
O

3

18

I am trying to play a video using MPMoviePlayerController for an iOS app in Swift.

My goal is to be able to play system music with something like apple music, then open my app and have the audio mix in, but I want my app to be able to take control of MPNowPlayingInfoCenter.

How can I use AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: .MixWithOthers) while still set the MPNowPlayingInfoCenter?

Google Maps mixes in audio while taking setting MPNowPlayingInfoCenter. Below is how I am trying to set the MPNowPlayingInfoCenter:

func setMeta(){
    UIApplication.sharedApplication().beginReceivingRemoteControlEvents()
    self.becomeFirstResponder()
    if let player = PlayWorkoutViewController.player{
        let coverArt = MPMediaItemArtwork(image: UIImage(named: "AlbumArt")!)
        let dict: [String: AnyObject] = [
            MPMediaItemPropertyArtwork: coverArt,
            MPMediaItemPropertyTitle:workout.title,
            MPMediaItemPropertyArtist:"Alex",
            MPMediaItemPropertyAlbumTitle:workout.program.title,
            MPNowPlayingInfoPropertyPlaybackRate: player.currentPlaybackRate,
            MPNowPlayingInfoPropertyElapsedPlaybackTime: player.currentPlaybackTime,
            MPMediaItemPropertyPlaybackDuration: player.playableDuration
        ]
        MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo = dict
    }
}

The above function works when I am not trying to play outside music with an option (.MixWithOthers) at the same time, but while I am trying to play outside music with the option (.MixWithOthers) the info center does not update.

Edit 1: Just to make things super clear, I already having video playing properly I am trying to play video with other background audio while being able to set MPNowPlayingInfoCenter.

Overhead answered 2/1, 2016 at 6:54 Comment(0)
F
11

This isn't currently possible in iOS. Even just changing your category options to .MixWithOthers causes your nowPlayingInfo to be ignored.

My guess is iOS only considers non-mixing apps for inclusion in MPNowPlayingInfoCenter, because there is uncertainty as to which app would show up in (e.g.) Control Center if there are multiple mixing apps playing at the same time.

I'd very much like it if iOS used a best-effort approach for choosing the "now playing app", something like this:

  1. If there's a non-mixing app playing, pick that. Else..
  2. If there's only one mixing app playing, pick that. Else..
  3. If there are multiple mixing apps playing, just pick one :) Or pick none, I'm fine with either.

If you'd like this behavior as well, I'd encourage you to file a bug with Apple.

Fermi answered 12/1, 2016 at 15:12 Comment(0)
I
0

Have you tried implementing your own custom function to update the MPNowPlayingInfoCenter? Recently I was using an AVAudioPlayer to play music and needed to do the updating manually.

This is basically the function I called upon a new song being loaded.

func updateNowPlayingCenter() {
    let center = MPNowPlayingInfoCenter.defaultCenter()
    if nowPlayingItem == nil {
        center.nowPlayingInfo = nil
    } else {
        var songInfo = [String: AnyObject]()

        // Add item to dictionary if it exists
        if let artist = nowPlayingItem?.artist {
            songInfo[MPMediaItemPropertyArtist] = artist
        }
        if let title = nowPlayingItem?.title {
            songInfo[MPMediaItemPropertyTitle] = title
        }
        if let albumTitle = nowPlayingItem?.albumTitle {
            songInfo[MPMediaItemPropertyAlbumTitle] = albumTitle
        }
        if let playbackDuration = nowPlayingItem?.playbackDuration {
            songInfo[MPMediaItemPropertyPlaybackDuration] = playbackDuration
        }
        if let artwork = nowPlayingItem?.artwork {
            songInfo[MPMediaItemPropertyArtwork] = artwork
        }
        center.nowPlayingInfo = songInfo
    }
}

I am not sure if doing this upon a movie being loaded will override the MPMoviePlayerController, but it seems worth a shot.

Additionally, they have depreciated MPMoviePlayerController and replaced it with AVPlayerViewController, so thats also worth looking into.

Edit: Also I would check to make sure that you are properly receiving remote control events, as this impacts the data being displayed by the info center.

It answered 6/1, 2016 at 1:11 Comment(1)
Hello, thanks for your reply. I have updated the question. The problem is not setting the info center normally it is setting the info center while playing music with the .MixWithOthers optionOverhead
W
-2

To play the video in swift use this:-

func playVideoEffect() {
    let path = NSBundle.mainBundle().pathForResource("egg_grabberAnmi", ofType:"mp4")
    let url = NSURL.fileURLWithPath(path!)
    self.moviePlayer = MPMoviePlayerController(contentURL: url)
    if let player = moviePlayer {
        let screenSize: CGRect = UIScreen.mainScreen().bounds
        player.view.frame = CGRect(x: frame.size.width*0.10,y: frame.size.width/2, width:screenSize.width * 0.80, height: screenSize.width * 0.80)
        player.view.sizeToFit()
        player.scalingMode = MPMovieScalingMode.Fill
        player.fullscreen = true
        player.controlStyle = MPMovieControlStyle.None
        player.movieSourceType = MPMovieSourceType.File
        player.play()
        self.view?.addSubview(player.view)
        var timer = NSTimer.scheduledTimerWithTimeInterval(6.0, target: self, selector: Selector("update"), userInfo: nil, repeats: false)     
    }
}


// And Use the function to play Video
playVideoEffect()
Wera answered 11/1, 2016 at 10:4 Comment(2)
yes we can :- var url:NSURL = NSURL(string: "Your URL")Wera
@Raksha I think you completely missed the question. I already know how to play video, please reread the question.Overhead

© 2022 - 2024 — McMap. All rights reserved.