How to add seekbar to Exoplayer exo_playback_control_view.xml

1234567 picture 1234567 · Sep 14, 2017 · Viewed 11.6k times · Source

cannot add seekbar to explayer

Ia ma referring to https://medium.com/google-exoplayer/customizing-exoplayers-ui-components-728cf55ee07a

to add custom play pause button and seekbar to exoplayer

this is the code I am trying

public class ExoplayerAct extends Activity implements VideoRendererEventListener {


    private static final String TAG = "MainActivity";
    private SimpleExoPlayerView simpleExoPlayerView;
    private SimpleExoPlayer player;
    private TextView resolutionTextView;
    String j;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.exoplayer);
        resolutionTextView = new TextView(this);
        resolutionTextView = (TextView) findViewById(R.id.resolution_textView);

        Intent iin = getIntent();
        Bundle b = iin.getExtras();
        if (b != null) {
            j = (String) b.get("fileVideoPath");
        }

// 1. Create a default TrackSelector
        BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
        TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);

// 2. Create a default LoadControl
        LoadControl loadControl = new DefaultLoadControl();

// 3. Create the player
        player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
        simpleExoPlayerView = new SimpleExoPlayerView(this);
        simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);

//Set media controller
        simpleExoPlayerView.setUseController(true);

        simpleExoPlayerView.requestFocus();


// Bind the player to the view.
        simpleExoPlayerView.setPlayer(player);


// I. ADJUST HERE:
//CHOOSE CONTENT: LiveStream / SdCard

//LIVE STREAM SOURCE: * Livestream links may be out of date so find any m3u8 files online and replace:

//        Uri mp4VideoUri =Uri.parse("http://81.7.13.162/hls/ss1/index.m3u8"); //random 720p source
//        Uri mp4VideoUri =Uri.parse("http://54.255.155.24:1935//Live/_definst_/amlst:sweetbcha1novD235L240P/playlist.m3u8"); //Radnom 540p indian channel
//        Uri mp4VideoUri =Uri.parse("FIND A WORKING LINK ABD PLUg INTO HERE"); //PLUG INTO HERE<------------------------------------------


//VIDEO FROM SD CARD: (2 steps. set up file and path, then change videoSource to get the file)
//        String urimp4 = "path/FileName.mp4"; //upload file to device and add path/name.mp4
//         Uri mp4VideoUri = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath()+"/2010a.mp4");

        Uri mp4VideoUri = Uri.parse(j);





//Measures bandwidth during playback. Can be null if not required.
        DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();
//Produces DataSource instances through which media data is loaded.
        DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this
                , Util.getUserAgent(this, "exoplayer2example"), bandwidthMeterA);
//Produces Extractor instances for parsing the media data.
        ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();


// II. ADJUST HERE:

//This is the MediaSource representing the media to be played:
//FOR SD CARD SOURCE:
        MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri, dataSourceFactory, extractorsFactory, null, null);

//FOR LIVESTREAM LINK:
//        MediaSource videoSource = new HlsMediaSource(mp4VideoUri, dataSourceFactory, 1, null, null);
        final LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);

// Prepare the player with the source.
        player.prepare(loopingSource);

        player.addListener(new ExoPlayer.EventListener() {
            @Override
            public void onTimelineChanged(Timeline timeline, Object manifest) {
                Log.v(TAG, "Listener-onTimelineChanged...");
            }

            @Override
            public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
                Log.v(TAG, "Listener-onTracksChanged...");
            }

            @Override
            public void onLoadingChanged(boolean isLoading) {
                Log.v(TAG, "Listener-onLoadingChanged...isLoading:"+isLoading);
            }

            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
                Log.v(TAG, "Listener-onPlayerStateChanged..." + playbackState);
            }

            @Override
            public void onRepeatModeChanged(int repeatMode) {
                Log.v(TAG, "Listener-onRepeatModeChanged...");
            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {
                Log.v(TAG, "Listener-onPlayerError...");
                player.stop();
                player.prepare(loopingSource);
                player.setPlayWhenReady(true);
            }

            @Override
            public void onPositionDiscontinuity() {
                Log.v(TAG, "Listener-onPositionDiscontinuity...");
            }

            @Override
            public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
                Log.v(TAG, "Listener-onPlaybackParametersChanged...");
            }
        });
        PlaybackParameters playbackParameters = new PlaybackParameters(2.0f, 1.0f);
        player.setPlaybackParameters(playbackParameters);

        player.setPlayWhenReady(true); //run file/link when ready to play.
        player.setVideoDebugListener(this); //for listening to resolution change and  outputing the resolution
    }//End of onCreate

    @Override
    public void onVideoEnabled(DecoderCounters counters) {

    }

    @Override
    public void onVideoDecoderInitialized(String decoderName, long initializedTimestampMs, long initializationDurationMs) {

    }

    @Override
    public void onVideoInputFormatChanged(Format format) {

    }

    @Override
    public void onDroppedFrames(int count, long elapsedMs) {

    }

    @Override
    public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
        Log.v(TAG, "onVideoSizeChanged ["  + " width: " + width + " height: " + height + "]");
        resolutionTextView.setText("RES:(WxH):"+width+"X"+height +"\n           "+height+"p");
    }

    @Override
    public void onRenderedFirstFrame(Surface surface) {

    }

    @Override
    public void onVideoDisabled(DecoderCounters counters) {

    }




