How Can Play Again Video in Exoplayer

Playing music or videos is a very popular activity on Android devices. There are several ways of providing media playback in your Android app and, in this tutorial, yous'll larn how to employ ExoPlayer to practise this.

ExoPlayer is a media playback library for Android which provides an alternative to Android'south MediaPlayer API. ExoPlayer is used past YouTube and Play Movies for video playback.

In this tutorial, you lot'll build an Android app that allows you to lookout man videos from Cloudinary'south complimentary cloud-based video direction solution. In the procedure, you lot'll acquire:

  • How to add a media player to your app.
  • How to customize the media player to fit your specific needs.
  • The best practices for media player architecture.
  • Additional capabilities ExoPlayer provides beyond the built in APIs.

Notation: This tutorial assumes that you are familiar with the basics of Android development. If you are completely new to Android development, read through our Start Android Development tutorials first.

Media Playback on the Android Framework

Audio and Video

First, you'll practice a little experiment. Have out your mobile device and count the number of apps you interact with on a regular footing. How many of them take the ability to play some kind of media? In fact, count how many of them don't accept that possibility. Y'all may detect that the number is zero — it seems every single app a user interacts with on a daily basis can play some kind of media. This demonstrates just how important and popular media playback is on mobile devices.

Only no matter the media type, they all take one matter in common: They have to become the media from somewhere to play it on your device.

Media used in an app can be stored on the local device's storage. That same app tin likewise allow you to stream the media from the Internet; in that instance, some remote spider web server is a media source. Media can as well be bachelor through many other streaming technologies, merely that's beyond the telescopic of this tutorial.

And then how do you play the media from any source? Earlier the hands-on function of this tutorial, you'll get-go cover the dissimilar ways media can exist played on the Android framework.

Playing Media on Android

The Android framework provides several options for media playback, covered beneath.

Sending Implicit Intent

An Intent represents an app's "intent to do something." Every bit with all implicit Intentdue south, you take to specify a full general activeness that you want to perform.

For media playback, yous must specify the ACTION_VIEW. You also have to include a URI of the media sample that you want to play. If there's an app on the device that tin can handle that media blazon, the Android organisation launches it. This is useful for very unproblematic utilize cases, the downside is you don't play the media within your app — yous use another app on the device that was built to handle the Intent.

YouTube Player API

To play a YouTube video, you can send an implicit Intent to launch the YouTube app, which will then play a video. But you don't have to do that. The YouTube Android Player API provides an embedded player to play YouTube videos straight in your app, and it gives you the possibility to customize the playback experience. This is useful if your use case is to play videos specifically from YouTube.

MediaPlayer

The Android multimedia framework includes support for playing a variety of mutual media types so that you tin easily integrate audio, video and images into your apps. The MediaPlayer class is the primary entry point for playing audio and video. Information technology supports the virtually mutual audio and video formats and data sources and because of that is good enough for many simple employ cases. MediaPlayer is besides very straightforward to use, but the downside is that it supports very petty customization.

ExoPlayer

ExoPlayer is an open-source library that provides an culling to Android's MediaPlayer API for playing audio and video. ExoPlayer supports features non supported past Android's MediaPlayer API, which yous'll come across later, and information technology's too piece of cake to customize and extend.

Because of that, ExoPlayer is recommended for media player apps of any complexity on Android. ExoPlayer'due south standard sound and video components are built on Android's MediaCodec API, which was released in Android 4.1 (API level sixteen), which means ExoPlayer tin can simply exist used on devices running Android four.1 or greater. This is also what you lot'll apply in this tutorial.

Custom Thespian

Information technology is also possible to create a custom media thespian from low-level media APIs. The downside of this is that it'southward very complicated and, in most cases unnecessary, other media-playing possibilities are adept plenty for almost every use case. Don't reinvent the bike. :]

Dancing Android

Getting Started

To show you how to implement ExoPlayer in an app, yous'll create a simple app called FunTime that allows you to play videos from Cloudinary straight from the app.

