How to change metadata for AVRoutePickerView?
Asked Answered
A

1

6

enter image description here

My app plays some sound and I implemented AVRoutePickerView so it can stream its sound through AirPlay or Bluetooth.

Once I tap the AVRoutePickerView, above image pops up which is good, however, with wrong image and title.

The image and title came from Apple Music app I played before.

How can I change this metadata?

I've tried configuring MPNowPlayingInfoCenter without luck.

let albumArt = MPMediaItemArtwork(boundsSize:CGSize(width: 50, height: 50)) { sz in
    return UIImage(named: "MyImage")!
}

MPNowPlayingInfoCenter.default().nowPlayingInfo = [MPMediaItemPropertyTitle: "some title",
                                               MPMediaItemPropertyArtist: "some artist",
                                               MPMediaItemPropertyArtwork: albumArt]

And this is how I made AVRoutePickerView.

import AVKit

let routePickerView = AVRoutePickerView.init(frame: myFrame)
routePickerView.backgroundColor = UIColor.clear
routePickerView.tintColor = UIColor(named: someColor)
routePickerView.activeTintColor = UIColor(named: someColor)
soundController.contentView.addSubview(routePickerView)

My app targets iOS11 and testing on iPhone 6 and iPhone 7.

Please guide me to the right way. Thanks

Ashur answered 26/4, 2018 at 20:15 Comment(0)
P
10

>> UPDATE <<
As well as providing Now Playing information using the MPNowPlayingInfoCenter object, it seems you need to setup remote event handlers (even if not used) using the MPRemoteCommandCenter object.
Also, the Now Playing info doesn't seem to update until audio is played by the app.

Steps:

1. Setup the Remote control event handlers.
In this example I have only configured the pauseCommand, as that was all that was needed to get the Now Playing info to work.

func setupRemoteTransportControls() {
    // Get the shared MPRemoteCommandCenter
    let commandCenter = MPRemoteCommandCenter.shared()

    // Add handler for Pause Command
    commandCenter.pauseCommand.addTarget{ event in
           // Does nothing yet
           return .success
    }

}


2. Configure the Now Playing information using the MPNowPlayingInfoCenter object.

func setupNowPlayingInfo() {

    var nowPlayingInfo = [String : Any]()
    nowPlayingInfo[MPMediaItemPropertyTitle] = "My Song Title"

    if let image = UIImage(named: "MyImage") {
        nowPlayingInfo[MPMediaItemPropertyArtwork] =
            MPMediaItemArtwork(boundsSize: image.size) { size in return image }
    }

    MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}


3. Create the Route Picker view control.

let routePickerView = AVRoutePickerView(frame: routView.bounds)
routePickerView.backgroundColor = UIColor.clear
routView.addSubview(routePickerView)


4. Play the audio and view the route picker.

If you view the route picker before playing the app audio, the old now playing info will remain.

Hope this works now!



OLD ANSWER
Your implementation looks ok. The only query would be the boundSize. It should be the original size of the artwork. From the manual: "The request handler returns an image in the newly requested size. The requested size must be less than the boundsSize parameter." It seems most implementations just return the original size.

Perhaps it is your implementation of AVRoutePickerView where the problem lies. Could you try putting it inside a dispatch queue?

DispatchQueue.main.async { 
    let albumArt = MPMediaItemArtwork(boundsSize:CGSize(width: 50, height: 50)) 
                    { sz in return UIImage(named: "MyImage")!}

    MPNowPlayingInfoCenter.default().nowPlayingInfo = 
        [MPMediaItemPropertyTitle: "some title", 
         MPMediaItemPropertyArtist: "some artist", 
         MPMediaItemPropertyArtwork: albumArt]
}

In my audio streaming application I provide the meta data for display in the Control Center and iOS Lock screen when the app is in background. I use the MPVolumeView which has a button for choosing the audio output route (automatically handles instantiation and display of an AVRoutePickerView).

My implemention is as follows (as per manual):

var nowPlayingInfo = [String : Any]()
nowPlayingInfo[MPMediaItemPropertyTitle] = "Song Title"
nowPlayingInfo[MPMediaItemPropertyArtist] = "Song Artist"

if let image = UIImage(named: "SongImage") {
    nowPlayingInfo[MPMediaItemPropertyArtwork] =  MPMediaItemArtwork(boundsSize: image.size) { size in return image }
}

MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
Pannell answered 3/5, 2018 at 0:19 Comment(4)
I implemented your code in a dispatch queue without luck. Thanks anyways.Ashur
How are you implementing the AVRoutePickerView ? Any code examples?Pannell
Works like a charm! I should have set the Remote control event handlers. Thanks a lot!Ashur
I am using AVRoutePickerView for audio call routing but AVRoutePickerView show iTunes icon when button is pressed instead of my app's icon. Though it works in a separate POC where I just add instance of AVRoutePickerView as subviewShrub

© 2022 - 2024 — McMap. All rights reserved.