Is there any way to use extras with the MediaMetadataCompat from the support library?
Using the MediaMetadata I can set extras, but with the compat one I cannot.
Hope it helps.
import android.support.v4.media.session.MediaSessionCompat;
private MediaSessionCompat mMediaSession;
//init mediasesson
mMediaSession = new MediaSessionCompat(getApplicationContext(), "AudioPlayer",new ComponentName(this, HeadsetNotificationBroadcast.class), null);
//set the metadata
mMediaSession.setMetadata(new MediaMetadataCompat.Builder()
.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, getSongDataHelper().getAlbumArt())
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, getSongDataHelper().getArtist())
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, getSongDataHelper().getAlbum())
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, getSongDataHelper().getTitle())
.build());
I have copy-pasted our code. Please tell me if you can understand it.
private static MediaInfo toCastMediaMetadata(MediaMetadataCompat track, JSONObject customData) {
MediaMetadata mediaMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MUSIC_TRACK);
mediaMetadata.putString(MediaMetadata.KEY_TITLE, track.getDescription().getTitle().toString());
mediaMetadata.putString(MediaMetadata.KEY_SUBTITLE, track.getDescription().getSubtitle().toString());
mediaMetadata.putString(MediaMetadata.KEY_ALBUM_ARTIST, track.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST));
mediaMetadata.putString(MediaMetadata.KEY_ALBUM_TITLE, track.getString(MediaMetadataCompat.METADATA_KEY_ALBUM));
WebImage image = new WebImage(new Uri.Builder().encodedPath(track.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI)).build());
// First image is used by the receiver for showing the audio album art.
mediaMetadata.addImage(image);
// Second image is used by Cast Companion Library on the full screen activity that is shown
// when the cast dialog is clicked.
mediaMetadata.addImage(image);
return new MediaInfo.Builder(
track.getDescription().getExtras().getString(MutableMediaMetadataCompat.
METADATA_KEY_TRACK_SOURCE)).setContentType(
MIME_TYPE_AUDIO_MPEG).setStreamType(MediaInfo.STREAM_TYPE_BUFFERED).setMetadata(mediaMetadata).setCustomData(customData).build();
}
Related
I would like my notifications to include the contact's image.
I am using NotificationCompat and MessagingStyle do display chat messages for contacts.
This works when using the .setIcon on the person, but the image is square, so I would like to use the setUri but it doesn't display the image, instead I see the contact's first initial in a circle.
Here is the code I'm using for the notification.
Person person = new Person.Builder()
// .setIcon(contactIcon)
.setName(displayName)
.setUri(contentLookupURI)
.setKey(contactDetail)
.build();
NotificationCompat.MessagingStyle chatMessageStyle = new NotificationCompat.MessagingStyle(person);
NotificationCompat.MessagingStyle.Message notificationMessage = new
NotificationCompat.MessagingStyle.Message(
contentText,
System.currentTimeMillis(),
person
);
chatMessageStyle.addMessage(notificationMessage);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, NOTIFICATION_MESSAGES_CHANNEL_ID)
.setSmallIcon(icon) // notification icon
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setStyle(chatMessageStyle)
.setOnlyAlertOnce(true)
.setContentTitle(displayName);
And for the contact URI used in the .setUri I'm using a library to obtain the contact id and lookupkey then use the method:
contactLookupURI =
ContactsContract.Contacts.getLookupUri(contactsList.get(0).getId(),
contactsList.get(0).getLookupKey());
Which produces this: content://com.android.contacts/contacts/lookup/3118r4-2F294339313F5B16.3789r5-2F294339313F5B16/6 which looks correct to me.
I'm not sure how new this form of the MessagingStyle method is as I can't find many examples of it's usage with a Person object.
Here is a solution for those using Remote URL with Glide
Step 1: Get Bitmap from Remote URL
private fun getAvatarFromUrl(photoUrl: String): Bitmap? {
return try {
val futureTarget = Glide.with(this)
.asBitmap()
.load(photoUrl)
.submit()
futureTarget.get()
} catch (e: Exception) {
Timber.e(e)
null
}
}
Step 2: Set Bitmap as Person.Icon
val avatar = getAvatarFromUrl(user.avatar)
val sender = Person.Builder()
.setName(msg.from?.name)
.setIcon(IconCompat.createWithBitmap(avatar))
.setImportant(true)
.build()
If you want to use resource id instead of bitmap:
val person = Person.Builder()
.setName("Name")
.setKey("Key")
.setIcon(IconCompat.createWithResource(this, R.drawable.ic_resource)).build()
My application has Videos, Audios and Photos. I'm successfully able to cast all three of them. However when I cast an image, the minicontrollerfragment, Notification and ExpandedControllerActivity shows video controls.
When I click play/pause button it just keeps spinning round for photo.
Is there a way where I can disable it for images? I looked up everywhere but for some reason I was not able to find a single example of Photo.
Any help would be appreciated.
Thank you.
Here is the code for CastOptionsProvider.
#Override
public CastOptions getCastOptions(Context context) {
NotificationOptions notificationOptions = new NotificationOptions.Builder()
.setTargetActivityClassName(ExpandedControlsActivity.class.getName())
.setActions(Arrays.asList(MediaIntentReceiver.ACTION_REWIND,MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK, MediaIntentReceiver.ACTION_FORWARD, MediaIntentReceiver.ACTION_STOP_CASTING), new int[]{1,2,3})
.build();
CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.setExpandedControllerActivityClassName(ExpandedControlsActivity.class.getName())
.build();
CastOptions castOptions = new CastOptions.Builder()
.setReceiverApplicationId(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID)
.setCastMediaOptions(mediaOptions)
.build();
return castOptions;
}
This is how I cast an image:
MediaMetadata photoMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_PHOTO);
photoMetadata.putString(MediaMetadata.KEY_TITLE, "Casting to " + mCastSession.getCastDevice().getFriendlyName());
photoMetadata.addImage(new WebImage(Uri.parse(photoItem.getImageUrl())));
MediaInfo mediaInfo = new MediaInfo.Builder(photoItem.getImageUrl())
.setContentType("image/jpeg")
.setMetadata(photoMetadata)
.setStreamDuration(0)
.setStreamType(MediaInfo.STREAM_TYPE_NONE)
.build();
MediaLoadOptions mediaLoadOptions = new MediaLoadOptions.Builder()
.setAutoplay(true)
.setPlayPosition(0)
.build();
RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
remoteMediaClient.load(mediaInfo, mediaLoadOptions);
You can use Default Media Receiver (CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID) to give it a try as a default receiver, otherwise you need to create your own.
Inside your CastOptionProvider, create a CastOptions like below
new CastOptions.Builder()
.setReceiverApplicationId(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID)
.setCastMediaOptions(mediaOptions)
.build();
So I am trying to play a DASH video in a SimpleExoplayerView. I am following the most basic tutorials from https://codelabs.developers.google.com/codelabs/exoplayer-intro/#0.
The trouble is, I am able to hear the audio but the screen is always white.
Things I have already tried -
Using three different .mpd links. Can hear the audio each time and the video is white in each case. So there is no problem with the .mpd links.
Tested in different devices - an API 19 HTC Desire and an API 24 Moto G4. So I'm sure it is not a device specific issue.
Here is the initialising method -
private void initialisePlayer() {
TrackSelection.Factory adaptiveTrackSelectionFactory = new AdaptiveTrackSelection.Factory
(defaultBandwidthMeter);
if (exoPlayer == null) {
exoPlayer = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(context), new
DefaultTrackSelector(adaptiveTrackSelectionFactory), new DefaultLoadControl());
simpleExoPlayerView.setPlayer(exoPlayer);
exoPlayer.setPlayWhenReady(true);
DashMediaSource mediaSource = buildMediaResource();
exoPlayer.prepare(mediaSource);
}
}
And this is the buildMediaSource method -
private DashMediaSource buildMediaResource() {
String userAgent = Util.getUserAgent(context, getString(R.string.app_name));
DataSource.Factory manifestDataSourceFactory = new DefaultHttpDataSourceFactory(userAgent);
DashChunkSource.Factory dashChunkSourceFactory = new DefaultDashChunkSource.Factory(new
DefaultHttpDataSourceFactory(userAgent, defaultBandwidthMeter));
return new DashMediaSource.Factory(dashChunkSourceFactory, manifestDataSourceFactory).createMediaSource(Uri
.parse(url));
}
Am I missing something?
I am developing an Android app for TV using the Leanback library. I have an HLS video stream with an srt subtitle from a URI. I am using ExoPlayer version 2.5.4 as used in this example app. I created my MediaSource using:
private MediaSource onCreateMediaSource(Uri uri, Uri subtitleUri) {
String userAgent = Util.getUserAgent(mContext, "ExoPlayerAdapter");
MediaSource videoSource = new HlsMediaSource(uri,
new DefaultDataSourceFactory(mContext, userAgent),
null,
null);
Format subtitleFormat = Format.createTextSampleFormat(
"1", MimeTypes.APPLICATION_SUBRIP, 0, "en");
MediaSource subtitleSource = new SingleSampleMediaSource(
subtitleUri,
new DefaultDataSourceFactory(mContext, userAgent),
subtitleFormat, C.TIME_UNSET);
MergingMediaSource mergedSource =
new MergingMediaSource(videoSource, subtitleSource);
return mergedSource;
}
In my PlaybackTransportControlGlue, I have a PlaybackControlsRow.ClosedCaptioningAction. When this button is clicked, what do I write in the action dispatcher to toggle the closed captions?
I tried this:
#Override
public void onActionClicked(Action action) {
if (action == mClosedCaptioningAction) {
DefaultTrackSelector trackSelector = mAdapter.getTrackSelector();
int rendererIndex = 0;
if (mClosedCaptioningAction.getIndex() == PlaybackControlsRow.ClosedCaptioningAction.INDEX_ON) {
MappingTrackSelector.MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
TrackGroupArray textGroups = mappedTrackInfo.getTrackGroups(rendererIndex);
int groupIndex = 0;
trackSelector.setRendererDisabled(rendererIndex, false);
MappingTrackSelector.SelectionOverride override =
new MappingTrackSelector.SelectionOverride(mTrackFactory, groupIndex, 0);
trackSelector.setSelectionOverride(rendererIndex, textGroups, override);
} else {
trackSelector.setRendererDisabled(rendererIndex, true);
trackSelector.clearSelectionOverrides();
}
}
super.onActionClicked(action);
}
I got this error:
E/gralloc: unregister FBM buffer
Okay I just answered a question which got text tracks working in a simple way here. This works for adaptive files (like HLS), but I would have to modify it to get it working with progressive files (like an .mp4 that you've merged with an .srt file).
It's at least a starting point.
I'd like to circle back around and get it fully working for you, but I think it may be a matter of working with the track index and tweaking the override so that it doesn't use the AdaptiveFactory (from the below line).
TrackSelection.Factory factory = tracks.length == 1
? new FixedTrackSelection.Factory()
: new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
We have it fully working in our code for both HLS and progressive, but our implementation is wrapped in a lot of additional architecture which might make it even harder to understand the core components.
I am using CastCompanionLibrary-android for chromecast integration.
I am going to show few methods of chromecast integration
first one is configuration initalization in application cast
private void initchromecast() {
String applicationId = getString(R.string.app_id);
// Build a CastConfiguration object and initialize VideoCastManager
CastConfiguration options = new CastConfiguration.Builder(applicationId)
.enableAutoReconnect()
.enableCaptionManagement()
.enableDebug()
.enableLockScreen()
.enableNotification()
.enableWifiReconnection()
.setCastControllerImmersive(true)
.setLaunchOptions(false, Locale.getDefault())
.setNextPrevVisibilityPolicy(CastConfiguration.NEXT_PREV_VISIBILITY_POLICY_DISABLED)
.addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_REWIND, false)
.addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_PLAY_PAUSE, true)
.addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_DISCONNECT, true)
.setForwardStep(10)
.build();
VideoCastManager.initialize(this, options);
}
and TO pass meta data
private void loadRemoteMedia(int position, boolean autoPlay) {
MediaMetadata mediaMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MUSIC_TRACK);
mediaMetadata.putString(MediaMetadata.KEY_TITLE, TITLE);
MediaInfo mediaInfo = new MediaInfo.Builder(
path)
.setContentType("application/x-mpegURL")
.setStreamType(MediaInfo.STREAM_TYPE_LIVE)
.setMetadata(mediaMetadata)
.setStreamDuration(MediaInfo.UNKNOWN_DURATION)
.build();
mCastManager.startVideoCastControllerActivity(getActivity(), mediaInfo, position, autoPlay);
}
Now my question is in below cod when i pass CastCompanion sample id 4F8B3483 ,i can successfully cast most of the videos but when i put my sample application reciver id some of the videos which works with their id does not work with mine.
For example http://iptvcanales.com/xw/peliculas.php?movie=006 url works with CastCompanion reciver id but not with mine id in my code.