//-------------------------------------------------------ANDROID LIFECYCLE---------------------------------------------------------------------------------------------

    @Override
    protected void onStop() {
        super.onStop();
        Log.v(TAG, "onStop()...");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.v(TAG, "onStart()...");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.v(TAG, "onResume()...");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.v(TAG, "onPause()...");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.v(TAG, "onDestroy()...");
        player.release();
    }
}

the exoplayer layout is

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/fab_margin"
    android:paddingLeft="@dimen/fab_margin"
    android:paddingRight="@dimen/fab_margin"
    android:paddingTop="@dimen/fab_margin"
    tools:context="com.ayalus.exoplayer2example.MainActivity">

    <TextView
        android:id="@+id/sample_app_title"
        android:text="ExoPlayer 2 Example App:"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="40sp"
        android:textColor="#000000"
        android:gravity="center_horizontal"/>

    <TextView
        android:id="@+id/resolution_textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Resolution"
        android:textSize="40px"
        android:background="#FFFFFF"
        android:textColor="#000000"
        android:layout_below="@+id/sample_app_title"
        android:gravity="center_horizontal"/>

    <com.google.android.exoplayer2.ui.SimpleExoPlayerView
        android:id="@+id/player_view"
        android:focusable="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/resolution_textView"
        app:use_controller="false"
        android:layout_marginTop="10dp" />




</RelativeLayout>

and the custom exo_playback_control_view

is

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:layoutDirection="ltr"
    android:background="#CC000000"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:paddingTop="4dp"
        android:orientation="horizontal">

        <ImageButton android:id="@id/exo_prev"
            android:visibility="gone"
            style="@style/ExoMediaButton.Previous"/>

        <ImageButton android:id="@id/exo_rew"
            android:visibility="gone"
            style="@style/ExoMediaButton.Rewind"/>

        <ImageButton android:id="@id/exo_play"
            style="@style/ExoMediaButton.Play"/>

        <ImageButton android:id="@id/exo_pause"
            style="@style/ExoMediaButton.Pause"/>

        <ImageButton android:id="@id/exo_ffwd"
            android:visibility="gone"
            style="@style/ExoMediaButton.FastForward"/>

        <ImageButton android:id="@id/exo_next"
            android:visibility="gone"
            style="@style/ExoMediaButton.Next"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <TextView android:id="@id/exo_position"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:textStyle="bold"
            android:paddingLeft="4dp"
            android:paddingRight="4dp"
            android:includeFontPadding="false"
            android:textColor="#FFBEBEBE"/>

        <!--<SeekBar android:id="@id/exo_progress"-->
            <!--android:layout_width="0dp"-->
            <!--android:layout_weight="1"-->
            <!--android:layout_height="32dp"-->
            <!--android:focusable="false"-->
            <!--style="?android:attr/progressBarStyleHorizontal"/>-->

        <TextView android:id="@id/exo_duration"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:textStyle="bold"
            android:paddingLeft="4dp"
            android:paddingRight="4dp"
            android:includeFontPadding="false"
            android:textColor="#FFBEBEBE"/>

    </LinearLayout>

</LinearLayout>

If I comment the seekbar as above , it works correctly

but If I add the seekbar it gives me error

Caused by: java.lang.ClassCastException: android.widget.SeekBar cannot be cast to com.google.android.exoplayer2.ui.TimeBar

Answer

Jez picture Jez · Oct 5, 2017

In your exo_playback_control_view layout replace Seekbar with com.google.android.exoplayer2.ui.DefaultTimeBar

This is what the error message is telling you, and if you check the docs here you'll find that the type given for the exo_progress control is indeed TimeBar.

<com.google.android.exoplayer2.ui.DefaultTimeBar
    android:id="@id/exo_progress"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="26dp"/>