You'll use sample videos from Cloudinary as your media source. Yous're not required to create an account for this library.

Download the materials for this tutorial using the Download Materials push at the acme or bottom of the page. Open the starter project in Android Studio 3.0 or greater.

Now, build and run your app to make sure everything works as expected.

You should get a screen like this:
Starter project

Project Construction

It'southward helpful to go through the project construction briefly, so you'll exercise that now.

Project Structure

The bundle names are pretty self-explanatory, but in that location are a few things that yous need to notice, hither.

The app is written using the Model-View-Presenter (MVP) architectural pattern. MVP is great manner of organizing your lawmaking in Android. Some of import advantages of using MVP are:

  • It provides a clear separation of responsibilities betwixt components which allows for easier understanding and maintenance of the lawmaking base.
  • MVP provides a modular approach which allows you to switch to a different implementation of a view component in order to completely alter the application's UI, while all other components remain intact.
  • Easier testing. Since there are well divers boundaries between components, it becomes much easier to exam each component in isolation (due east.thou. by mocking other components).

Calculation a Media Histrion to the Application

The main screen shows you a listing of sample video names that are fetched from Cloudinary.

When you lot click on a list particular VideoViewActivity launches, merely shows nothing in the starter project. This is where your video is going to be displayed.

Calculation the Dependency

Recall that ExoPlayer is a library, in order to apply it y'all have to add it to the projection first. The ExoPlayer library is split into modules to permit developers to import only a subset of the functionality provided by the total library. The benefits of depending on only the modules you need are that you become a smaller APK size and you don't include the features in your app that you aren't going to utilize.

These are the available modules and their purpose:

  • exoplayer-core: Core functionality (required).
  • exoplayer-dash: Support for Nuance content.
  • exoplayer-hls: Back up for HLS content.
  • exoplayer-smoothstreaming: Support for SmoothStreaming content.
  • exoplayer-ui: UI components and resources for use with ExoPlayer.

It's yet possible to depend on the full library if you prefer which is equivalent to depending on all of the modules individually.

For the sake of simplicity we'll add the full library.

Open up your app module level build.gradle file and add the post-obit dependency to the dependencies block:

implementation 'com.google.android.exoplayer:exoplayer:' + projection.ext.exoPlayerVersion

The ExoPlayer version constant is already added to the project level build.gradle file so you can only use that version.

Sync the project after adding the dependency.

Creating the View

Next, yous'll create the view. If yous were using Android's MediaPlayer API you would display videos in a SurfaceView. The ExoPlayer library provides it's own high level view for media playback. It displays video, subtitles and album fine art, and besides displays playback controls.

To add it, open the activity_video_view.xml layout file from res/layout and replace the contents with the following:

<?xml version="ane.0" encoding="utf-eight"?> <android.support.constraint.ConstraintLayout     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context=".ui.video.VideoViewActivity">    <com.google.android.exoplayer2.ui.PlayerView     android:id="@+id/ep_video_view"     android:layout_width="match_parent"     android:layout_height="wrap_content"     app:layout_constraintBottom_toBottomOf="parent"     app:layout_constraintEnd_toEndOf="parent"     app:layout_constraintStart_toStartOf="parent"     app:layout_constraintTop_toTopOf="parent" />  </android.support.constraint.ConstraintLayout>        

Open the VideoViewActivity.kt file in the iu.video package and add together a property for the PlayerView:

private lateinit var videoView: PlayerView

Initialize the view in the init() method:

videoView = findViewById(R.id.ep_video_view)

Creating the Player

Since you're using the MVP pattern in this projection, you will decouple the view from the player. Start by creating a new com.raywenderlich.funtime.device.player package.

Inside this parcel, create a MediaPlayer interface, which is going to describe the behavior for the media player, and a MediaPlayerImpl class, which will contain the concrete implementation of your media histrion. Make the MediaPlayerImpl class implement the MediaPlayer interface.

Using the MediaPlayer interface makes swapping thespian implementations a breeze. You might want to explore creating alternate implementations without using ExoPlayer to explore the Android Media APIs more than deeply.

