首页 > 解决方案 > 如何在 CarPlay Xamarin.iOS 中制作 NowPlay 屏幕?以及如何在 MPPlayableContentManager 中设置 nowPlayingIdentifiers 属性?

问题描述

我在 Xamarin.Forms 中创建了音频应用程序,用于播放音频我使用了 MediaManager 插件。

现在我想让它与 CarPlay 兼容。

CarPlay 音频应用由 MPPlayableContentManager 控制。您需要实现 MPPlayableContentDelegate 和 MPPlayableContentDatasource 协议才能与 CarPlay 连接。UI 由 CarPlay 控制——您需要做的就是为它提供选项卡+表格(数据源)的数据并响应可播放项目(委托)。

我已经为音频应用程序使用了所有必需的 CarPlay api,但问题是:

MPPlayableContentDelegate 类

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;
    }
}

所以,问题是我现在应该如何应对可玩项目?

任何人都知道我错过了什么或我必须纠正哪个错误?任何帮助将不胜感激,谢谢。

标签: c#xamarinxamarin.formsxamarin.ioscarplay

解决方案


要获得 NowPlaying 屏幕,您必须设置两件事。

  1. MP远程指挥中心
var commandCenter = MPRemoteCommandCenter.Shared;
commandCenter.PlayCommand.Enabled = true;
commandCenter.StopCommand.Enabled = true;
  1. MPPlayableContentManager.NowPlayingIdentifiers
var urlId = "11111";
string[] identifier = new string[1];
identifier[0] = urlId;

contentManager = MPPlayableContentManager.Shared;
contentManager.NowPlayingIdentifiers = identifier;

推荐阅读