How to change exoplayer default TrackSelector Dialog

The Default Exoplayer trackSelector dialog is too old-fashioned. Nowadays we need some materialistic design in our app while exoplayer provides us default old looking trackSelection dialog. we are here to explain step by step how to customize your trackSelector dialog as you want in your app.

so lets get started.

OVERVIEW :

  • we need to manually extract track details from video URL
  • we will show extracted data into our custom View/dialog in whatever way you want it to show
  • we will enable onClick on that View/Dialog
  • onClick of the item in that view we will override the bitrate of the video manually

STEP 1 :

we will going to extract track details from URL

  private DefaultTrackSelector trackSelector;

go to your player activity where you declared and initialize trackSelector. define 2 Array List for format and bitrates

    private ArrayList<String> formatList = new ArrayList<>();
    private ArrayList<Double> bitrateList = new ArrayList<>();

then write this function to extract data from trackSelector . *** you must call this function after trackSelector is initialised *** i am calling this function after user click on button for showing dialog. if you will call before then trackSelector can be null and this function never runs.

 void trackList()
    {
        if(formatList!=null){formatList.clear();}
        if(bitrateList!=null){bitrateList.clear();}
        final Gson gson = new GsonBuilder()
                .excludeFieldsWithoutExposeAnnotation()
                .excludeFieldsWithModifiers(TRANSIENT) // STATIC|TRANSIENT in the default configuration
                .create();
        if (trackSelector.getCurrentMappedTrackInfo() != null) {
        Log.d("TAG", "log tracks clicked");
        MappingTrackSelector.MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
        DefaultTrackSelector.Parameters parameters = trackSelector.getParameters();

        for (int rendererIndex = 0; rendererIndex < mappedTrackInfo.getRendererCount(); rendererIndex++) {
            if (TrackSelectionDialog.showTabForRenderer(mappedTrackInfo, rendererIndex)) {
                int trackType = mappedTrackInfo.getRendererType(rendererIndex);
                TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(rendererIndex);
                Boolean isRendererDisabled = parameters.getRendererDisabled(rendererIndex);
                DefaultTrackSelector.SelectionOverride selectionOverride = parameters.getSelectionOverride(rendererIndex, trackGroupArray);

                Log.d("TAG", "------------------------------------------------------Track item " + rendererIndex + "------------------------------------------------------");
                Log.d("TAG", "track type: ");
                Log.d("TAG", "track group array: " + gson.toJson(trackGroupArray));
                for (int groupIndex = 0; groupIndex < trackGroupArray.length; groupIndex++) {
                    for (int trackIndex = 0; trackIndex < trackGroupArray.get(groupIndex).length; trackIndex++) {
                        TrackNameProvider trackNameProvider = new DefaultTrackNameProvider(getResources());
                        String trackName = trackNameProvider.getTrackName(trackGroupArray.get(groupIndex).getFormat(trackIndex));
                         String[] widthxheight = trackName.split(",");
                      //  Log.d("TAG", "wid" + widthxheight[0]);
                         String[] height = widthxheight[0].split("×");
                      //  Log.d("TAG", "hei" + height[0]);
                        Boolean isTrackSupported = mappedTrackInfo.getTrackSupport(rendererIndex, groupIndex, trackIndex) == RendererCapabilities.FORMAT_HANDLED;
                        Log.d("TAG", "track item " + groupIndex + ": trackName: " + trackName + ", isTrackSupported: " + isTrackSupported);
                        if(rendererIndex == 0)
                        {
                            formatList.add(height[1] + "p");
                            bitrateList.add(Double.parseDouble(widthxheight[1].replace("Mbps","").trim()));
                        }
                    }
                }
                Log.d("TAG", "bitrate" + bitrateList);
                Log.d("TAG", "isRendererDisabled: " + isRendererDisabled);
                Log.d("TAG", "selectionOverride: " +  gson.toJson(selectionOverride));
            }
        }
    }
    }

STEP 2 :

we will use this EasyDialog , for that we have to insert its dependencies

https://github.com/michaelye/EasyDialog

add this line into your build.gradle dependencies

compile 'com.github.michaelye.easydialog:easydialog:1.4'

STEP 3 :

Go to the activity in which you want to show that dialog like in my case i want it in playeractivity.java

import com.michael.easydialog.EasyDialog; 

 EasyDialog qualityDialog;

add above lines of code in it for declaration

STEP 4 :

we will create out custom trackSelection dialog view in xml

Create 1 Layout file in res>Layout folder and name it popupwindow.xml to follow along in this tutorial. you can put any name you want.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/colorTransparent"
    android:orientation="vertical"
    >