Now, open the MediaPlayerImpl grade. Offset, you need to initialize your player.

Add together a holding called exoPlayer for the actor:

private lateinit var exoPlayer: ExoPlayer

Besides add a belongings for the context that you'll ready and use later on:

individual lateinit var context: Context

Side by side, add the initializePlayer() method where you're going to create a new instance of ExoPlayer and assign it to the exoPlayer fellow member variable.

You can create an ExoPlayer instance using ExoPlayerFactory. The factory provides a range of methods for creating ExoPlayer instances with varying levels of customization. Simply, for most use cases, y'all should utilise 1 of the ExoPlayerFactory.newSimpleInstance methods.

Initialize exoPlayer in the method like this:

private fun initializePlayer() {    val trackSelector = DefaultTrackSelector()   val loadControl = DefaultLoadControl()   val renderersFactory = DefaultRenderersFactory(context)    exoPlayer = ExoPlayerFactory.newSimpleInstance(       renderersFactory, trackSelector, loadControl) }        

ExoPlayerFactory.newSimpleInstance() takes three parameters:

  • A RenderersFactory that creates renderer instances for use by ExoPlayer; they render media from some stream.
  • A TrackSelector is responsible for selecting tracks to be consumed past each of the role player'south renderers.
  • A LoadControl that controls the buffering of the media.

Don't worry about the specifics of these classes; using the default classes works perfectly in near use cases.

Crawly, you created an instance of the ExoPlayer!

You desire your player to accept the power to play media, so describe that in the MediaPlayer interface past calculation the post-obit method:

fun play(url: String)

Implement that method in the MediaPlayerImpl class.

This is how you lot play the media with ExoPlayer:

override fun play(url: String) {   //1   val userAgent = Util.getUserAgent(context, context.getString(R.string.app_name))   //two   val mediaSource = ExtractorMediaSource       .Manufacturing plant(DefaultDataSourceFactory(context, userAgent))       .setExtractorsFactory(DefaultExtractorsFactory())       .createMediaSource(Uri.parse(url))   //three   exoPlayer.prepare(mediaSource)   //4   exoPlayer.playWhenReady = true }        

Going through this stride by step:

  1. A UserAgent is just a cord that is generated for y'all based on the given awarding name and library version. You'll utilize information technology in next step.
  2. In ExoPlayer, every slice of media is represented by a MediaSource. To play a piece of media, you must get-go create a corresponding MediaSource. Again, there's a factory for media source cosmos that takes a data source mill as a parameter. Data source is a component from which streams of data can be read. Yous accept to set the ExtractorsFactory, which just returns the assortment of extractors. An Extractor extracts media data from a container format. Don't worry about the specifics of these classes, since using the default classes works perfectly in most use cases. What'southward important here is the createMediaSource() method which takes a Uri of the media that you want to play. In this instance yous'll play the media from a remote server.
  3. You lot need to call the prepare() method on the ExoPlayer example. This method prepares the actor to play the provided media source.
  4. Finally, by setting the playWhenReady variable to truthful or imitation, y'all actually tell the role player to play the media when it's ready. If the player is already in the fix state, and so this method tin can be used to pause and resume playback.

You have at present initialized the actor and yous accept the view. What's next?

Attaching the Thespian to a View

Attaching the player to the view is very straightforward. You only ready the ExoPlayer instance on the thespian view that yous added to the xml by calling the setPlayer(...) method.

Since you're using MVP and you're decoupling the concrete actor implementation from the view, you need a way to go the underlying player implementation.

Add together a method to the MediaPlayer interface that will give yous access to the underlying implementation:

fun getPlayerImpl(context: Context): ExoPlayer

Implement that method in MediaPlayerImpl class:

override fun getPlayerImpl(context: Context): ExoPlayer {   this.context = context   initializePlayer()   return exoPlayer }        

Now, you have access to the ExoPlayer implementation. VideoViewActivity volition get the ExoPlayer case through VideoViewPresenter.

Add a getPlayer() method to the VideoViewContract.Presenter interface in the ui.video package, which returns a MediaPlayer instance:

fun getPlayer(): MediaPlayer

Add together a media player property to the VideoViewPresenter:

private val mediaPlayer = MediaPlayerImpl()        

Implement the getPlayer() method, which will just return the media thespian instance:

override fun getPlayer() = mediaPlayer

In VideoViewActivity, set the histrion on the view inside the init() method by calling:

videoView.player = presenter.getPlayer().getPlayerImpl(this)

To really play the video, add together a play() method to the VideoViewContract.Presenter interface and laissez passer in the media url:

fun play(url: String)

At present, implement that method in the VideoViewPresenter. This method just delegates media playing to media player.

override fun play(url: String) = mediaPlayer.play(url)

Dandy, now you're ready to play the video.

At the end of VideoViewActivity'southward init() method, tell the presenter to play the video:

presenter.play(videoUrl)

It's important to release the player when it's no longer needed, in order to gratuitous up limited resources, such equally video decoders, for use by other apps. This can be done by calling ExoPlayer.release().

Add a releasePlayer() method to the MediaPlayer interface:

fun releasePlayer()

And implement it in the MediaPlayerImpl class:

override fun releasePlayer() {   exoPlayer.stop()   exoPlayer.release() }        

Add the releasePlayer() method to the VideoViewContract.Presenter, equally well, and implement information technology in the VideoViewPresenter course:

override fun releasePlayer() = mediaPlayer.releasePlayer()

You demand to brand sure that VideoViewActivity releases the player when information technology is no longer the active Activeness.

To exercise this, you release the player in onPause() if on Android Marshmallow and below:

override fun onPause() {   super.onPause()   if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {     presenter.releasePlayer()  } }        

Or release in onStop if on Android Nougat and above because of the multi window support that was added in Android Due north:

override fun onStop() {   super.onStop()   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.North) {     presenter.releasePlayer()  } }        

