void UpdateMetadata() { if (!QueueHelper.isIndexPlayable(currentIndexOnQueue, playingQueue)) { LogHelper.Error(Tag, "Can't retrieve current metadata."); UpdatePlaybackState(Resources.GetString(Resource.String.error_no_metadata)); return; } var queueItem = playingQueue [currentIndexOnQueue]; var musicId = MediaIDHelper.ExtractMusicIDFromMediaID( queueItem.Description.MediaId); var track = musicProvider.GetMusic(musicId); var trackId = track.GetString(MediaMetadata.MetadataKeyMediaId); if (musicId != trackId) { var e = new InvalidOperationException("track ID should match musicId."); LogHelper.Error(Tag, "track ID should match musicId.", " musicId=", musicId, " trackId=", trackId, " mediaId from queueItem=", queueItem.Description.MediaId, " title from queueItem=", queueItem.Description.Title, " mediaId from track=", track.Description.MediaId, " title from track=", track.Description.Title, " source.hashcode from track=", track.GetString( MusicProvider.CustomMetadataTrackSource).GetHashCode(), e); throw e; } LogHelper.Debug(Tag, "Updating metadata for MusicID= " + musicId); session.SetMetadata(track); // Set the proper album artwork on the media session, so it can be shown in the // locked screen and in other places. if (track.Description.IconBitmap == null && track.Description.IconUri != null) { var albumUri = track.Description.IconUri.ToString(); AlbumArtCache.Instance.Fetch(albumUri, new AlbumArtCache.FetchListener { OnFetched = (artUrl, bitmap, icon) => { var qItem = playingQueue [currentIndexOnQueue]; var trackItem = musicProvider.GetMusic(trackId); trackItem = new MediaMetadata.Builder(trackItem) .PutBitmap(MediaMetadata.MetadataKeyAlbumArt, bitmap) .PutBitmap(MediaMetadata.MetadataKeyDisplayIcon, icon) .Build(); musicProvider.UpdateMusic(trackId, trackItem); // If we are still playing the same music var currentPlayingId = MediaIDHelper.ExtractMusicIDFromMediaID( qItem.Description.MediaId); if (trackId == currentPlayingId) { session.SetMetadata(trackItem); } } }); } }
void LoadChildrenImpl(string parentId, Result result) { LogHelper.Debug(Tag, "OnLoadChildren: parentMediaId=", parentId); var mediaItems = new JavaList <MediaBrowser.MediaItem> (); if (MediaIDHelper.MediaIdRoot == parentId) { LogHelper.Debug(Tag, "OnLoadChildren.ROOT"); mediaItems.Add(new MediaBrowser.MediaItem( new MediaDescription.Builder() .SetMediaId(MediaIDHelper.MediaIdMusicsByGenre) .SetTitle(GetString(Resource.String.browse_genres)) .SetIconUri(Android.Net.Uri.Parse("android.resource://" + "com.example.android.mediabrowserservice/drawable/ic_by_genre")) .SetSubtitle(GetString(Resource.String.browse_genre_subtitle)) .Build(), MediaItemFlags.Browsable )); } else if (MediaIDHelper.MediaIdMusicsByGenre == parentId) { LogHelper.Debug(Tag, "OnLoadChildren.GENRES"); foreach (var genre in musicProvider.Genres) { var item = new MediaBrowser.MediaItem( new MediaDescription.Builder() .SetMediaId(MediaIDHelper.CreateBrowseCategoryMediaID(MediaIDHelper.MediaIdMusicsByGenre, genre)) .SetTitle(genre) .SetSubtitle(GetString(Resource.String.browse_musics_by_genre_subtitle, genre)) .Build(), MediaItemFlags.Browsable ); mediaItems.Add(item); } } else if (parentId.StartsWith(MediaIDHelper.MediaIdMusicsByGenre)) { var genre = MediaIDHelper.GetHierarchy(parentId) [1]; LogHelper.Debug(Tag, "OnLoadChildren.SONGS_BY_GENRE genre=", genre); foreach (var track in musicProvider.GetMusicsByGenre(genre)) { var hierarchyAwareMediaID = MediaIDHelper.CreateMediaID( track.Description.MediaId, MediaIDHelper.MediaIdMusicsByGenre, genre); var trackCopy = new MediaMetadata.Builder(track) .PutString(MediaMetadata.MetadataKeyMediaId, hierarchyAwareMediaID) .Build(); var bItem = new MediaBrowser.MediaItem( trackCopy.Description, MediaItemFlags.Playable); mediaItems.Add(bItem); } } else { LogHelper.Warn(Tag, "Skipping unmatched parentMediaId: ", parentId); } LogHelper.Debug(Tag, "OnLoadChildren sending ", mediaItems.Count, " results for ", parentId); result.SendResult(mediaItems); }
public void Play(MediaSession.QueueItem item) { playOnFocusGain = true; TryToGetAudioFocus(); RegisterAudioNoisyReceiver(); string mediaId = item.Description.MediaId; bool mediaHasChanged = mediaId != currentMediaId; if (mediaHasChanged) { currentPosition = 0; currentMediaId = mediaId; } if (State == PlaybackStateCode.Paused && !mediaHasChanged && mediaPlayer != null) { ConfigMediaPlayerState(); } else { State = PlaybackStateCode.Stopped; RelaxResources(false); MediaMetadata track = musicProvider.GetMusic( MediaIDHelper.ExtractMusicIDFromMediaID(item.Description.MediaId)); string source = track.GetString(MusicProvider.CustomMetadataTrackSource); try { CreateMediaPlayerIfNeeded(); State = PlaybackStateCode.Buffering; mediaPlayer.SetAudioStreamType(Android.Media.Stream.Music); mediaPlayer.SetDataSource(source); mediaPlayer.PrepareAsync(); wifiLock.Acquire(); if (Callback != null) { Callback.OnPlaybackStatusChanged(State); } } catch (IOException ex) { LogHelper.Error(Tag, ex, "Exception playing song"); if (Callback != null) { Callback.OnError(ex.Message); } } } }
MediaMetadata GetCurrentPlayingMusic() { if (QueueHelper.isIndexPlayable(currentIndexOnQueue, playingQueue)) { var item = playingQueue [currentIndexOnQueue]; if (item != null) { LogHelper.Debug(Tag, "getCurrentPlayingMusic for musicId=", item.Description.MediaId); return(musicProvider.GetMusic( MediaIDHelper.ExtractMusicIDFromMediaID(item.Description.MediaId))); } } return(null); }
static List <MediaSession.QueueItem> ConvertToQueue(IEnumerable <MediaMetadata> tracks, params string[] categories) { var queue = new List <MediaSession.QueueItem>(); int count = 0; foreach (var track in tracks) { string hierarchyAwareMediaID = MediaIDHelper.CreateMediaID(track.Description.MediaId, categories); MediaMetadata trackCopy = new MediaMetadata.Builder(track) .PutString(MediaMetadata.MetadataKeyMediaId, hierarchyAwareMediaID) .Build(); var item = new MediaSession.QueueItem(trackCopy.Description, count++); queue.Add(item); } return(queue); }
public static List <MediaSession.QueueItem> GetPlayingQueue(string mediaId, MusicProvider musicProvider) { // extract the browsing hierarchy from the media ID: var hierarchy = MediaIDHelper.GetHierarchy(mediaId); if (hierarchy.Length != 2) { LogHelper.Error(Tag, "Could not build a playing queue for this mediaId: ", mediaId); return(null); } var categoryType = hierarchy[0]; var categoryValue = hierarchy[1]; LogHelper.Debug(Tag, "Creating playing queue for ", categoryType, ", ", categoryValue); IEnumerable <MediaMetadata> tracks = null; // This sample only supports genre and by_search category types. if (categoryType == MediaIDHelper.MediaIdMusicsByGenre) { tracks = musicProvider.GetMusicsByGenre(categoryValue); } else if (categoryType == MediaIDHelper.MediaIdMusicsBySearch) { tracks = musicProvider.SearchMusic(categoryValue); } if (tracks == null) { LogHelper.Error(Tag, "Unrecognized category type: ", categoryType, " for mediaId ", mediaId); return(null); } return(ConvertToQueue(tracks, hierarchy[0], hierarchy[1])); }
public override void OnCreate() { base.OnCreate(); LogHelper.Debug(Tag, "onCreate"); playingQueue = new List <MediaSession.QueueItem> (); musicProvider = new MusicProvider(); packageValidator = new PackageValidator(this); session = new MediaSession(this, "MusicService"); SessionToken = session.SessionToken; var mediaCallback = new MediaSessionCallback(); mediaCallback.OnPlayImpl = () => { LogHelper.Debug(Tag, "play"); if (playingQueue == null || playingQueue.Count != 0) { playingQueue = new List <MediaSession.QueueItem> (QueueHelper.GetRandomQueue(musicProvider)); session.SetQueue(playingQueue); session.SetQueueTitle(GetString(Resource.String.random_queue_title)); currentIndexOnQueue = 0; } if (playingQueue != null && playingQueue.Count != 0) { HandlePlayRequest(); } }; mediaCallback.OnSkipToQueueItemImpl = (id) => { LogHelper.Debug(Tag, "OnSkipToQueueItem:" + id); if (playingQueue != null && playingQueue.Count != 0) { currentIndexOnQueue = QueueHelper.GetMusicIndexOnQueue(playingQueue, id); HandlePlayRequest(); } }; mediaCallback.OnSeekToImpl = (pos) => { LogHelper.Debug(Tag, "onSeekTo:", pos); playback.SeekTo((int)pos); }; mediaCallback.OnPlayFromMediaIdImpl = (mediaId, extras) => { LogHelper.Debug(Tag, "playFromMediaId mediaId:", mediaId, " extras=", extras); playingQueue = QueueHelper.GetPlayingQueue(mediaId, musicProvider); session.SetQueue(playingQueue); var queueTitle = GetString(Resource.String.browse_musics_by_genre_subtitle, MediaIDHelper.ExtractBrowseCategoryValueFromMediaID(mediaId)); session.SetQueueTitle(queueTitle); if (playingQueue != null && playingQueue.Count != 0) { currentIndexOnQueue = QueueHelper.GetMusicIndexOnQueue(playingQueue, mediaId); if (currentIndexOnQueue < 0) { LogHelper.Error(Tag, "playFromMediaId: media ID ", mediaId, " could not be found on queue. Ignoring."); } else { HandlePlayRequest(); } } }; mediaCallback.OnPauseImpl = () => { LogHelper.Debug(Tag, "pause. current state=" + playback.State); HandlePauseRequest(); }; mediaCallback.OnStopImpl = () => { LogHelper.Debug(Tag, "stop. current state=" + playback.State); HandleStopRequest(null); }; mediaCallback.OnSkipToNextImpl = () => { LogHelper.Debug(Tag, "skipToNext"); currentIndexOnQueue++; if (playingQueue != null && currentIndexOnQueue >= playingQueue.Count) { currentIndexOnQueue = 0; } if (QueueHelper.isIndexPlayable(currentIndexOnQueue, playingQueue)) { HandlePlayRequest(); } else { LogHelper.Error(Tag, "skipToNext: cannot skip to next. next Index=" + currentIndexOnQueue + " queue length=" + (playingQueue == null ? "null" : playingQueue.Count.ToString())); HandleStopRequest("Cannot skip"); } }; mediaCallback.OnSkipToPreviousImpl = () => { LogHelper.Debug(Tag, "skipToPrevious"); currentIndexOnQueue--; if (playingQueue != null && currentIndexOnQueue < 0) { currentIndexOnQueue = 0; } if (QueueHelper.isIndexPlayable(currentIndexOnQueue, playingQueue)) { HandlePlayRequest(); } else { LogHelper.Error(Tag, "skipToPrevious: cannot skip to previous. previous Index=" + currentIndexOnQueue + " queue length=" + (playingQueue == null ? "null" : playingQueue.Count.ToString())); HandleStopRequest("Cannot skip"); } }; mediaCallback.OnCustomActionImpl = (action, extras) => { if (CustomActionThumbsUp == action) { LogHelper.Info(Tag, "onCustomAction: favorite for current track"); var track = GetCurrentPlayingMusic(); if (track != null) { var musicId = track.GetString(MediaMetadata.MetadataKeyMediaId); musicProvider.SetFavorite(musicId, !musicProvider.IsFavorite(musicId)); } UpdatePlaybackState(null); } else { LogHelper.Error(Tag, "Unsupported action: ", action); } }; mediaCallback.OnPlayFromSearchImpl = (query, extras) => { LogHelper.Debug(Tag, "playFromSearch query=", query); if (string.IsNullOrEmpty(query)) { playingQueue = new List <MediaSession.QueueItem> (QueueHelper.GetRandomQueue(musicProvider)); } else { playingQueue = new List <MediaSession.QueueItem> (QueueHelper.GetPlayingQueueFromSearch(query, musicProvider)); } LogHelper.Debug(Tag, "playFromSearch playqueue.length=" + playingQueue.Count); session.SetQueue(playingQueue); if (playingQueue != null && playingQueue.Count != 0) { currentIndexOnQueue = 0; HandlePlayRequest(); } else { HandleStopRequest(GetString(Resource.String.no_search_results)); } }; session.SetCallback(mediaCallback); session.SetFlags(MediaSessionFlags.HandlesMediaButtons | MediaSessionFlags.HandlesTransportControls); playback = new Playback(this, musicProvider); playback.State = PlaybackStateCode.None; playback.Callback = this; playback.Start(); var context = ApplicationContext; var intent = new Intent(context, typeof(MusicPlayerActivity)); var pi = PendingIntent.GetActivity(context, 99 /*request code*/, intent, PendingIntentFlags.UpdateCurrent); session.SetSessionActivity(pi); var extraBundle = new Bundle(); CarHelper.SetSlotReservationFlags(extraBundle, true, true, true); session.SetExtras(extraBundle); UpdatePlaybackState(null); mediaNotificationManager = new MediaNotificationManager(this); }