Change lock screen background audio controls text? - ios

I have an iOS app that streams background audio using AVAudioSession. It is working correctly, but I am curious, is there any way to change the text on the lock screen audio controls? Right now it simply displays the name of my app, but I would like to change it to the name of the track.
Additionally, the multi-tasking bar has no text under the controls- is there a way to add the track name there, as the iPod app does?

iOS 5 now supports setting the track title as well as an album art image in both the lock screen and the remote playback controls (the controls you get when you double-click the home button and swipe right). Take a look at the
MPNowPlayingInfoCenter class. Of course, to maximize compatibility, you'd want to test whether MPNowPlayingInfoCenter is available, by doing something like:
if ([MPNowPlayingInfoCenter class]) {
/* we're on iOS 5, so set up the now playing center */
UIImage *albumArtImage = [UIImage imageNamed:#"HitchHikersGuide"];
albumArt = [[MPMediaItemArtwork alloc] initWithImage:albumArtImage];
NSDictionary *currentlyPlayingTrackInfo = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:#"Life, the Universe and Everything", [NSNumber numberWithInt:42], albumArt, nil] forKeys:[NSArray arrayWithObjects:MPMediaItemPropertyTitle, MPMediaItemPropertyPlaybackDuration, MPMediaItemPropertyArtwork, nil]];
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = currentlyPlayingTrackInfo;
}

here it is in swift! (no need to check for iOS 5 and up anymore)
let albumArt = MPMediaItemArtwork(image: UIImage(named:"HitchHikersGuide"))
let albumDict = [MPMediaItemPropertyTitle: "Life, the Universe and Everything", MPMediaItemPropertyPlaybackDuration: 42, MPMediaItemPropertyArtwork: albumArt]
MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo = albumDict

Related

App icon is not showing in CallKit UI

I have configured my Provider Configuration for CallKit iOS. In which I have also set 'iconTemplateImageData' for displaying app icon in CallKit UI. But app icon is not showing. It shows a white square box.
Provider Configuration Code:
CXProviderConfiguration *configuration = [[CXProviderConfiguration alloc] initWithLocalizedName:[NSString stringWithFormat:#"%#\n", _title]];
configuration.maximumCallGroups = 1;
configuration.maximumCallsPerCallGroup = 1;
UIImage *callkitIcon = [UIImage imageNamed:#"AppIcon"];
configuration.iconTemplateImageData = UIImagePNGRepresentation(callkitIcon);
_callKitProvider = [[CXProvider alloc] initWithConfiguration:configuration];
[_callKitProvider setDelegate:self queue:nil];
_callKitCallController = [[CXCallController alloc] initWithQueue:dispatch_get_main_queue()];
I have used AppIcon images in 'Images.xcassets' with sizes: -
1x: 40*40, 2x: 80*80, 3x: 120*120
Please help why my app icon is not showing.
Thanks in advance.
This is likely because you are using your AppIcon image, which is a fully opaque image, i.e. no part of that image is transparent or has alpha=0.
To get the desired effect, you have to use a different image which is partly (or mostly) transparent. The native in-call UI will only use the alpha channel of the image you provide, so it ignores colors. I suggest following the example in the Speakerbox sample app and providing a secondary PNG image in your image asset catalog with transparency.
You need to use below code in order to set app name and app icon for incoming VOIP calls
let localizedName = NSLocalizedString("App-Name", comment: "Name of application")
let providerConfiguration = CXProviderConfiguration(localizedName: localizedName)
providerConfiguration.iconTemplateImageData = UIImage.init(named: "appicon-Name")?.pngData()
Note: Your app icon must be transparent. result will be like in below image

how to change default receiver image size on tv screen

I altered the sample code and set the value, and then found that the default receiver image size has no change on tv. how to change that?
GCKMediaMetadata *metadata = [[GCKMediaMetadata alloc] init];
if (thumbnailURL) {
[metadata addImage:[[GCKImage alloc] initWithURL:thumbnailURL width:200 height:100]]; //<=== alter here, try to change "width:200 height:100" to "width:720 height:960", but there's no change.
}
GCKMediaInformation *mediaInformation =
[[GCKMediaInformation alloc] initWithContentID:[url absoluteString]
streamType:GCKMediaStreamTypeNone
contentType:mimeType
metadata:metadata
streamDuration:0
customData:nil];
[self.mediaControlChannel loadMedia:mediaInformation autoplay:autoPlay playPosition:startTime];
It is not clear what you are trying to achieve; if you want the image to be differently sized on your TV, then yo have to make changes in your receiver, in the <img/> tag to adjust to the size that you want.
You cannot customise the UI with a default media receiver. Use the styled media receiver instead and specify the size of your image in the css.

How to control play and pause of AVPlayer from locked screen. And how to set image of the app on locked screen [duplicate]

This question already has answers here:
How to enable iPod controls in the background to control non-iPod music in iOS 4?
(3 answers)
Closed 9 years ago.
I have an online audio player app. I want the user to have controls of the app's play and pause even from the locked screen. The buttons are already shown by default. The code for my app is here.
Now how to enable the buttons to control my player. And how to show the image of my App when the screen of the App is locked. This is the example image
Please help if this is possible.
Thanx in Advance.
iOS 5 onwards, MPNowPlayingInfoCenter supports the setting of the track title as well as album art image in both the lock screen and the remote playback controls.To check whether MPNowPlayingInfoCenter is available, try this:-
if ([MPNowPlayingInfoCenter class]) {
UIImage *albumArtImg = [UIImage imageNamed:#"abc.png"];
albumArt = [[MPMediaItemArtwork alloc] initWithImage:albumArtImg];
NSDictionary *dictCurrentlyPlaying = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:#"Temporary", [NSNumber numberWithInt:22], albumArt, nil] forKeys:[NSArray arrayWithObjects:MPMediaItemPropertyTitle, MPMediaItemPropertyPlaybackDuration, MPMediaItemPropertyArtwork, nil]];
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = dictCurrentlyPlaying;
}
Updated:- Please have a look at these:-1. http://jaysonlane.net/tech-blog/2012/04/lock-screen-now-playing-with-mpnowplayinginfocenter/2. How to set the title when playing music in background on iPhone?

iOS 7 rewind songs on lock screen using AVPlayer

I havn't found the way how to rewind song from lock screen iOS 7. Volume slider is available, all the buttons work correctly but the upper slider is not available!
AVPlayer is the class I'm using.
Any help is appreciated!
You'll need to set this in the "now-playing info".
Whenever the item (track) changes, do something like
NSMutableDictionary *nowPlayingInfo = [[NSMutableDictionary alloc] init];
[nowPlayingInfo setObject:track.artistName forKey:MPMediaItemPropertyArtist];
[nowPlayingInfo setObject:track.trackTitle forKey:MPMediaItemPropertyTitle];
...
[nowPlayingInfo setObject:[NSNumber numberWithDouble:self.player.rate] forKey:MPNowPlayingInfoPropertyPlaybackRate];
[nowPlayingInfo setObject:[NSNumber numberWithDouble:self.currentPlaybackTime] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = nowPlayingInfo;
Whenever the playback rate changes (play/pause), do
NSMutableDictionary *nowPlayingInfo = [[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo mutableCopy];
[nowPlayingInfo setObject:[NSNumber numberWithDouble:self.player.rate] forKey:MPNowPlayingInfoPropertyPlaybackRate];
[nowPlayingInfo setObject:[NSNumber numberWithDouble:self.currentPlaybackTime] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = nowPlayingInfo;
You can get the current playback time like this:
- (NSTimeInterval)currentPlaybackTime {
CMTime time = self.player.currentTime;
if (CMTIME_IS_VALID(time)) {
return time.value / time.timescale;
}
return 0;
}
You have to register for different events like below in swift
MPRemoteCommandCenter.shared().playCommand.addTarget(self, action: #selector(self.handleRemoteCommandActions))
MPRemoteCommandCenter.shared().nextTrackCommand.addTarget(self, action: #selector(self.handleRemoteCommandActions))
MPRemoteCommandCenter.shared().previousTrackCommand.addTarget(self, action: #selector(self.handleRemoteCommandActions))
MPRemoteCommandCenter.shared().stopCommand.addTarget(self, action: #selector(self.handleRemoteCommandActions))
MPRemoteCommandCenter.shared().pauseCommand.addTarget(self, action: #selector(self.handleRemoteCommandActions))
MPRemoteCommandCenter.shared().changePlaybackPositionCommand.isEnabled = true
MPRemoteCommandCenter.shared().changePlaybackPositionCommand.addTarget(self, action: #selector(self.handleChangePlaybackPositionRemoteCommandActions))
let rcc = MPRemoteCommandCenter.shared()
let skipBackwardIntervalCommand: MPSkipIntervalCommand? = rcc.skipBackwardCommand
skipBackwardIntervalCommand?.isEnabled = false
let skipForwardIntervalCommand: MPSkipIntervalCommand? = rcc.skipForwardCommand
skipForwardIntervalCommand?.isEnabled = false
let seekForwardCommand: MPRemoteCommand? = rcc.seekForwardCommand
seekForwardCommand?.isEnabled = true
rcc.changePlaybackPositionCommand.isEnabled = true
rcc.changePlaybackRateCommand.isEnabled = true
rcc.ratingCommand.isEnabled = true
rcc.playCommand.isEnabled = true
rcc.togglePlayPauseCommand.isEnabled = true
here handleChangePlaybackPositionRemoteCommandActions this method will be your method which will have to manage seeking of song when scrubber (upper slider) changes its value
it will look something like below:-
#objc func handleChangePlaybackPositionRemoteCommandActions(event:MPChangePlaybackPositionCommandEvent) -> MPRemoteCommandHandlerStatus
{
print("handleChangePlaybackPositionRemoteCommandActions : \(event.positionTime)")
self.appDelegate.audioPlayer?.seek(to: CMTime(seconds: event.positionTime, preferredTimescale: (self.appDelegate.audioPlayer?.currentItem?.currentTime().timescale)!))
MPNowPlayingInfoCenter.default().nowPlayingInfo![MPNowPlayingInfoPropertyElapsedPlaybackTime] = event.positionTime
return MPRemoteCommandHandlerStatus.success
}
I can not seem to find a way to add the functionality of dragging the progress bar to scrub through the currently playing song either, however getting the progress bar to show is partly covered by Chris above, but you have to pass the song's duration in as well as the other information to get the progress bar to show up. So in addition to what Chris pointed out, you need to add the following to the NSMutableDictionary:
[nowPlayingInfo setObject:[track valueForProperty: MPMediaItemPropertyPlaybackDuration]
forKey:MPMediaItemPropertyPlaybackDuration];
Also, you can handle a long press of the forward and back buttons and scroll your music. In the:
- (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent
you can look for these event subtypes:
if (receivedEvent.subtype == UIEventSubtypeRemoteControlBeginSeekingBackward){};
if (receivedEvent.subtype == UIEventSubtypeRemoteControlBeginSeekingForward){};
if (receivedEvent.subtype == UIEventSubtypeRemoteControlEndSeekingBackward){};
if (receivedEvent.subtype == UIEventSubtypeRemoteControlEndSeekingForward){};
The BeginSeekingForward and BeginSeekingBackward are triggered by long presses of the forward and back buttons respectively, and of course the EndSeekingForward and EndSeekingBackward event subtypes are when the finger is lifted off the button.
When you get these event subtypes, pass a new NSDictionary to
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo
with all of the information that was already in it (otherwise properties that you do not pass in will be cleared) plus a new MPNowPlayingInfoPropertyElapsedPlaybackTime and MPNowPlayingInfoPropertyPlaybackRate. For the rate, you decide how fast you want to scroll the audio. 1 is normal speed, negative values play backwards, so -2 is 2x normal speed in reverse. You will have to set the playback rate of the MPNowPlayingInfoCenter to be the same as the playback rate of the AVPlayer or they will not line up. This is why you want to also pass in the current time. You can get this with:
[player currentTime]
so to set the current time and rate:
[nowPlayingInfo setObject:[player currentTime]
forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
[nowPlayingInfo setObject:[[NSNumber alloc] initWithFloat:10]
forKey:MPNowPlayingInfoPropertyPlaybackRate];
and set the rate of the player with:
[player setRate:10]
This should line up both the player and the progress bar while scrolling with a 10x forward scroll speed. So you would do this when you get the BeginSeekingForward event subtype. When the scrolling ends, set the rate back to one, but still pass in the time and other information to the information center. For BeginSeekingBackward, just use a negative number for the rate.
I know this is an old post, but there was not a good solution and I ran across this thread while searching for how to get music information on to the lock screen. I was trying to implement this functionality in C# with Xamarin iOS and found a nice guide and sample Objective-C app with some of this functionality at http://www.sagorin.org/ios-playing-audio-in-background-audio/. But it did not have the scrolling functionality, nor did it make use of the information center, it just covered handling pause/play from the lock screen. I made a sample app in C# with Xamarin that demonstrates supplying info to the information center and scrolling with the back and forward buttons from the lock and control screens, which you can get here: https://github.com/jgold6/Xamarin-iOS-LockScreenAudio
I hope someone finds this helpful.
Here's how you do this thing with the timeline slider:
First of all the nowPlayingInfo must be set right. You can find how to do that anywhere (don't forget the key MPNowPlayingInfoPropertyPlaybackRate);
Second is to define the action for 'sliding':
MPChangePlaybackPositionCommand *changePlaybackPositionCommand = [[MPRemoteCommandCenter sharedCommandCenter] changePlaybackPositionCommand];
[changePlaybackPositionCommand addTarget:self action:#selector(changePlaybackPositionEvent:)];
[[MPRemoteCommandCenter sharedCommandCenter].changePlaybackPositionCommand setEnabled:YES];
Inside the action you can do some additional things, but the main thing here is
[yourPlayer seekTo:event.positionTime completionHandler:^(BOOL finished) {
[self updatePlaybackRateMetadata];
}];
updatePlaybackRateMetadata method has to update MPNowPlayingInfoPropertyElapsedPlaybackTime and MPNowPlayingInfoPropertyPlaybackRate.
A lot of time passed, but i hope this will help someone!

MPMediaItem with no artwork when bought from iTunes

I'm developing a iOS media Player using the iPodMusicPlayer. I have a UITableView with the MPMediaPickerController selector.
After buying a song from the iTunes store, the picked track has no artwork in the iPodMusicPlayer:
MPMediaPlayer* player = [MPMediaPlayer iPodMusicPlayer];
MPMediaItem*item = [player nowPlayingItem];
MPMediaItemArtwork *artwork = [item valueForProperty:MPMediaItemPropertyArtwork];
UIImage *albumCoverArt = [artwork imageWithSize:CGSizeMake(100.0f, 100.0f)];
if(albumCoverArt!=nil) {
// do something
}
else {
// nil before sync
}
After syncing with iTunes the song reveals the artwork.
Since before syncing, the iPod player shows the artwork, I think I'm missing something in the code when requesting the item to the MPMediaLibrary.
Any idea?
I am having the same issue.
Seems like when you buy a song from the iTunes store directly on your iPhone, retrieving the artwork will give you a blank image.
After syncing your phone with iTunes, solves it and then you will get the right image from MPMediaItemArtwork.
Offcourse I would suspect the right image immediately after buying from iTunes.

Resources