<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/colorTransparent"
    >
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/popup_element"
        android:padding="20dp"
        android:gravity="center"

        android:orientation="vertical">

       <TextView
                android:id="@+id/title_txt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingRight="6dp"
                android:paddingLeft="6dp"
                android:gravity="center"
                android:text="Video Quality"
                android:textSize="14sp"
                android:layout_marginBottom="5dp"
                android:textColor="@color/hc_color_white_op90" />
        
    </LinearLayout>
</RelativeLayout>

</LinearLayout>

put this code into that file.

This is the file on which popup ui is dependent you can make changes if you want, just try to play with the properties of it.

STEP 5 :

Now come back to our activity in which we added code in step 3

void populatePopupmenus(){
        View v ;
        LinearLayout lLayout ;
        v =    this.getLayoutInflater().inflate(R.layout.popupwindow, null);
        lLayout = v.findViewById(R.id.popup_element);

           
// Root ViewGroup in which you want to add textviews

           for (int i = 0; i < formatList.size(); i++) {
               TextView tv = new TextView(this); 
               tv.setText(formatList.get(i));
               tv.setId(i);
               tv.setTextColor(Color.WHITE);
               tv.setGravity(CENTER);
               tv.setPadding(0,5,0,5);
               tv.setTextSize(18);
               tv.setOnClickListener(new View.OnClickListener() {
                   @Override
                   public void onClick(View view) {

                       Log.d("STATE", "jjjjjjjjjjj" + tv.getText() + tv.getId());
                      // String id = (String) tv.getText();
                       int id = tv.getId();
                       if(id == 0)
                       {
                           Log.d("STATE", "jjjjjjjjjjj" + bitrateList.get(id));
                           changeQuality(bitrateList.get(id)*1000000);

                       }
                       if(id == 1)
                       {
                           Log.d("STATE", "jjjjjjjjjjj" + bitrateList.get(id));
                           changeQuality(bitrateList.get(id)*1000000);
                       }
                       if(id == 2)
                       {
                           Log.d("STATE", "jjjjjjjjjjj" + bitrateList.get(id));
                           changeQuality(bitrateList.get(id)*1000000);
                       }
                       if(id == 3)
                       {
                           Log.d("STATE", "jjjjjjjjjjj" + bitrateList.get(id));
                           changeQuality(bitrateList.get(id)*1000000);
                       }
                       if(id == 4)
                       {
                           Log.d("STATE", "jjjjjjjjjjj" + bitrateList.get(id));
                           changeQuality(bitrateList.get(id)*1000000);
                       }
                   }
               });
               Log.d("STATE", lLayout + formatList.get(i));
               if (tv.getParent() != null) {
                   ((ViewGroup) tv.getParent()).removeView(tv); // <- fix
               }
               if (lLayout != null) {
                   lLayout.addView(tv);
               } // Add to your ViewGroup using this method
           }
      
          

        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int height = displayMetrics.heightPixels;
        int width = displayMetrics.widthPixels;
       ///////
        Log.d("STATE",height +" " +width);

       qualityDialog =  new EasyDialog(PlayerActivity.this)
                // .setLayoutResourceId(R.layout.layout_tip_content_horizontal)//layout resource id
                .setLayout(v)
                .setBackgroundColor(PlayerActivity.this.getResources().getColor(R.color.colorSpinerGray))
                // .setLocation(new location[])//point in screen
                .setLocationByAttachedView("here you can give View from which this dialog will appear in my case its setting image view")
                .setGravity(EasyDialog.GRAVITY_TOP)
                .setAnimationTranslationShow(EasyDialog.DIRECTION_X, 1000, -600, 100, -50, 50, 0)
                .setAnimationAlphaShow(1000, 0.3f, 1.0f)
                .setAnimationTranslationDismiss(EasyDialog.DIRECTION_X, 500, -50, 800)
                .setAnimationAlphaDismiss(500, 1.0f, 0.0f)
                .setTouchOutsideDismiss(true)
                .setMatchParent(false)
                .setOutsideColor(PlayerActivity.this.getResources().getColor(R.color.colorTransparent))
                .show();

    }

setLocationByAttachedView for this attribute you have to give View from which this dialog will show .you have to define imageview inside any layout then in activity findviewbyid that layout and assign that layout to this attribute.

STEP 6 :

define change function

we will change the quality in this function.

   void changeQuality(double bitrate){
        DefaultTrackSelector.ParametersBuilder builder = new DefaultTrackSelector.ParametersBuilder(this);
        builder.setMaxVideoBitrate((int) Math.round(bitrate));
        //40000000
        //4.5  * 1000000
        //2.6  * 1000000
        //0.8  * 1000000
        //0.4  * 1000000
        trackSelectorParameters = builder.build();
        trackSelector.setParameters(trackSelectorParameters);
        qualityDialog.dismiss();
    }

that’s it you have your nice Glassmorphism UI quality selector dialog

Enjoy…

if any doubts plz comment down i’ll reply right away

Leave a Reply

Your email address will not be published. Required fields are marked *

Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.