@Override public void onResume() { super.onResume(); mPlayer = ExoPlayer.Factory.newInstance(2, 1000, 5000); mPlayer.addListener(this); mPlayer.seekTo(mPlayerPosition); mMediaController.setMediaPlayer(new PlayerControl(mPlayer)); mMediaController.setEnabled(true); mCallback = new RendererBuilderCallback(); mBuilder.buildRenderers(mCallback); }
private void maybeStartPlayback() { Surface surface = mSurfaceView.getHolder().getSurface(); if (mVideoRenderer == null || surface == null || !surface.isValid()) { return; } mPlayer.sendMessage(mVideoRenderer, MSG_SET_SURFACE, surface); if (mAutoPlay) { mPlayer.setPlayWhenReady(true); mAutoPlay = false; } }
private void pushSurface(boolean blockForSurfacePush) { if (videoRenderer == null) { return; } if (blockForSurfacePush) { player.blockingSendMessage( videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); } else { player.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); } }
public DemoPlayer(RendererBuilder rendererBuilder) { this.rendererBuilder = rendererBuilder; player = ExoPlayer.Factory.newInstance(RENDERER_COUNT, 1000, 5000); player.addListener(this); playerControl = new PlayerControl(player); mainHandler = new Handler(); listeners = new CopyOnWriteArrayList<>(); lastReportedPlaybackState = STATE_IDLE; rendererBuildingState = RENDERER_BUILDING_STATE_IDLE; // Disable text initially. player.setSelectedTrack(TYPE_TEXT, TRACK_DISABLED); }
private void maybeStartPlayback() { Log.d(TAG, "maybeStartPlayback"); Surface surface = surfaceView.getHolder().getSurface(); if (videoRenderer == null || surface == null || !surface.isValid()) { // We're not ready yet. return; } player.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); if (autoPlay) { player.setPlayWhenReady(true); autoPlay = false; } }
@Override public void onPause() { super.onPause(); if (mPlayer != null) { mPlayer.stop(); mPlayerPosition = mPlayer.getCurrentPosition(); mPlayer.release(); mPlayer = null; } mCallback = null; mVideoRenderer = null; mShutter.setVisibility(View.VISIBLE); }
private void pushSurfaceAndVideoTrack(boolean blockForSurfacePush) { if (rendererBuildingState != RenderBuildingState.BUILT) { return; } if (blockForSurfacePush) { player.blockingSendMessage( videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); } else { player.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); } pushTrackSelection(RENDER_VIDEO_INDEX, surface != null && surface.isValid()); }
public int getPlaybackState() { if (rendererBuildingState == RenderBuildingState.BUILDING) { return ExoPlayer.STATE_PREPARING; } return player.getPlaybackState(); }
public void onRenderers( String[][] trackNames, MultiTrackChunkSource[] multiTrackSources, TrackRenderer[] renderers) { builderCallback = null; // Normalize the results. if (trackNames == null) { trackNames = new String[RENDER_COUNT][]; } if (multiTrackSources == null) { multiTrackSources = new MultiTrackChunkSource[RENDER_COUNT]; } for (int i = 0; i < RENDER_COUNT; i++) { if (renderers[i] == null) { // Convert a null renderer to a dummy renderer. renderers[i] = new DummyTrackRenderer(); } else if (trackNames[i] == null) { // We have a renderer so we must have at least one track, but the names are unknown. // Initialize the correct number of null track names. int trackCount = multiTrackSources[i] == null ? 1 : multiTrackSources[i].getTrackCount(); trackNames[i] = new String[trackCount]; } } // Complete preparation. this.videoRenderer = renderers[RENDER_VIDEO_INDEX]; this.audioRenderer = renderers[RENDER_AUDIO_INDEX]; this.trackNames = trackNames; this.multiTrackSources = multiTrackSources; rendererBuildingState = RenderBuildingState.BUILT; pushSurfaceAndVideoTrack(false); pushTrackSelection(RENDER_AUDIO_INDEX, true); pushTrackSelection(RENDER_CLOSED_CAPTION_INDEX, true); player.prepare(renderers); }
@UiThread(propagation = UiThread.Propagation.REUSE) void updateTime(long ms) { mVideoTime.setText( String.format( VideoPlayActivity.this.getResources().getString(R.string.video_time), ms2Time(ms), ms2Time(mExoPlayer.getDuration()))); }
@Override public void onVisibleBehindCanceled() { super.onVisibleBehindCanceled(); if (player != null) { player.release(); player = null; } videoRenderer = null; shutterView.setVisibility(View.VISIBLE); }
@Override protected void onStop() { super.onStop(); if (player != null) { player.release(); player = null; } videoRenderer = null; shutterView.setVisibility(View.VISIBLE); }
public void release() { if (builderCallback != null) { builderCallback.cancel(); builderCallback = null; } rendererBuildingState = RenderBuildingState.IDLE; surface = null; player.release(); }
public void prepare() { if (rendererBuildingState == RENDERER_BUILDING_STATE_BUILT) { player.stop(); } rendererBuilder.cancel(); videoFormat = null; videoRenderer = null; rendererBuildingState = RENDERER_BUILDING_STATE_BUILDING; maybeReportPlayerState(); rendererBuilder.buildRenderers(this); }
private void maybeReportPlayerState() { boolean playWhenReady = player.getPlayWhenReady(); int playbackState = getPlaybackState(); if (lastReportedPlayWhenReady != playWhenReady || lastReportedPlaybackState != playbackState) { for (Listener listener : listeners) { listener.onStateChanged(playWhenReady, playbackState); } lastReportedPlayWhenReady = playWhenReady; lastReportedPlaybackState = playbackState; } }
private void onRenderers( RendererBuilderCallback callback, MediaCodecVideoTrackRenderer videoRenderer, MediaCodecAudioTrackRenderer audioRenderer) { if (mCallback != callback) { return; } mCallback = null; mVideoRenderer = videoRenderer; mPlayer.prepare(videoRenderer, audioRenderer); maybeStartPlayback(); }
public int getPlaybackState() { if (rendererBuildingState == RENDERER_BUILDING_STATE_BUILDING) { return STATE_PREPARING; } int playerState = player.getPlaybackState(); if (rendererBuildingState == RENDERER_BUILDING_STATE_BUILT && playerState == STATE_IDLE) { // This is an edge case where the renderers are built, but are still being passed to the // player's playback thread. return STATE_PREPARING; } return playerState; }
public EMExoPlayer(RenderBuilder rendererBuilder) { this.rendererBuilder = rendererBuilder; player = ExoPlayer.Factory.newInstance(RENDER_COUNT, BUFFER_LENGTH_MIN, REBUFFER_LENGTH_MIN); player.addListener(this); playerControl = new PlayerControl(player); mainHandler = new Handler(); listeners = new CopyOnWriteArrayList<>(); lastReportedPlaybackState = ExoPlayer.STATE_IDLE; rendererBuildingState = RenderBuildingState.IDLE; selectedTracks = new int[RENDER_COUNT]; // Disable text initially. selectedTracks[RENDER_CLOSED_CAPTION_INDEX] = DISABLED_TRACK; }
private void preparePlayer() { // TODO(cartland): Remove sample video. String url = "http://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Fiber%20to%20the%20Pole.mp4"; mVideo.setContentUrl(url); 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); }
private void pushTrackSelection(int type, boolean allowRendererEnable) { if (rendererBuildingState != RenderBuildingState.BUILT) { return; } int trackIndex = selectedTracks[type]; if (trackIndex == DISABLED_TRACK) { player.setRendererEnabled(type, false); } else if (multiTrackSources[type] == null) { player.setRendererEnabled(type, allowRendererEnable); } else { boolean playWhenReady = player.getPlayWhenReady(); player.setPlayWhenReady(false); player.setRendererEnabled(type, false); player.sendMessage( multiTrackSources[type], MultiTrackChunkSource.MSG_SELECT_TRACK, trackIndex); player.setRendererEnabled(type, allowRendererEnable); player.setPlayWhenReady(playWhenReady); } }
public void prepare() { if (prepared || rendererBuilder == null) { return; } if (rendererBuildingState == RenderBuildingState.BUILT) { player.stop(); } if (builderCallback != null) { builderCallback.cancel(); } rendererBuildingState = RenderBuildingState.BUILDING; reportPlayerState(); builderCallback = new InternalRendererBuilderCallback(); rendererBuilder.buildRenderers(this, builderCallback); prepared = true; }
/** * Invoked with the results from a {link RendererBuilder}. * * @param renderers Renderers indexed by {link DemoPlayer} TYPE_* constants. An individual element * may be null if there do not exist tracks of the corresponding type. * @param bandwidthMeter Provides an estimate of the currently available bandwidth. May be null. */ /* package */ void onRenderers(TrackRenderer[] renderers, BandwidthMeter bandwidthMeter) { for (int i = 0; i < RENDERER_COUNT; i++) { if (renderers[i] == null) { // Convert a null renderer to a dummy renderer. renderers[i] = new DummyTrackRenderer(); } } // Complete preparation. this.videoRenderer = renderers[TYPE_VIDEO]; this.codecCounters = videoRenderer instanceof MediaCodecTrackRenderer ? ((MediaCodecTrackRenderer) videoRenderer).codecCounters : renderers[TYPE_AUDIO] instanceof MediaCodecTrackRenderer ? ((MediaCodecTrackRenderer) renderers[TYPE_AUDIO]).codecCounters : null; this.bandwidthMeter = bandwidthMeter; pushSurface(false); player.prepare(renderers); rendererBuildingState = RENDERER_BUILDING_STATE_BUILT; }
public long getDuration() { return player.getDuration(); }
@Override public void surfaceDestroyed(SurfaceHolder holder) { if (videoRenderer != null) { player.blockingSendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, null); } }
@UiThread(propagation = UiThread.Propagation.REUSE) void updateSeekBar() { mSeekBar.setProgress( (int) (mExoPlayer.getCurrentPosition() * 1.0f / mExoPlayer.getDuration() * 100)); }
public int getBufferedPercentage() { return player.getBufferedPercentage(); }
@Override protected void onStop() { super.onStop(); mExoPlayer.release(); timer.cancel(); }
void initPlayer(String videoLink) { if (null == mExoPlayer) { mExoPlayer = ExoPlayer.Factory.newInstance(2); mPlayerControl = new PlayerControl(mExoPlayer); Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE); DataSource dataSource = new DefaultUriDataSource(this, null, USER_AGENT); ExtractorSampleSource sampleSource = new ExtractorSampleSource( Uri.parse(videoLink), dataSource, allocator, BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE); MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer( sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT); MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource); mExoPlayer.prepare(videoRenderer, audioRenderer); mExoPlayer.sendMessage( videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, mExoPlayerSurface.getHolder().getSurface()); mExoPlayer.setPlayWhenReady(true); } controllerBtn.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { mPlayerControl.pause(); } else { mPlayerControl.start(); } } }); mSeekBar.setMax(100); mSeekBar.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { updateTime((long) (progress / 100.0f * mExoPlayer.getDuration())); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { controllerBtn.setChecked(true); timer.cancel(); } @Override public void onStopTrackingTouch(SeekBar seekBar) { mExoPlayer.seekTo((int) (mExoPlayer.getDuration() / 100.0f * seekBar.getProgress())); } }); mExoPlayer.addListener( new ExoPlayer.Listener() { @Override public void onPlayerStateChanged(boolean b, int i) { if (i == ExoPlayer.STATE_READY) { mProgress.setVisibility(View.INVISIBLE); timer = new Timer(true); timer.schedule( new TimerTask() { @Override public void run() { updateTime(mExoPlayer.getCurrentPosition()); updateSeekBar(); } }, 0, 1000); } } @Override public void onPlayWhenReadyCommitted() {} @Override public void onPlayerError(ExoPlaybackException e) {} }); }
public boolean getPlayWhenReady() { return player.getPlayWhenReady(); }
/* package */ Looper getPlaybackLooper() { return player.getPlaybackLooper(); }