In my app, I am using the CastCompanionLibrary to cast videos to a chromecast device. I want to perform some action when the video has finished playing. How do I determine as to when the video has completed playing? I did not find any suitable callback for this.
Register a VideoCastConsumer that implements onRemoteMediaPlayerStatusUpdated(). This will inform you when the playback status changes.
In that callback, get the mediaStatus = mCastManager.getMediaStatus(); this will give you the updated status.
If mediaStatus == MediaStatus.PLAYER_STATE_IDLE and mCastManager.getIdleReason() == MediaStatus.IDLE_REASON_FINISHED, then it means the currently playing item is just finished.
Note that a version of this is already being done in the associated fragment so please tell us what you are doing exactly; what I suggested allows you to generically find out when the playback of a single media items reaches its end.
Related
I am trying to report the approximate position of a live stream to our sender apps (user is able to seek around our "live" streams so they are not always at the live edge).
Specifically for Android the value I want to override comes back via the progress listener:
castSession?.remoteMediaClient?.addProgressListener(progressListener, 1000)
Currently this value is inaccurate for live streams and I believe it just reports the position in the current window or something.
On the receiver end I've looked into intercepting the MEDIA_STATUS event but this event does not emit frequently enough.
player.setMessageInterceptor(
cast.framework.messages.MessageType.MEDIA_STATUS,
status => {
status.currentTime = {some overridden time here};
return status;
});
Has anyone had success overriding the progress time sent to sender apps?
I suppose one solution might be using a custom callback message the emits every second?
I am using the Spotify android SDK, and I am trying to get a single song to play, and I would like to potentially play a song after the current one is completed. The issue is that after the song completes Spotify plays a random song afterwards. Is it possible to play the song and not have anything else automatically play after it?
I am simply calling the app remotes player API play function,
mSpotifyAppRemote?.getPlayerApi()?.play(uri)
#Mikee you are doing nothing wrong, Spotify messes around with track replay if you are only using the Free version, if you use Premium it will work correctly. Funny enough if you try playing by an alblum or artist that works with the Free version.
I'm not an expert but from their documentation it looks like you could watch the PlayerState. I'm also not sure when a PlayerState event would trigger but if it's coming back relatively often you could check the track value and see if it's gone to null, or another value and work using that.
Here's a Java example from their website:
// Subscribe to PlayerState
mSpotifyAppRemote.getPlayerApi()
.subscribeToPlayerState()
.setEventCallback(new Subscription.EventCallback<PlayerState>() {
public void onEvent(PlayerState playerState) {
// See what values are in playerState, might be able to determine
// if it's now randomly playing?
final Track track = playerState.track;
if (track != null) {
Log.d("MainActivity", track.name + " by " + track.artist.name);
// If the track is now different, your song has finished, stop it?
}
}
});
I've put a few extra comments in the code above that might yield some results!
After reading the documentation on Spotify's Android Media Notifications API, https://beta.developer.spotify.com/documentation/android-sdk/guides/android-media-notifications/, I successfully managed to receive the notifications metadata and it is displayed properly on my app.
However, the notifications metadata is only updated when the queue changes, when the track changes, and when playback is changed, so unless one of these three actions happens, the "positionInMs" intent extra isn't sent.
As of right now as a workaround I am simply starting a timer using the time the intent was sent, the last known playback position, and the track duration to track current playback position.
This seemed to work at first, but after further testing I've realized that the timer I set can go out of sync, if the track the user is listening to freezes because of a slow internet connection.
Any ideas to properly track the playback position, while accounting for a slow internet connection? Or are there any alternatives I should look into?
I understand that this question is rather old, but I am going to answer anyway if anyone else comes across it.
I recommend constantly querying Spotify to get the playback position. One way you can do this is by using a timer and querying Spotify every given time frame. The below example queries Spotify every 100ms. If you want to reduce/increase the numbers of queries, you can simply use stopwatch.setClockDelay() and provide your required time
For instance, you can use this timer library
implementation 'com.yashovardhan99.timeit:timeit:1.2.0'
Then use the following code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spotify);
Stopwatch stopwatch = new Stopwatch();
stopwatch.setOnTickListener(this);
stopwatch.start();
}
#Override
public void onTick(Stopwatch stopwatch) {
Data.getAndroidSpotifyAppRemote().getPlayerApi().getPlayerState().setResultCallback(new CallResult.ResultCallback<PlayerState>() {
#Override
public void onResult(PlayerState playerState) {
Log.d("TAG", playerState.playbackPosition);
}
});
}
Don't forget to add the following code at the top of your class:
implements Stopwatch.OnTickListener
I want to get the start and end position in Millisecond after à seek.
Actually, I get:
mYouTubePlayer.setPlaybackEventListener(new YouTubePlayer.PlaybackEventListener() {
#Override
public void onSeekTo(int endPositionMillis) {
Log.i("SEEK CURRENT MILLIS", String.valueOf(mYouTubePlayer.getCurrentTimeMillis()));
Log.i("SEEK ENDPOS MILLIS", String.valueOf(endPositionMillis));
}
}
The problem is when the user move the cursor from the timeline, an event onSeekTo is launch, and when I'm inside my onSeekTo methode, I only got the endPositionMillis, but there is no way to get the timer/position before the seek.
If you are referring to the endTime of the video, use the getDurationMillis(). For getting the current time use getCurrentTimeMillis() which you are already using then to go to a specific time of the video use either seekRelativeMillis() or seekToMillis(). With regard to your video not pausing before seeking to a specified time, it will still depend on your implementation if you want to pause the video before going to seeking to that time then playing it.
You can also check this related SO post (using web).
Hope this helps.
I initialized my TrackPlayer like this :
trackPlayer = new TrackPlayer((Application) context.getApplicationContext(), deezerConnect, new WifiAndMobileNetworkStateChecker());
trackPlayer.playTrack(trackId);
Then, I want to seek into the track with this code :
if (trackPlayer != null && trackPlayer.isAllowedToSeek()) {
trackPlayer.seek(newPositionInMs);
}
I get this error :
java.lang.IllegalStateException: Unable to retrieve AudioTrack pointer for getSampleRate()
at android.media.AudioTrack.native_get_playback_rate(Native Method)
If everyone can help me,
Thanks
This issue might happen if you try to seek too soon. When you call playTrack(), the player needs to fetch the requested track information, and download the track, which means that the player might not be initialised yet when you call the seek method.
You might want to wait for the player to be in the READY or PLAYING state before seeking.
To do so, just add a PlayerStateChangedListener on your player.