Android SDK (Core)
Integrate External Player
Integrating ExoPlayer
5 min
the external exoplayer is now deprecated we strongly encourage you to switch to our custom player, nwplayer please consult the migration section for detailed instructions on how to migrate from external exoplayer to nwplayer we, nativewaves ag, have designed our sdk to integrate seamlessly with your custom exoplayer implementation by leveraging our observer feature, you can smoothly inject your version of exoplayer into the sdk’s playback process, ensuring a tailored experience for your users this observer is intelligently designed to activate at key moments, ensuring optimal synchronization with the sdk’s lifecycle and usage scenarios initialization the observer is triggered during the initialization phase of audio or video players, setting the stage for immediate playback needs switching tracks it also reactivates whenever a switch in video or audio (if applicable) tracks allows dynamic content changes without interrupting the user experience below, we have provided a code snippet to help you understand how to observe the signal and inject your exoplayer instance while this example demonstrates one way to achieve this, feel free to adapt it to fit your application’s architecture and requirements code breakdown here is the provided code snippet expplayback expinitializeplayer collect { deferred > val success = deferred complete(externalexoplayer generateexoplayer(context) if (success) { log d("sampleapp", "successfully sent exoplayer instance") } else { log e("sampleapp", "failed to send exoplayer instance") } } let us break it down step by step expinitializeplayer sharedflow\<completabledeferred\<exoplayer>> this is a sharedflow that emits completabledeferred\<exoplayer> objects a sharedflow is a kotlin coroutine construct that allows multiple collectors to receive the same data stream in this case, it signals when it is time to initialize and inject your exoplayer instance completabledeferred is a special type of deferred that can be manually completed it acts as a promise, allowing the sdk to wait for your exoplayer instance to be ready before proceeding with playback collect { deferred > } the collect function is used to observe the sharedflow whenever a new completabledeferred is emitted, the code inside the collect block is executed deferred complete(generateexoplayer()) you generate your custom exoplayer instance using the generateexoplayer() function (which you must implement) the complete function is then called on the completabledeferred object to provide the sdk with your exoplayer instance the complete function returns a boolean indicating the operation’s success success and error logging (optional) if the complete operation is successful, a log message is printed using timber d to confirm that the exoplayer instance was sent successfully if it fails, an error message is logged using timber e to help you debug the issue why use completabledeferred and sharedflow ? completabledeferred this bridges your code and the sdk it allows the sdk to wait for your exoplayer instance to be ready before proceeding, ensuring that playback starts smoothly without timing issues sharedflow this creates a reactive stream that multiple collectors can observe it ensures the sdk can signal your code at the right moments (e g , during initialization or stream switches) without tightly coupling your implementation to the sdk’s internal logic if you do not implement the observer, your event will not use your exoplayer; instead, it will run on our sdk's internal player be careful when calling the collect {} function it should be called only once; otherwise, you may experience abnormal behavior while streaming any event conclusion this mechanism provides a decoupled and flexible way to integrate custom exoplayer instances into your application using our observer feature, you can enhance our sdk’s video and audio playback capabilities with your tailored solutions, ensuring your users' seamless and personalized experience