Hello folks, I am back again with the 2nd part of ExoPlayer blog. In my previous blog, I explained the components of ExoPlayer and how to configure it in our application.
In this blog, we will learn how to detect different events of ExoPlayer and how to customize its UI components. The feature to customize the ExoPlayer UI components is available from V2.1.0 onwards.
So let’s start with ExoPlayer events first:
- ExoPlayer.EventListener: This event listener gets called when there are any changes in player state. For example, this listener will get called if we change the seek position of the player or if we change the current playing track. There are several callbacks related to this event listener:
- onTimelineChange(): called when the duration of the source has been determined.
- onTrackChange(): called when the source track has changed.
- onPlayerError(): called when some error occurs in playing the source file.
- onPlayerStateChange(): called when the player state changes from one to another. The possible player states are idle, ready, buffering, paused, playing, stopped, completed, error, etc.
- onLoadingChange(): called when the source starts or stops loading.
- onPositionDiscontinuty(): called when the source seeks to some position.
- onPlaybackParameterChange(): called when the current source parameter gets changed.
So if you want to perform any operation or any customization during any of these events, then you can implement this listener. To start getting callbacks for any of the events mentioned above, you can set the ExoPlayer.EventListener to your player object using the addListener() method of the SimpleExoPlayer class.
Let’s look at an example of the class that will implement the ExoPlayer.EventListener:
Now let’s see how we can add the ExoPlayer.EventListener to the player:
- AudioRendererEventListener: This listener can be used to listen to events related to audio rendering. For example, this listener will get called if the audio format gets changed or if the audio decoder gets initialized. Below are the available callback methods of the AudioRendererEventListener:
- onAudioSessionId(): called when the first audio frame gets rendered and a random integer id is assigned to the audio stream.
- onAudioDecoderInitialized(): called when the audio decoder gets initialized and the audio is ready to play.
- onAudioTrackUnderrun(): called when the audio track gets cut down because of any reason by the ExoPlayer.
- onAudioInputFormatChanged(): called when the audio format gets changed from one to another.
- onAudioEnabled(): called when the audio track is enabled by the track selector.
- onAudioDisabled(): called when the audio track is disabled by the track selector.
To start getting callback events for any of the above-mentioned methods, you can implement the AudioRendererEventListener. You can set this listener to the ExoPlayer object by using the setAudioDebugListener() method of the SimpleExoPlayer class.
Let’s look at an example of the class that will implement the AudioRendererEventListener:
Now let’s see how we can set this listener to our player object:
- VideoRendererEventListener: This listener can be used to listen to events related to video rendering. For example, this listener gets called when the first video frame is rendered on the screen or if a video frame gets dropped because of any reason. Below is the list of available callbacks of VideoRendererEventListener:
- onDroppedFrame(): called when any video frame gets dropped by a player because of any reason. It will also give you the count and duration in milliseconds for the dropped frame.
- onVideoSizeChanged(): called when the size (resolution) of the video gets changed.
- onVideoInputFormatChnaged(): called when the source file format changes from one format to another.
- onVideoEnabled: called when the video track is enabled using a track selector.
- onRenderedFirstFrame(): called when the first frame of the video track gets rendered.
- onVideoDecoderInitialized(): called when the video decoder gets initialized and the video is ready to play.
- onVideoDisabled(): called when video track is disabled using a track selector.
To start getting callbacks for the above-mentioned events, you can implement the VideoRendererEventListener. You can set this listener to the ExoPlayer object using the setVideoDebugListener() method of the SimpleExoPlayer class.
Let’s look at an example of the class that implements the VideoRendererEventListener:
Now let’s see how we can set this listener to our player object:
Use of these events is optional. You are free to set the listeners if you need the callbacks. For example, if you want to perform any action when the video size gets changed then you can set the VideoRendererEventListener on SimpleExoPlayer via setVideoDebugListener() or if you want to perform any action when the audio decoder is initialized, you can set the AudioRendererEventListener on SimpleExoPlayer via setAudioDebugListener().
Now, let’s look at the ExoPlayer UI components.
- PlaybackControlView: It is a view for controlling and managing different actions on the ExoPlayer instance. PlaybackControlView displays standard controls like play/pause, seekbar (for displaying the total duration and current duration), fast-forward and rewind.
- SimpleExoPlayerView: It is a high-level view for ExoPlayer to display video, subtitle, and other standard player controllers.
Use of these UI Components is also optional. Developers are free to customize the complete view by implementing their UI components from scratch as well if they want. ExoPlayer has provided the privilege for full customization of UI components. These UI components can be customized in three different ways.
- By setting attributes (or calling corresponding methods) on the views.
- By globally overriding the view layout files.
- By specifying a custom layout file for a single view instance.
Let’s have a look at how we can customize certain attributes of the ExoPlayer:
As shown above, 5 attributes are used to customize the ExoPlayer UI.
- use_controller: If you want to display the playback controller, set it to true else false.
- show_timeout: Input can be any long value which accepts the value in milliseconds. This is the controller view timeout.
- fastforward_increment: Input can be any long value which accepts the value in milliseconds. This is used to skip the video playback position forward with the input value. The default value is 15 sec.
- rewind_increment: Input can be any long value which accepts the value in milliseconds. This is used for moving playback position backward with the input value. The default value is 5 sec.
- controller_layout_id: If a developer wants to make the design of controller by themselves then they can design any layout XML file and can pass it to controller_layout_id.
That’s all for this blog. This blog was all about the different types of events and how to customize some basic UI components of ExoPlayer.
Hope you enjoyed reading this blog. In case you have any queries, I would be happy to answer them. Drop them in the comments section below.