I have created Audio App in Xamarin.Forms, for playing audio I have used MediaManager plugin.
Now I want to make it compatible with CarPlay.
CarPlay audio apps are controlled by the MPPlayableContentManager. You are required to implement the MPPlayableContentDelegate and MPPlayableContentDatasource protocol in order to connect with CarPlay. The UI is controlled by CarPlay - all you need to do is feed it data for tabs+tables (datasource) and respond to playable items (delegate).
I have used all required CarPlay api for audio app but, the problem is:
- Not getting now playing screen in CarPlay simulator.
- How to set ArtWork in MPContentItem ?
MPPlayableContentDelegate class
public class PlayableContentDelegate : MPPlayableContentDelegate
{
public override void PlayableContentManager(MPPlayableContentManager contentManager, NSIndexPath indexPath, Action<NSError> completionHandler)
{
DispatchQueue.MainQueue.DispatchAsync(() =>
{
UIApplication.SharedApplication.BeginReceivingRemoteControlEvents();
completionHandler(null);
UIApplication.SharedApplication.EndReceivingRemoteControlEvents();
UIApplication.SharedApplication.BeginReceivingRemoteControlEvents();
});
}
[Export("playableContentManager:initiatePlaybackOfContentItemAtIndexPath:completionHandler:")]
public override void InitiatePlaybackOfContentItem(MPPlayableContentManager contentManager, NSIndexPath indexPath, Action<NSError> completionHandler)
{
try
{
DispatchQueue.MainQueue.DispatchAsync(() =>
{
UIApplication.SharedApplication.BeginReceivingRemoteControlEvents();
var itemToPlay = BaseSettingsService.CurrentPlayList[indexPath.Row];
var NowPlayingInfoCenter = MPNowPlayingInfoCenter.DefaultCenter;
MPNowPlayingInfo playingInfo = new MPNowPlayingInfo();
playingInfo.Title = itemToPlay.Title;
playingInfo.Artist = itemToPlay.Editor;
playingInfo.AlbumTitle = "1989";
playingInfo.Genre = "Pop";
playingInfo.PlaybackDuration = 231;
playingInfo.PlaybackRate = 22;
playingInfo.PersistentID = (ulong)111111;
playingInfo.PlaybackQueueIndex = 3;
playingInfo.PlaybackQueueCount = BaseSettingsService.CurrentPlayList.Count;
playingInfo.IsLiveStream = false;
playingInfo.MediaType = MPNowPlayingInfoMediaType.Audio;
NowPlayingInfoCenter.NowPlaying = playingInfo;
var id = itemToPlay.PodcastId.ToString();
string[] s1 = new string[1];
s1[0] = id;
contentManager.NowPlayingIdentifiers = s1;
completionHandler(null);
UIApplication.SharedApplication.EndReceivingRemoteControlEvents();
});
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
public override nuint RetainCount { get; }
public override void ContextUpdated(MPPlayableContentManager contentManager, MPPlayableContentManagerContext context)
{
try
{
//base.ContextUpdated(contentManager, context);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
public override NSDictionary GetDictionaryOfValuesFromKeys(NSString[] keys)
{
return base.GetDictionaryOfValuesFromKeys(keys);
}
}
MPPlayableContentDataSource
public class AppDelegateDataSource : MPPlayableContentDataSource
{
public override MPContentItem ContentItem(NSIndexPath indexPath)
{
if (indexPath.Length == 1)
{
var item = new MPContentItem("PlayList");
item.Title = "PlayList";
item.Subtitle = "Hello";
item.Container = true;
item.Playable = false;
return item;
}
else
{
var play = CurrentPlayList[indexPath.Row];
var item = new MPContentItem(play.PodcastId);
item.Title = play.Title;
item.Subtitle = play.Editor;
item.Playable = true;
return item;
}
}
public override nint NumberOfChildItems(NSIndexPath indexPath)
{
if (indexPath.GetIndexes().Length == 0)
return 1;
else
return CurrentPlayList.Count;
}
}
So, the question is How should I respond to playable items now?
Anyone know what I'm missing or which mistake I have to correct? Any help would be appreciated, thanks.
beginReceivingRemoteControlEvents()
andendReceivingRemoteControlEvents()
. As for the audio session, you need to get the currentAVAudioSession.sharedInstance()
and then at least set a configuration (setConfiguration()
and set it active (setActive()
), otherwise iOS will not pass any audio through. – Ghastly