@Override public void onStateChanged(boolean playWhenReady, int playbackState) { if (playWhenReady && playbackState == ExoPlayer.STATE_READY) { notifyTracksChanged(getAllTracks()); String audioId = getTrackId(TvTrackInfo.TYPE_AUDIO, mPlayer.getSelectedTrack(TvTrackInfo.TYPE_AUDIO)); String videoId = getTrackId(TvTrackInfo.TYPE_VIDEO, mPlayer.getSelectedTrack(TvTrackInfo.TYPE_VIDEO)); String textId = getTrackId(TvTrackInfo.TYPE_SUBTITLE, mPlayer.getSelectedTrack(TvTrackInfo.TYPE_SUBTITLE)); notifyTrackSelected(TvTrackInfo.TYPE_AUDIO, audioId); notifyTrackSelected(TvTrackInfo.TYPE_VIDEO, videoId); notifyTrackSelected(TvTrackInfo.TYPE_SUBTITLE, textId); notifyVideoAvailable(); } }
private String getStateString(int state) { switch (state) { case ExoPlayer.STATE_BUFFERING: return "B"; case ExoPlayer.STATE_ENDED: return "E"; case ExoPlayer.STATE_IDLE: return "I"; case ExoPlayer.STATE_PREPARING: return "P"; case ExoPlayer.STATE_READY: return "R"; default: return "?"; } }
@Override public boolean isPlaying() { if (mInternalPlayer == null) return false; int state = mInternalPlayer.getPlaybackState(); switch (state) { case ExoPlayer.STATE_BUFFERING: case ExoPlayer.STATE_READY: return mInternalPlayer.getPlayWhenReady(); case ExoPlayer.STATE_IDLE: case ExoPlayer.STATE_PREPARING: case ExoPlayer.STATE_ENDED: default: return false; } }
@Override public void run() { switch (player.getPlaybackState()) { case ExoPlayer.STATE_BUFFERING: mlistener.onBuffering(playerControl.getBufferPercentage() + ""); break; case ExoPlayer.STATE_ENDED: mlistener.onCompletion(); break; case ExoPlayer.STATE_IDLE: break; case ExoPlayer.STATE_PREPARING: mlistener.onBufferingStarted(); break; case ExoPlayer.STATE_READY: mlistener.onBufferingFinished(); break; default: break; } mlistener.onProgressChanged((int) player.getCurrentPosition()); mainHandler.postDelayed(updatePlayer, 200); }
@MainThread public long getCurrentPosition() { // TODO: More precise time may be necessary. MpegTsPlayer mpegTsPlayer = mPlayer; long currentTime = mpegTsPlayer != null ? mRecordStartTimeMs + mpegTsPlayer.getCurrentPosition() : mRecordStartTimeMs; if (mChannel == null && mPlayerState == ExoPlayer.STATE_ENDED) { currentTime = mRecordingDuration + mRecordStartTimeMs; } if (DEBUG) { long systemCurrentTime = System.currentTimeMillis(); Log.d(TAG, "currentTime = " + currentTime + " ; System.currentTimeMillis() = " + systemCurrentTime + " ; diff = " + (currentTime - systemCurrentTime)); } return currentTime; }
private void stopPlayback() { mChannelDataManager.removeAllCallbacksAndMessages(); if (mPlayer != null) { mPlayer.setPlayWhenReady(false); mPlayer.release(); mPlayer = null; mPlayerState = ExoPlayer.STATE_IDLE; mPlaybackParams.setSpeed(1.0f); mPlayerStarted = false; mReportedDrawnToSurface = false; mPreparingStartTimeMs = INVALID_TIME; mBufferingStartTimeMs = INVALID_TIME; mReadyStartTimeMs = INVALID_TIME; mSession.sendUiMessage(TunerSession.MSG_UI_HIDE_AUDIO_UNPLAYABLE); mSession.notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_UNAVAILABLE); } }
public CustomExoPlayer(Context context) { this.context = context; this.mainHandler = new Handler(Looper.getMainLooper()); this.userAgent = Util.getUserAgent(context, "ExoPlayerDemo"); // 1. Instantiate the player. player = ExoPlayer.Factory.newInstance(2); // // 2. Construct renderers. // MediaCodecVideoTrackRenderer videoRenderer = ... // MediaCodecAudioTrackRenderer audioRenderer = ... // // 3. Inject the renderers through prepare. // player.prepare(videoRenderer, audioRenderer); // // 4. Pass the surface to the video renderer. // player.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); // // 5. Start playback. // player.setPlayWhenReady(true); }
@Override public void onPlayerStateChanged(boolean playWhenReady, int state) { switch (player.getPlaybackState()) { case ExoPlayer.STATE_BUFFERING: playerState = "buffering"; break; case ExoPlayer.STATE_ENDED: playerState = "ended"; break; case ExoPlayer.STATE_IDLE: playerState = "idle"; break; case ExoPlayer.STATE_PREPARING: playerState = "preparing"; break; case ExoPlayer.STATE_READY: playerState = "ready"; break; } updateDebugInfoTextView(); }
private static String getStateString(int state) { switch (state) { case ExoPlayer.STATE_BUFFERING: return "B"; case ExoPlayer.STATE_ENDED: return "E"; case ExoPlayer.STATE_IDLE: return "I"; case ExoPlayer.STATE_PREPARING: return "P"; case ExoPlayer.STATE_READY: return "R"; default: return "?"; } }
@Override public void run() { Looper.prepare(); player = ExoPlayer.Factory.newInstance(1); player.addListener(this); ExtractorSampleSource sampleSource = new ExtractorSampleSource( uri, new DefaultUriDataSource(context, Util.getUserAgent(context, "ExoPlayerExtVP9Test")), new DefaultAllocator(BUFFER_SEGMENT_SIZE), BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT, new WebmExtractor()); LibvpxVideoTrackRenderer videoRenderer = new LibvpxVideoTrackRenderer(sampleSource, true); player.sendMessage(videoRenderer, LibvpxVideoTrackRenderer.MSG_SET_OUTPUT_BUFFER_RENDERER, new VpxVideoSurfaceView(context)); player.prepare(videoRenderer); player.setPlayWhenReady(true); Looper.loop(); }
private void releasePlayer() { if (player != null) { Log.d(TAG, "Release player"); videoPlayerView.stopDebugView(); playerPosition = player.getCurrentPosition(); long duration = player.getDuration(); player.getPlayerControl().pause(); updatePlaybackState(ExoPlayer.STATE_IDLE); updateMediaSessionIntent(); player.release(); player = null; eventLogger.endSession(); eventLogger = null; timeLogger.endSession(); timeLogger = null; if (playerPosition >= duration) { mediaSession.setActive(false); mediaSession.release(); mediaSession = null; } } }
private void updatePlaybackState(int playbackState) { PlaybackState.Builder state = new PlaybackState.Builder(); long position = player.getCurrentPosition(); if (ExoPlayer.STATE_PREPARING == playbackState) { state.setState(PlaybackState.STATE_CONNECTING, position, 1.0f); } else if (ExoPlayer.STATE_BUFFERING == playbackState) { state.setState(PlaybackState.STATE_BUFFERING, position, 1.0f); } else { if (player.getPlayerControl().isPlaying()) { state.setState(PlaybackState.STATE_PLAYING, position, 1.0f); } else { state.setState(PlaybackState.STATE_PAUSED, position, 1.0f); } } mediaSession.setPlaybackState(state.build()); }
private void executeListeners() { long duration = player.getDuration() / 1000; long position = player.getCurrentPosition() / 1000; List<Pair<Long, OnTimeReached>> executed = new ArrayList<>(); if (duration > 0 && (state == ExoPlayer.STATE_READY || state == ExoPlayer.STATE_ENDED)) { long remain = duration - position; for (Pair<Long, OnTimeReached> listener : listeners) { long condition = listener.first; if (remain <= condition) { Log.d(TAG, "Executing listener, duration=" + duration + ", position=" + position + ", remaining=" + remain); listener.second.onPositionRemainingReached(duration, position); executed.add(listener); } } } listeners.removeAll(executed); }
@Override public void onStateChanged(boolean playWhenReady, int playbackState) { state = playbackState; String text = "playWhenReady=" + playWhenReady + ", playbackState="; switch (playbackState) { case ExoPlayer.STATE_BUFFERING: text += "buffering"; break; case ExoPlayer.STATE_ENDED: text += "ended"; break; case ExoPlayer.STATE_IDLE: text += "idle"; break; case ExoPlayer.STATE_PREPARING: text += "preparing"; break; case ExoPlayer.STATE_READY: text += "ready"; break; default: text += "unknown"; break; } Log.d(TAG, text); }
/** * Retrieves a list of available tracks * * @return A list of available tracks associated with each type (see {@link com.devbrackets.android.exomedia.annotation.TrackRenderType}) */ @Nullable public Map<Integer, List<MediaFormat>> getAvailableTracks() { if (getPlaybackState() == ExoPlayer.STATE_IDLE) { return null; } Map<Integer, List<MediaFormat>> trackMap = new ArrayMap<>(); int[] trackTypes = new int[] {RENDER_AUDIO, RENDER_VIDEO, RENDER_CLOSED_CAPTION, RENDER_TIMED_METADATA}; //Populates the map with all available tracks for (int type : trackTypes) { int trackCount = getTrackCount(type); List<MediaFormat> tracks = new ArrayList<>(trackCount); trackMap.put(type, tracks); for (int i = 0; i < trackCount; i++) { tracks.add(getTrackFormat(type, i)); } } return trackMap; }
private void reportPlayerState() { boolean playWhenReady = player.getPlayWhenReady(); int playbackState = getPlaybackState(); int newState = stateStore.getState(playWhenReady, playbackState); if (newState != stateStore.getMostRecentState()) { stateStore.setMostRecentState(playWhenReady, playbackState); //Because the playWhenReady isn't a state in itself, rather a flag to a state we will ignore informing of // see events when that is the only change. Additionally, on some devices we get states ordered as // [seeking, ready, buffering, ready] while on others we get [seeking, buffering, ready] boolean informSeekCompletion = stateStore.matchesHistory(new int[]{StateStore.STATE_SEEKING, ExoPlayer.STATE_BUFFERING, ExoPlayer.STATE_READY}, true); informSeekCompletion |= stateStore.matchesHistory(new int[]{StateStore.STATE_SEEKING, ExoPlayer.STATE_READY, ExoPlayer.STATE_BUFFERING, ExoPlayer.STATE_READY}, true); for (ExoPlayerListener listener : listeners) { listener.onStateChanged(playWhenReady, playbackState); if (informSeekCompletion) { listener.onSeekComplete(); } } } }
private void preparePlayer() { SampleSource sampleSource = new FrameworkSampleSource(this, Uri.parse(mVideo.getContentUrl()), /* headers */ null, RENDERER_COUNT); // Build the track renderers videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT); TrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource); // Setup the player player = ExoPlayer.Factory.newInstance(RENDERER_COUNT, 1000, 5000); player.addListener(this); // Build the player controls mediaController.setMediaPlayer(new PlayerControl(player)); mediaController.setEnabled(true); player.prepare(videoRenderer, audioRenderer); }