I have built an application that uses Cast Companion Library (CCL) to remotely play video to cast comparable devices. Every thing is working find but I need to be able to change video files and not kill and restart the activity and fragment.
I have implemented my own custom version of the VideoCastControllerActivity that implements the same interface but I am re-using the VideoCastControllerFragment that CCL comes with. One problem is that the VideoCastControllerFragment does not really give specific notice when the end of a video file is reached. It somewhat does by calling closeActivity() from the IVideoCastController interface so I tried to use that event to know when to load the next video file. But loading the next video file by calling
getCastManager().loadMedia( mSelectedMedia, autoPlay, position );
but doing that results in another call to close activity and a loop until the end of the playlist is reached without playing any video.
Is there another way to go about this without re-writing my own VideoCastControllerFragment?
To answer your first question (or observation), you can listen to various callback events directly in your implementation of VideoCastControllerActivity; you have access to the VideoCastManager so you know when your media status goes to IDLE with the reason FINISHED. Outside of that, you seem to be trying to implement some sort of playlist functionality in your sender while the right place for that is on the receiver (i.e. you need to write a custom receiver); if your playlist knowledge/logic lives on your phone, then the whole thing becomes dependent on your phone so if it goes to sleep, you chromecast doesn't know what to do. In addition, if a second device connects to the same cast device, it cannot correctly reflect the playlist, etc. So a phone device can let user form a playlist and then it has to send the information about that playlist to your custom receiver and your custom receiver should handle playing them in queue and your sender(s) should be able to send custom messages to move to the next/prev, etc and your receiver should do the right thing accordingly. We have a very rudimentary sample on our GitHub repo that shows how you can do video playlist on the receiver.
Related
I am developing an app that mirrors the player state of third party player apps for studying reasons.
I managed to get to know how to control the other players playback state through the AudioManager API, but I'm clueless when it comes to know how to fetch any of the other players' current song info, like:
song name;
artist name, and;
current song position.
Is there anything one can do to fetch this data from Android?
From my research, I only found one way to do that but that unfortunately requires the device to be running Android >= 21 (Lollipop) and a special permission from the user (android.permission.BIND_NOTIFICATION_LISTENER_SERVICE)
It is possible to know which media is playing on the device using the MediaSessionManager. To do that, all we need is to fetch the active MediaControllers in two ways:
MediaSessionManager#getActiveSessions(...), and;
MediaSessionManager#addOnActiveSessionsChangedListener(...).
With the active MediaControllers in hands, we can get the info we want from them through its available functions. It is good to point out that each player fills its Media Session data the way they want, so it's very possible that one has almost or no useful data at all, and another has a large amount of it (which is the case of the Google Play Music App).
Some functions of the MediaController class that we can highlight are:
MediaController#getMetaData
MediaController#getPlayerState;
MediaController#getQueue, and;
MediaController#getQueueTitle.
It is good to notice that players can put custom data into MediaController#getMetaData bundle. Google Play Music, for instance, adds two of them:
"com.google.android.music.mediasession.METADATA_KEY_QUEUE_SIZE", and;
"com.google.android.music.mediasession.METADATA_KEY_QUEUE_POSITION".
Debugging might be your best friend to get to know them.
Another fancy way to achieve that is through the use of MediaBrowserService. A detailed reading can be done in this article.
If you know a better way to do this, specially if it does not require the android.permission.BIND_NOTIFICATION_LISTENER_SERVICE permission, you are more than welcome to contribute :)
I want to start chromecast routing automatically and not when the user presses the button. Does anyone know how i can simulate in any way that the user pressed the media route button? I have looked through the different classes and not found anything.
I am aware that this is not how Google intends developers to use it, and my application is only functioning as a proof of concept.
If anyone knows another way to achieve the same thing (The casting starts when the app starts, if the user has enabled it in the options menu) - let me know!
You can follow the same steps as usual (get a hold of MediaRouter instance, set a selector, register a callback, etc) but then you need to keep a list of discovered routes in your application (as they are discovered by MediaRouter; you will get a call back via onRouteAdded(()). You need to do the bookkeeping as well (via onRouteRemoved() callback). Now that you have a list of routes, you can programmatically decide which one is the one you want to use and again do as usual (same stuff that you would do when you get a callback via onRouteSelected()) except that you need to call MediaRouter.selectRoute(your_selected_route) yourself to tell the framework about it. For the first part, you can take a look at this sample.
So what I discovered was that I couldn't make a check for routes in the beginning of the program because the MediaRouter hadn't discovered them yet. (I.e the call to getRoutes returned only the default route...) In my program, it was enough to start a thread that sleeps for three seconds and then calls selects any available route:
if(mMediaRouter.getRoutes().size() >= 1) {
mMediaRouter.selectRoute(mMediaRouter.getRoutes().get(1));
}
If I needed a more persistent solution, I'd do as Ali Naddaf suggested.
Currently there is no MedaiStatus.PLAYER_STATE_LOADING state to tell if the video is being loaded to the chromecast device.
Is there a way i can ask the GoogleCast device if I am loading data, as apposed to Buffering, Idle, Playing, or Paused?
We don't have such event exposed through the SDK. There is a couple of nice diagrams here that show the flow and events that are captured (see section Media Events). If there is a any reason that you need a certain event (exposed by MediaElement) that are not exposed through the SDK, you should consider doing the following:
Listen to that event on the MediaElement directly and inform your senders accordingly. The receiver SDK does exactly the same thing; it gets all its media events from the media element.
Open a feature request on our SDK tracker. There, you need to explain in detail why you need that feature and basically build a case that shows it is a valuable feature not just for your particular case, but in general.
I am working on live radio app.
I parse list of channels and show in list view , My problem is when i click on particular channel first time than it plays that channel according to assign link. but when you go out of application and come back and again you click on same channel (Which is playing currently ) it restart the media-player and start playing it again.
so to solve this problem i used manifest "singleTask" to solve this problem.But now when i try to click another link ( other than currently playing) than it wont play the current selected channel from Listview item and its assign link..
So can anybody please tell me How can i have code for activity and service to solve this problem , I am student so i don't have much experience.
Also I am checking for internet if you are connected to internet than it parse the json otherwise it will show message but it only check once when you start your application So how can i check net connection background?
Thank you
You need to set up a Service to play music in background.
There is a sample project called RandomMusicPlayer embedded with the SDK which could help you a lot to achieve it. (In Eclipse: New Project > Android > Android Sample Project)
Move your player to the Service, bind it in activity a send commands from your activity, there is plenty tutorials for this.
Similar question
Service activity communication
Service media player
I need to call setVolumeControlStream from a service that plays some sound via STREAM_SYSTEM.
Obviously in an Activity that is no problem, but how can I do this with a service?
From the looks of it, this isn't possible the way you are trying to do it.
As said in the android reference
The suggested audio stream will be tied to the window of this Activity
Hence with a service that has no activity, there is no window to tie the audio stream to.
However, It looks like you should be able to receive media key events (including volume keys) from a broadcaster as shown here which would allow you to change your service volume without an activity being visible.
I think this library can provide you what you need:
http://code.google.com/p/media-volume-control/