Build and run your app to encounter what happens.

Click on any item in the list and you will become a screen like this:

Playing Video

Now you tin can play video. Awesome. :]

Judge nosotros're washed here, right? Not still.

Customizing ExoPlayer

If you lot take a look at the UI of ExoPlayer, it'due south minimalistic. Adjacent, you'll brand information technology nice and shiny.

The ExoPlayer library is designed specifically with customization in mind. That's a huge advantage of ExoPlayer: yous tin customize nigh anything. The ExoPlayer library defines a number of interfaces and abstract base classes that make it possible for app developers to easily replace the default implementations provided by the library.

In your app, yous'll customize the user interface.

Changing the Appearance

Video is displayed in the PlayerView in XML. PlayerView is a loftier level UI component for media playback which displays the video and playback controls. Playback controls are displayed in a PlaybackControlView. Those elements back up a diversity of XML attributes, which yous tin use to customize the wait of the UI.

Yous can besides override the default layout files. When these views are inflated, they use specific layout files that determine how the UI will look. Y'all'll change the appearance of the playback controls.

When PlaybackControlView is inflated, it uses exo_playback_control_view.xml. Create a new XML layout file in the res/layout binder and name it exo_playback_control_view.xml. This volition override the default file.

Update the file to the following:

<?xml version="i.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:layout_gravity="lesser"  android:background="#CC000000"  android:layoutDirection="ltr"  android:orientation="vertical">   <LinearLayout    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:gravity="centre"    android:orientation="horizontal"    android:paddingTop="4dp">     <ImageButton      android:id="@id/exo_rew"      way="@way/ExoMediaButton.Rewind" />     <ImageButton      android:id="@id/exo_play"      style="@style/CustomExoMediaButton.Play" />     <ImageButton      android:id="@id/exo_pause"      style="@style/CustomExoMediaButton.Pause" />     <ImageButton      android:id="@id/exo_ffwd"      style="@fashion/ExoMediaButton.FastForward" />  </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:includeFontPadding="simulated"      android:paddingLeft="4dp"      android:paddingRight="4dp"      android:textColor="#FFBEBEBE"      android:textSize="14sp"      android:textStyle="assuming" />     <com.google.android.exoplayer2.ui.DefaultTimeBar      android:id="@id/exo_progress"      android:layout_width="0dp"      android:layout_height="26dp"      android:layout_weight="1" />     <TextView      android:id="@id/exo_duration"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:includeFontPadding="false"      android:paddingLeft="4dp"      android:paddingRight="4dp"      android:textColor="#FFBEBEBE"      android:textSize="14sp"      android:textStyle="bold" />   </LinearLayout> </LinearLayout>        

