Media3 and Jetpack Compose: The Future of Media App Development in Android

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
imagine a world where your media apps are more immersive more powerful and simpler to build welcome to that world with media 3 the evolution of Android libraries you're probably head of exoplayer they go to Red rally for media playback in Android well hold on to your screens because exoplayer now has a new home and it's called media 3. say goodbye to the old ways with media 2. media 3 steps in with the promise of a simpler more consistent architecture Superior performance and enhanced reliability in this video we are going to guide you through the transition from media 2 to Media 3 and show you how to harness its potential you learn how to effortlessly play different media sources Master the art of UI customization and connect the dots with other jpeg gems so are you ready to dive into the world of media 3 make sure to hit that like button subscribe to our Channel and let's dive into the exciting world of J pass API when you are playing only an audio at the foreground or a media to foreground you'll have a simpler architecture like this one here so you have a UI and also you have a player so something like EXO player which is going to help us to play the audio so the UI is going to send up the commands to the player and the player here is going to send this stick to the UI if the audio is playing or the media is playing so here we can send commands like pose play and other things but the problem with this is that the Android OS doesn't understand that we are playing audio so we cannot use other controllers or the rich features of Android in order to control the playback so something like a good Google Assistant we cannot just use Google Assistant to post the play here so how can we solve this then basically we have to introduce a media session that can be advertised to the Android OS to let it know that we have a media playing so you can easily handle this outside of our application and this is just the foreground so what if we have a background and we want to play this in the background whenever we create our application so the architecture is going to be a little bit complex so for this case we have to separate the player and also the media differently so we have the service and also we have the activity so we have to introduce here the media session which can be easily used to play other complete our audio to other applications and also here we have the activity that is going to control this but one problem here which we have is that the player cannot communicate to the media session and the media controller cannot communicate directly to the UI so what we have to do is to introduce the connectors so these connectors here are going to help to translate the commands from the player to the media session and also the media controller to the UI in order to control our state so this architecture here is just really complex when you see here because this is going to introduce a lot of code and which is not just a simplest Snippets of course it's going to be a complex code so managing this is going to be difficult and I have already done the media tool video where I'm talking all about this so the media 3 is going to help us to solve this problem here of adding connectors by creating a cohesive regularly that we can easily Now integrate in our application that is easier to implement this architecture here our application can easily communicate to the Android OS and the Android OS card is going to address these two other applications something like a notification manager or for example we have other media payback state or UI that is going to be issued by Android we can easily use it to pause or play our audio so we have seen this with the previous API now let's look at the current API so with the current API we have a similar architecture which looks like this one which we're going to be playing at the background so now to solve the problem with media 3 as you have seen earlier there we had to introduce connectors that use to connect between EXO player and the media session and also the media controller and the UI so media3 implemented a common interface so for now here we have a common player interface that the exoplane is going to implement and also the media controller is going to implement which is going to make it easier whenever we want to build our application so we don't have to pass in connectors in order to translate the commands or to transport the controls for this case and as you can see here now this exoplayer is going to implement a player and this one here is going to take a player so the media session we can easily take the EXO player and also pass it to the media session and make it easier whenever we want to transport the controls and all also this one is going to implement a player and also this one is going to take up a player so as you can see here we have a cohesive regularly that is easy to implement and it's going to remove a lot of brayler plate codes so for this case the EXO player can directly communicate to the media session and the media controller can directly communicate to the UI so now we can entirely omit the connectors okay so enough Theory let's see how we can easily implement this architecture inside our application now let's get started okay so now before we get started here you have to get the initial project from GitHub repository so that we can have a common starting point so I have added and changed several things here so the major things which I have changed as you can see inside our theme I have added these colors here and I have generated this color from the material 3 generator and you can easily just get it when you Google material 3 and create your custom colors and here inside our theme I have made to use this this type of colors also the next thing which I have changed here is insidewill.gradophile I have had added the dependencies which are necessary to make application using media 3 now in any type of application the first thing which you want to get is the data so for this case let's create here a new package and call this data and inside here you can just substitute with different type of datas which you want to receive so for a case here we're going to get our data from our Android application so for this case we want to get it locally so we can create here a local so if you want to substitute this with a network calls you can just easily create a remote and for a case we're just going to get this from our local device that's what we're just creating here a local package now inside here let's create a new package and we can just call this model and inside here now let's just create a new coding class or file and we want to Define now our model okay so this data class here is going to hold up our ad audio data so for this case the first case which we want to obtain here is a URI so this URL is going to be a like a resource identifier that is going to help us to play this type of audio which we are going to receive and the next case here which you want to get is the display name okay so as you can see here we have a URI display name ID artist data duration and title which we can easily use inside the application now the next case is actually fetching the data and basically we can easily create a Content resolver that is going to help us to fetch the data so in order to fetch the data we have to use a Content resolver so I have already created an audio application using media 2 and demonstrating the same code which we are going to write it here so for this case I'm just going to copy the code from the GitHub project repository so when you navigate inside my GitHub you can see that I have this application here which is just audio player and just easily just select this and you want to change here the branch to the latest branch in order to get all of the data okay so now make sure you have changed here the branch to the latest branch and when you navigate inside here the data you'll find the content resolver and inside here the content resolver I have all of the data so we are just going to copy this and inside here our logo we can just easily paste this code here okay so the code after I imported everything so as you can see I have added this import now one thing if you want to understand this code more in depth you can easily check the video which is linked in the top corner here but here just that has one thing which is going to help us to retrieve the data from our database here inside the application so the first thing which we Define here is just the casa that is going to help us to select so this code is similar just an sqlite code that you can easily write in order to get the data so the first case here is we Define the projections so these are just something like the data which we want to select inside our database so for Casey we just select the display name the ID artist data duration and the title and here is we Define the selection close so as you can see here we want to Define if this is going to be the music because you can retrieve different type of data like photos and other things so for case we want to select this if this is going to be a music and we are using here a question mark so that we can prevent SQL injections because here you can just provide a data and then the hacker is going to obtain your application and then they can easily insert a an sqlite code here which is going to make it really bad so for this case it's just a good practice to provide a question mark which the Android OS is going to substitute this with the selection argument so for a case we just defined here the selection argument to be one which is just going to be true for this case is music and that space we can easily just return the music which is going to be selected and you can easily provide here the sort order so for case we want to sort order ascending by using the display name or you can just easily change it differently the next case here is we Define this function here which is just going to be called outside of this application outside of this class in order to access the data and basically here it's going to return us with the audio list which is just the model which we have defined inside here and they get a casa data here it's just there where the magic is going to happen so the first case here we are just defining here a mutable list now we use our casa here and initialize it so as you can see here we're using a con a context and get the content resolver and we want to query and what we want to query here we just provide the content URI which we want to select we provide the projection which we have defined here which are just the things which we want to select so for case it's just this data and the next case here is the selection close so this is just going to help us to filter the data by using this selection close here and then case here is just the selection order which is just the order which we have defined here the sort other other selection argument which is just going to be substituted with this question mark here and the next case is just the sort order which is just the order which we want to select then we use the casa in order to iterate through all of the data and get the specific ID column or the index which we want to get so for this case we use get column index or throw and provide the data which we have been providing here in order to gain every items inside our data so we can be returned with thousands or even millions of if a user has a lot of data inside the application so for this case we just use this index in order to obtain the each column index and obtain the rows and for this case we just use Casa dot apply and we want to check if the count is going to be equal to zero and this is just the function which is just going to be returned from the cathode from the casa if it's going to be equal to zero so we can just easily log here the casa data is going to be empty now the next case here inside we have the data if the count is not going to be equal to zero then we can easily just get the data so we are going to use here a while and inside here our oil we can just move to the next item inside our casa now we want to obtain it specifically each item inside our our index which we have inside our array which we are going to have or inside our casa so for this case we call Casa dot move index and for this case we are just going to obtain every data inside our inside our table or inside our list which has been returned and for this case we're just going to append it inside our audio list by using this initialization here and now everything is going to be added here so overall this code demonstrates how to use their Android content resolver query audio data from the external content provider so the process the class is going to return the results and construct the audio object based on the retrieved information so the resulting result of audio object is returned when they get audio data function is going to be called and for this case we can easily just use it inside our application okay so the next case here is just to define the repository so for this case we can just easily create here our repository inside here our data so let's just create a new putting class or file and here let's just call this Repository and inside here let's create a new coding class or file and we can easily just call this audio Repository okay so as you have notes here I'm using the new Android Studio UI you find it really good or not just let me know inside the comment so for this case here we want to inject here our audio and create here the Constructor so the first case we want to obtain the content resolver and here we can just use the content resolver helper so basically if you are just fetching the data from the Internet or from a remote Source then you can just substitute here with the data which you want to receive here and because we have Constructor injected then the data Hills is going to understand how to insert it so for case we can just create here a suspend function and call this get audio data and this is going to return us a list of audio which is just the audio which we have defined here and for this case we can just use with context and we want to use a we want to change the thread so for our case we want to use a dispatcher so it's IO okay so for this case we can just call here our content resolver dot get audio data which is just going to give us the data so this is just the method which we want to get our data so if you are using a remote data source just change this to what you are going to receive it or by using your data service and return the audio okay so the next case here we want to allow background playback so in order to allow background playback we have to include the service and the service is going to help us to manage this and for this case now let's just collapse this and create a new package inside here and inside here let's create a package called the player we're just going to include everything related to our player or our media player and inside here let's create a new package and we can just call this service and inside here let's create a new coding class of file and call this jet out your service okay so this is going to inherit from the media session service and this is going to help us to allow us to advertise our media sessions to for example the notification or through the Android OS by allowing to use these media sessions so for this case let's just inherit from the media session and you have to use the media session service here now the next case here we want to annotate this without Android entry point in order to allow dagger Hills to create the dependencies which we require okay as you can see here we have some errors and we have to press Ctrl I in order to inherit this one method and this is just going to give us the get sessions here okay so simply here what we want to do is to read an a media session and we're just going to implement this method at the moment but the first case here we want to inject the media sessions which we are going to use and because we are using dagger Hilt then we can just easily inject it so for a case let's create here letting it variable then call this media session and use the media session 3 here with media3 and let's annotate this with ADD inject okay so after we inject here our media session what we can easily just do here is return this media session here and we can just call here our media session and this is just the code which you require right now here to get your application functional release the media session whenever our service is going to be destroyed otherwise everything is going to go into messy so for this case after we override this on get session here we want to override the on Destroy in order to manage our data efficiently so for this case we can just call here our media session and the first case we want to release the resources because we are going to occupy the resources and we don't want our application to be consuming a lot of battery so for this case also we can just easily check here if so if our player is not in an idle state okay so as you can see here we are just checking here our state so if our state is not an idle State we want to stick to a zero position and we want to play this one already and also player.stop so as you can see here we can easily access the player by using just directly the media session and we don't have to create the connectors so if you understand Android media too you know this service here is going to be filled with a lot of code here in order to manage just the a simple thing here like releasing this audio player here okay so our service here is ready but one thing which is missing here is just the notification we want to be able to handle the player inside our notification so for this case let's create here a new package inside here our player okay now the first thing which we want to create here is just a notification manager so now let's create here a new coding class or file and we want to call this jet notification manager okay also this is just we're just going to inject here the Constructor and what we want to receive here is the context and we want also to be able to receive the context here so basically here we can just annotate this with that application context in order to tell Daga Health hey you want to get the application context and the next thing which we want to receive here is just the EXO player which is just going to be the player which we use inside the application now the first case here we want to Define some constants which we can easily use inside here now let's create here a private construct valve and we can just call this notification ID and you can just provide any type of ID so for my case I have provided this number now let's create another constant of all and we want to call the notification channel name let's press Ctrl D and here we want to create the notification Channel ID and here we can just add the ID in order to make the notification ID okay so here we want to create the notification manager so let's create here a private variable and this is just going to use the notification manager compact and we can use our context here in order to create this notification manager okay so the first case here we want to create the notification Channel okay now let's create here a private function I want to create a notification channel so for this case we can easily create a channel okay so you can just pass in here the notification Channel ID and also the notification channel name and here we can just provide the importance so we can just use our notification manager and use the important law so this one is going to help us to create the notification so for this case we can just call here our notification channel manager and one thing here we're just getting the errors because our minimum SDK is 24 and this requires us to have minimum API level of 26 so for this case we can just add here The annotation require build Os or which is just going to be primarily using API level 26 So Below this we are not creating a notification Channel okay so now let's use here our notification manager and create a notification Channel and for this case we can just pass in here our channel in order to create our notification okay so one thing which we want to do here let's create an init block or whenever we initialize this we want to create our notification channel so you can just call here or create notification Channel and we're getting here error also we have to handle this so we can just click here more action and we want to surround this with an if else statement so if you want to handle below this you can just add another statement but for case we're just handling here to create a notification channel so this is how you can easily manage apis differences in apis in Android so what we want to do also is to start the notification service in order to play the background we want to play our audio in the background so for this case we can easily just create a function and call this start notification set notification service and we want to receive here the media service the media session service and also the media sessions in order to control our audio playback here so as you can see this is how we advertise our media session to the notification manager okay so let's create here first a helper function that is going to help us to build the notification service so for this case let's just create here our private function and call this build notification and this requires us to obtain the media session okay so for this case we can just use our player notification manager okay so here we are getting error we are using here the player notification manager and this player notification manages just from media3 UI and why are we getting this error here when you hover around you can see we have to opt into the unstable apis so the media 3 has two types of apis so they have this table and their unstable apis so the stable apis these apis are not subject to changes in future and their unstable apis they might be changed in the future or removed in the future and because the code base of these apis are just really huge so the Android team cannot commit to manage all of this type of apis so that's why they choose the common functionality which they can easily commit and make them not changing so for this case this might be able to change whenever you upgrade to a new version so for this case we have to add The annotation here with at an unstable API and this does not indicate any type of performance or for example the quality of the apis so everything is really good and the performance is good but it might be subject to changes whenever you pump up your your vision okay so the next case here we want to define the media description adapter so for this case we can just all here set media description adapter and inside here we are just going to create our adapter so the next case here we can just add a we can set the small resource ID and basically I have a drawable for this so you can just use arrow. drawable you can use any type of ID here let's import this first so I have this microphone here to set it whenever we play inside our notification so you can add your logo or anything else and for this case we can just call Dot build and everything is going to be built so one thing which we want to Define here is the media description adapter so for this case let's just navigate inside our notification and create a new package okay now let's create here a new coding class or file okay the first case we have to annotate this with ADD unstable API because we're just going to be using those type of apis okay so the next case here will have to Define our Constructor here and we want to get for example the context here and also you want to pass in here depending intent okay so what we are going to do here is to use the notification manager so we want to inherit it from the player notification manager dot media's description adapter now let's implement the method which we want to get here okay so this is just our media description adapter and as you can see here we're just writing minimum code because we are just implementing this from our media 3 libraries so when we are using media truth libraries there are a lot of code in order to make this functional so you can just look inside our GitHub repository about the audio player which we created previously and you can just compare the amount of code which you have to write in order to obtain the same functionalities okay so for now here we can just use here our player but media metadata and we want to get the display title and if this is going to be another button we can just return here unknown as you can see we are just getting the current audio so if the display data is going to be null about then we're just going to return unknown and here we want to return the pending intent okay so the next case here is to get the context and for a case here we can just easily and here we can just call unknown so here basically we have to use the album title and not the display title because the display title here is just going to be the content text here okay so the last method which we have to implement here is just to get the large icon so if you have the image which you want to load here you can easily use a Glide in order to help you to load this because the bitmap here handling this is going to be quite challenging if you don't use a library so for a case we can just make our life easier by using Glide here so you can just call this width and pass in here the context which you want to receive and we want to call this as bitmap and this is going to help you and we can just call here.lot so if you have here the media you can just easily use it so you can just call here a player but media metadata dot artwork URI if you have it so if there is no then it's going not good to load the data okay so we can just provide here the disk cache strategy and for case we can just call here this catch strategy but all and call Dot into and here basically we have to override the method so we can just call here our object and we want to call the custom nugget and call the on bitmap and pass in here the resource and the last case here is the unload cleared here and otherwise we can just call return null in order to return null inside this method here so here we use our Glide in order to uh render our bitmap or if you have the artwork which you want to play so you can easily access the artwork and this one is going to help you render it by using Glide okay so we can just return here inside our jet audio notification manager so we have to set here the media description adapter and we have already created so you can just call here project audio and notification adapter and let's initialize it now let's provide here the context which is just going to be the context and also pass in here depending intent and for kiss we can just use here our media session dot session activity which is just going to help us to provide the the pending intent so whenever we click the notification is going to take us back to our application okay so the next case here we can just call Dot also function in order to have the data here now one thing we want to do is to set the media session token so we can just call here it dot media session token you want to set the media session token so for this case we can just call here a media session but session unpacked token in order to set it here so the next case here we want to customize our notifications so for this case we can just call here dot set use passed forward in the next case we want to set the priority or we can just use here the notification Compact and we want to use the Android X call and here we want to set the priority row and the last thing which we want to set here is just the player and we can just pass in here our EXO player to be the player which we are going to use now the next case we can just come here inside start notification and we want to build our notification we can just call here build the notification and here we can easily just pass in here our media session in order to build a notification and we want to all these unstable API here in order to remove the error the next case here we want to start the foreground service and this is just the notification for ground service in order to be able to pay this from the foreground so for this case let's create TI function and call this a stat okay let's also make this to be a private function because we are not going to use it outside of this class so for this case we want to create our notification and we can easily call here our notification and call Dot Builder now the next case here we can easily just pass in here the context and also the notification Channel ID you have our notification Channel ID and as you can see we are getting here an error so we can add require annotation all here in order to manage this okay so the next case here we have now our notification so we can just call here now dot set category and we want to call this category service and call Dot start for ground and basically here now we can just pass in here our notification Channel ID and also pass in here our notification okay now let's call here our media session service and we want to call Dot start service and basically here we want to start the foreground service notes service oh you want to call here stat foreground and basically we have to pass in here the ID and the notification so for the part of the ID we can just pass in here the notification ID and also pass in here our notification and everything here is looking perfectly so the next case after or below this bill notification here we can easily just now pass in here our start foreground foreground notification service and we have to pass in here our media session service and also here we can just add the at require annotation in order to handle this okay so here our notification manager is complete so it's just really simple here as you can see we have here a method that is going to help us to start the notification service so we build our notification here and also we start the foreground notification service by just calling this methods here and as you can see we can easily create here notification Channel by using this method so this is all what it takes in order to manage our audio player by using the notification so now our notification manager is complete so the next case here is we have to navigate back inside our jet audio service here and we want to hook up the notification so that we can easily start our notification we or we can just combine our service and the notification so for this case we have to get the reference to this notification and we can just annotate this without inject and create a red need variable and we want to call this notification manager and this is just going to be the audio the Jetta audio notification manager which we have created here now another thing which we can override here is just the onstart command so whenever this is going to be called so we want to start our notification so for this case above their own Super method we can just call here our notification channel manager and we want to call this start notification service and basically we have to pass in here the media service so for the media session we can just call here media session and for the media session service we can just pass in this okay so here we have an error and that is just managing our apis so for this case we can just click more action and we want to surround this with an if else's statement here in order to start our notification and the next case here we have to annotate this with ADD unstable API in order to opt in so for this case we can just call this unstable API and opt in and everything is looking perfectly So This Is What It Takes here in order to start our notification service okay so now most of our code is complete but one thing which is missing here is just the player interface which we have to implement in order to help us to set up the media and also to create our our playback listeners so for this case we have to go inside here our service and implement the player so let's create here a new coding class or file and we want to call this jet audio okay so here we have the jit audio service Handler so it's a Handler for managing audio playback using EXO player in an Android application so the class handles playback events date management and progress update so using this class here we can easily do this okay so for this case let's just inject here our Constructor and we want to receive the player so for this case let's create here private wow and we want to get our exoplayer and now we have to implement the player listener and here now we have to manage our state and also the events which are going to be occurring so we have the state for example whenever we want to play our audio and if our audio is ready or buffering or is in a progress or is actually playing so we have to manage this also we have the events like play or post selected audio changes for example and also backward and seeking two and other things which we have to implement so for this case below here we can just easily create our build interfaces for this case let's create here a cell the class and we want to call this jet audio speed okay so this is just going to be our state so the first case we can just initialize here our initial so here initially we don't have anything so we are just going to return our jet audio State here with nothing else okay the next case here is whenever our media is ready to play so we can just call this ready and basically here we can just get our duration and this is just going to be of type long and we inhale it from the jet audio State here okay the next case let's create here our data class and whenever we have the progress now we can just get the progress and this is just going to be of type long also this in heritages from the jet audio state okay now let's create another data class if we are buffering okay so the next case here is let's create a data class and here if we are playing so we can just call this plane and basically here let's create a variable and call this is playing and this is just going to be a Boolean and also inheritance from digit audio state and the last state which we want to track here is the current plane but we want to get the current playing audio so yes we can just call this current so the first case we want to get the media item index or the index of the items which is going to be playing and this is just going to be of type ins and this is just going to inherit from the Jetta audio state so these are just this state which we have so we have the initial State the ready progress buffering plane and also the current playing item or the media item and basically we are going to hold up the index for this case okay so we have here our date the next case is we want also to track the events which we have so we can just easily create a sld class and call this player events which are just the event that are going to be occurring okay so the first case here we can just create an object for play oppose and this is just going to inherit from the player event okay so the next case we can just create an object and this is just the selected whenever the selected audio is going to change then we want to inherit this okay the next case here is backward let's press Ctrl D and duplicate this now if we want to seek to next and the last one here is just the update progress so here we are going to use a data class and we can just call this update progress and here we can just call here our new progress and this is just going to be of type plot and inheritance from the player event as others so here you can add all of the events which you want so for my case these are just going to be enough here so we have play pose selected audio change backward whenever we want to go back stick to the next so if you want to seek to next and also forward here we can just easily forward our media if we want to seek to the another item so we can pass in here another item and also here we can just stop here in order to stop our player and here we are going to update our progress so these are just the events which we are going to require okay so here I'm creating a state and I'm just going to call this audio state and basically here we want to call our jetaudio state and our initial value we can just call here our jetaudio state DOT initial it's just going to give us the initial value and we can easily just import everything and here let's just change this and we can just call here audio state DOT as bad flow oh sorry as as a state flow okay so here we have our state for the audio State and basically we can just now start to use it the next case here we can just create a job so we can create a variable and call this job and by default here we can just make it to be null let's import this okay so here we have now our job and we can now start to create the media items which we want to okay so the next case here we want to create the method that is going to help us to add the media items so we can just call this add media item and basically pass in here the media item or we can easily just call here our EXO player and call set media item and pass in here a media item and the next case here we can just call exoplayer search prepare and everything here is ready to so this method here is going to add a single item so what if you have multiple items which you want to play so for this case you can just set the media item list so let's create AI function and call this and here we're just going to get the media items it is just going to be a list of media items okay so what we can do here we can just call here our exit layer and call set media items and basically pass in here the media items and call here our exoplayer dot prepare which is just going to prepare here okay now the next case here let's create a function that is going to help us to track the events so we can just call here suspend function and call this on player events okay so the parameters which we want to get here is just the player event which we are currently here and the next case here is just the selected audio and by default here we can just pass in here negative one and the next case here seek position and this is just going to be of type int and by default we're just going to pass in here zero okay so these are just the parameters which we require so the player event the selected audio index and the seek position are the position which we want whenever a user is going to change their okay now let's just pass in here a win statement and here we want to check the player events which has been provided from our UI and for this case we can just call here our player event now let's start here for example with backward so what we can do here we can just call here our EXO player let's seek back really simple as this the next case here is just the player event dot forward or we can just call here our exoplayer DOT seek forward and let's call here player event stick to next and we can just call here our EXO player put seek to next okay so the next case here is our player event dot play oppose okay so here we can just create a helper function that is going to help us to check the play oppose so let's just come below this now let's create here a private suspend function and call this play oppose let's check first if our EXO player if it's actually playing so here we want to use our EXO player we can just call here EXO player dot pause and one thing here we want to pose or stop our progress update and also start our progress update so let's create yarn else statement here and we can just call here our EXO player dot play if we are if we are not actually if our audio is not playing so we can just easily start to play and here we can just change our audio state so you can just call here our audio State DOT value and call here our date audio state DOT plane and here we can just check is playing and make it to be true so here we are changing our state so the next case here is we want to start the progress update and for this case we can just easily create here a function but let's create a function below create private suspend function and call this now we can just use here our job and you can call job.run so now we can check this while this is true we want to delay for 500 milliseconds before we send the new value so here we can just change our audio state and we can just call here with our progress and what we can do here we can just call our EXO player good current position which after 500 milliseconds here the position is going to be changed so we can emit the new value so this one is just going to be our start progress indicator the progress update sorry and the last case here we want to stop the progress for example if we have posed our media so for this case we can just call here our stop so here we can just call here our job.council and here now we can just call our audio state and here we can change the audio is plain so now here we have our methods so inside here I'll play oppose and let's change this to small function here so inside the r play of pools inside here whenever we post we want to stop our progress update so we can just call here the progress update and here inside our EXO player whenever we are playing we can just easily start our progress update and for this case here we can just call here a play oppose okay so the next case here we can just override here event and we want to check if we want to see two so you can just call this C2 and similarly here we can just call here our EXO player and here basically we can just pass in here the seek position which is just going to help us to seek us to this position here so we have to change this to long okay so the next case here is selected audio change whenever our audio changes so here we can easily now start to implement our method what we want to check here we can use a win statement again inside here we can check our selected audio index so if this selected audio index is going to be equal to the Alexa player.current media item index we know that we are just clicking the same audio so we want to pause and note that again so for this case we can just call here our play oppose method here so if the audio is playing actually we want to pause it now as if they selected audio index is not going to be equal to the current playing media so for this case we want to seek to another position or we want to to select that media so we can just easily call here EXO player dot seek to default position and here we have to pass in the media index but we can just call here our selected audio and the next case here we can just change our audio so you can change our audio state DOT value let's just call here RJ audio state and we can check here is playing and make it to be true the next case here we can just call here x sub player so to play when ready and we can make it to be true and here we can just call it start a progress update because here our EXO player is going to be starting so here we have the selected audio change let's create another event here which is just when we want to stop we can just call here stop and here we can easily just call the progress update okay so the last method which we have to accommodate here is whenever our player event is updating so you can just call here player event dot update progress and this is just a data class which is just different from other Medias which we use than object so here we have to use is in order to take this is going to be in this type of this class so if this is going to be the case so basically we can just go here we can just call here our EXO player go to seek to basically here now we want to provide our method so we can just call here our EXO player the duration and we want to multiply this with the new update so we can just call here a pair event dot new progress so we want to use the player event because we have a scope this so we can easily access the new progress here and we want to change these two floats too too too long sorry in order to get the update progress so here we never want to update our progress so basically we can just change here this seek to we can use our exoplayer duration and multiply this with the new progress and we want to change this to long in order to stick to that particular position so this is just our events which we have okay so managing our state here is uh almost complete so one thing which we want to do is to override the on playback State change here so we can just call here on playback State change okay so inside here we can use our win statement and what we want to do is to check the playback as state and now if our EXO player or we want to check if EXO player dot stage buffering so we know here our EXO player now is buffering so we can change our audio State we can just call here audio State DOT value and we want to change this to audio stage buffering so let's just call here audio state dot buffering okay so here we have to provide the progress so what we can do we can just call here our exoplayer but current position in order to get the current position the next case here is to check if our EXO player is in a state of buffering a state ready sorry or if it's ready to play then we have also to update our state so we can just call here dot value now we can just call here object audio state and call ready and basically pass in here our EXO player but duration in order to say hey we are ready to play here so this is how we can easily manage our state so we check here if we are buffering then we change our state here and if our state is ready then we can easily change our state now last method here which we want to override is whenever our audio is in a state of changing changing in a plane so for this case we have to override on is playing okay so whenever this method is going to be called we want to change our state first the audio state DOT value and we can just call here our jet audio State and call here plane and then here is playing is going to be equal to is playing also we have to change here our audio state and we want to change the current playing audio and basically we can just call here our EXO player dot current media item index now we want to start our progress uh for example whenever we are just playing we want to also to start our progress update and also if we are not playing we want to stop our progress update so for this case we can just write here the the if a statement and check if we are playing actually now here we can just use a global scope so you can create here a custom scope for this case though for my case just this is just a really simple tutorial so I can just call here a global scope but this is not a good practice because the global scope is not intended to be used here but uh let's just continue with this so we can just call here dispatcher.io and now here we can easily start our progress update and if it's not the case so we can just call here else sorry yeah we can just call here our else and stop our progress update so guys if you're finding value out of this video please don't forget to provide a like And subscribe for more so let's continue okay so our audio service Handler here is complete now so overall digit audio service Handler class serves as a mediator between the Android exoplayer library and the high level audio playback management of the application so it manages the playback events they transition and also progress updates it encapsulate the complexity of exoplayer and providing a cleaner interface for controlling our audio playback so on the previous video we managed to create here our audio repository our audio service and also our audio service Handler so in this video we are going to see how we can easily inject our data by using dagger health the last thing which is remaining here is just to create a new package here and we can just call this Di and inside here now let's create a new module and let's create here coding class or file and this is just going to be an object and we can just call this media module okay so here we have to annotate this with that module and we have to annotate this without the install in and we can just call here a single tone components after we tell here that hit that we want to make this class to be a module now we want to provide several things so the first case here is to provide the modules the audio attribute okay so first let's annotate this without provide and annotate this with ADD Singleton now let's create here a function and call this provide so this class here is going to return audio attributes and basically here now we can just call here our audio attributes dot Builder now we want to set the content type and we can just use here our C okay so after we import that value now we can just call here set usage and we want to call here C dot usage media and here basically we can just call Dot build okay so make sure you import the C here by using the Android as you can see this is Android X media3.com okay so after we provide this and just easily copy this press Ctrl C now we want to provide the EXO player so we can just create here let's paste this and create here a function and call this provide EXO player now the first case here we want to get that application context and pass in here our context the next case here is just the audio attributes and this is just going to return us with the EXO player now we can easily just call here our EXO player and call exoplayer.build and pass in here our context now the next case here we want to set the audio attributes okay so the next case here we can just set the track selector and here we can easily create here default track selector and pass in here our context and let's just call here.build in order to build this okay so one thing here we have to opt in at unstable API so we can just annotate this without unstable apis okay so the next case here we want to set something like handle forecast noisy forecast so this one is going to help us if we have for example an audio call or a notification is going to enter so you want to be able to Fed our audio so we can just call this set and audio focus becoming noisy and we can easily set this to be true and for this case here we have our exoplayer okay so the next case here we can just provide the media session so let's create here a function and call this provide media session okay also here we want to obtain the application context so we can annotate this with application context and obtain our context the next case here is to get the player which is just the exoplayer and this method is going to return us with the media media session here and we can just call here our middle session.builder and provide here our context now context and a player and call Dot build and everything here is looking perfectly okay so the next case here is to provide the notification manager so we can paste this here and create a function and call this provide okay now let's annotate this with that application context and pass in here our context and this is supposed to be contexts the next case here is just the EXO player and here we're just going to return our jit audio notification manager now we can just easily call here our jetaudio notification manager and we want to pass in here the context and the next case here we want to pass in the EXO player and we can just pass in here our player okay so the last method which we are required to provide here is the service Handler so we can just call this provide service Handler and it requires us to pass in here the EXO player okay and this method here is going to return us with the jetaudio service Handler okay so for this case here we can easily now use our jet audio let's create our jit audio service Handler and let's pass in here our EXO player and everything now is looking perfectly okay so guys everything here is looking perfectly so one thing here what we can do is just hit this make project here so that we can build and see if everything is working correctly we saw our build is successfully and everything is looking perfectly so what has remained here is just to hook up the UI part and the data part so for this case we are going to do this in the next video so if you find this video helpful please don't forget to provide a like And subscribe for more videos and if you have any questions and you thought you can easily leave them in the comment section below
Info
Channel: HoodLab
Views: 6,575
Rating: undefined out of 5
Keywords: media3, jetpack compose, android, media app, tutorial, app development, media playback, streaming, caching, offline support, UI design, animations, transitions
Id: XrcmjIW45u8
Channel Id: undefined
Length: 70min 6sec (4206 seconds)
Published: Fri Sep 01 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.