These changes customize how the Play and Pause buttons look. Open styles.xml and view the custom styles for those buttons. The default styles change the drawable source that is displayed and brand the buttons a little chip bigger.

<fashion name="CustomExoMediaButton">    <item name="android:background">?android:attr/selectableItemBackground</detail>    <particular name="android:scaleType">fitXY</detail>    <item name="android:layout_width">@dimen/video_view_exo_player_play_pause_button_dimen</item>    <item name="android:layout_height">@dimen/video_view_exo_player_play_pause_button_dimen</particular> </style>  <way proper noun="CustomExoMediaButton.Play">    <item name="android:src">@drawable/ic_play_circle_filled</item> </fashion>  <fashion name="CustomExoMediaButton.Pause">    <item proper noun="android:src">@drawable/ic_pause_circle_filled</item> </manner>        

Build and run your app and play a video to see what it looks like.

Custom Appearance

OK, it's not as dainty and shiny as yous might have hoped, only experience free to change the styles if yous want to run into a more dramatic change. :]

There is a pocket-sized consequence with this approach. Since you lot overrode the default XML layout file, all instances of the PlaybackControlView in your app will be customized like this. If you don't want this behavior, you can customize individual instances every bit well. You can use the controller_layout_id attribute in the XML to specify a custom layout file for individual instances.

Pros and Cons of ExoPlayer

The biggest advantages of ExoPlayer are its flexibility and rich feature stack, but that too makes it harder to work with it.

Since you can customize the thespian to suit well-nigh every use case, ExoPlayer is the best choice for complex utilise cases. For simple use cases at that place really isn't a reason to apply ExoPlayer, MediaPlayer will suffice.

For audio-only playback on some devices, ExoPlayer may swallow significantly more bombardment than MediaPlayer.

Ane more advantage of MediaPlayer over ExoPlayer is that MediaPlayer works all the style back to the first of Android, while ExoPlayer is only available on Jelly Bean and above. Merely I wouldn't phone call this a problem since there's only nigh i% of active devices running earlier versions.

Where to Become From Here?

You lot covered a lot in this tutorial, only ExoPlayer has many other possibilities and avant-garde features that aren't mentioned hither. In general, if at that place is something that yous tin can't do with Android's MediaPlayer there'due south a high probability that you can do it with ExoPlayer. Therefore, ExoPlayer is often the best choice for media playback on Android.

Nevertheless, be conscientious of over-engineering science! You must be thinking at present: "ExoPlayer is crawly, I'll utilize it all the time!" Before y'all do that, ask yourself this: "Do I really need an ExoPlayer?" Say yous have a killer app thought. You want to brand an app that plays dizzy audio effects. Do yous really need ExoPlayer here? ExoPlayer has many cool features, simply in this instance you don't need it. You but demand a way to play a very unproblematic sound. Android's MediaPlayer would be a ameliorate choice. Don't over-engineer things!

The FunTime app was just ane example of how you can play videos from a remote web server in your app. If you want to check out other features of ExoPlayer and run into how to implement those, Google'southward codelab is a good place to showtime. You can check it out here.

We promise yous enjoyed this tutorial and learned something from information technology. If you have any question or comments, or y'all desire to share your experience with ExoPlayer, please bring together in the give-and-take below.

danielssperady86.blogspot.com

Source: https://www.raywenderlich.com/5573-media-playback-on-android-with-exoplayer-getting-started

0 Response to "How Can Play Again Video in Exoplayer"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel