Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Let's Stream that Video - an ExoPlayer Starters...

Let's Stream that Video - an ExoPlayer Starters Guide

DroidCon India 2019

Have you ever thought how much work it is to build a streaming video player as robust as YouTube? Have you ever wondered how to play a video with subtitles and multiple audio tracks like Netflix? How does YouTube do streaming which adapts the video quality based on your network speed?

In this talk, we will take a look at ExoPlayer - Android's open-source video player which allows video streaming with minimal efforts from the developer side. We will take a brief look at what are the limitations of the MediaPlayer API provided by the android system and the advantages of using ExoPlayer. We will understand how to stream video, add subtitles, enable multiple language audio selections.

We will also understand how the ExoPlayer can help us in playing video in a flaky network. We will take a look at how to customize the UI for Video Player.

Bedanta Bikash Borah

November 02, 2019
Tweet

More Decks by Bedanta Bikash Borah

Other Decks in Programming

Transcript

  1. About this talk How many of you have watched a

    video on ExoPlayer? How many of you have watched a video on YouTube or Netflix?
  2. Create Video URI val videoURL = Uri.parse("https:!"myVideosmall.mp4") val surfaceView =

    findViewById<SurfaceView>(R.id.surface_view) val mediaPlayer = MediaPlayer.create(context, videoURL, surfaceView.ho mediaPlayer.start() Play video using MediaPlayer
  3. val videoURL = Uri.parse("https:!"myVideosmall.mp4") val surfaceView = findViewById<SurfaceView>(R.id.surface_view) val mediaPlayer

    = MediaPlayer.create(context, videoURL, surfaceView.ho mediaPlayer.start() Find Surface Play video using MediaPlayer
  4. val videoURL = Uri.parse("https:!"myVideosmall.mp4") val surfaceView = findViewById<SurfaceView>(R.id.surface_view) val mediaPlayer

    = MediaPlayer.create(context, videoURL, surfaceView.ho mediaPlayer.start() Create Media Player Play video using MediaPlayer
  5. val videoURL = Uri.parse("https:!"myVideosmall.mp4") val surfaceView = findViewById<SurfaceView>(R.id.surface_view) val mediaPlayer

    = MediaPlayer.create(context, videoURL, surfaceView.ho mediaPlayer.start() Start Media Player Play video using MediaPlayer
  6. • BlackBox • No customisation • Slow updates • Good

    for simple use-cases • Easy Implementation • No size overhead The Bad The Good Media Player
  7. ✓ Open Source ✓ Fewer device specific issues. ✓ Updatable

    with application. ✓ Highly customisable. ✓ Support for Widevine common encryption. ✓ Support for DASH, HLS and Smooth Streaming. Advantages of ExoPlayer
  8. Globally override xml Playback Control View exo_playback_control_view.xml Play : @id/exo_play

    Pause : @id/exo_pause Fast forward : @id/exo_ffwd Rewind : @id/exo_rew
  9. Exo Player HttpDataSource Track Selector Load Control Video Renderer Audio

    Renderer Media Source Renderer Exo Player Internals
  10. Exo Player HttpDataSource Track Selector Load Control Video Renderer Audio

    Renderer Media Source Renderer Exo Player Internals
  11. Exo Player HttpDataSource Track Selector Load Control Video Renderer Audio

    Renderer Media Source Renderer Exo Player Internals
  12. Exo Player HttpDataSource Track Selector Load Control Video Renderer Audio

    Renderer Media Source Renderer Exo Player Internals TG
  13. Exo Player HttpDataSource Track Selector Load Control Video Renderer Audio

    Renderer Media Source Renderer Exo Player Internals TG RC RC
  14. Exo Player HttpDataSource Track Selector Load Control Video Renderer Audio

    Renderer Media Source Renderer Exo Player Internals TG RC RC
  15. Exo Player HttpDataSource Track Selector Load Control Video Renderer Audio

    Renderer Media Source Renderer Exo Player Internals TG RC RC TS
  16. Exo Player HttpDataSource Track Selector Load Control Video Renderer Audio

    Renderer Media Source Renderer Exo Player Internals TS
  17. Exo Player HttpDataSource Track Selector Load Control Video Renderer Audio

    Renderer Media Source Renderer Exo Player Internals TS
  18. Load Control Exo Player HttpDataSource Video Renderer Audio Renderer Track

    Selector Renderer Media Source Exo Player Internals
  19. Load Control Exo Player HttpDataSource Video Renderer Audio Renderer Track

    Selector Renderer Media Source Exo Player Internals
  20. Load Control Exo Player HttpDataSource Video Renderer Audio Renderer Track

    Selector Renderer Media Source Exo Player Internals
  21. Load Control Exo Player HttpDataSource Video Renderer Audio Renderer Track

    Selector Renderer Media Source Exo Player Internals
  22. Load Control Exo Player HttpDataSource Video Renderer Audio Renderer Track

    Selector Renderer Media Source Exo Player Internals
  23. Load Control Exo Player HttpDataSource Video Renderer Audio Renderer Track

    Selector Renderer Media Source Exo Player Internals
  24. Load Control Exo Player HttpDataSource Video Renderer Audio Renderer Track

    Selector Renderer Media Source Exo Player Internals
  25. Load Control Exo Player HttpDataSource Video Renderer Audio Renderer Track

    Selector Renderer Media Source Exo Player Internals
  26. Load Control Exo Player HttpDataSource Video Renderer Audio Renderer Track

    Selector Renderer Media Source Exo Player Internals
  27. Creating Playlist val firstSource = ProgressiveMediaSource.Factory() .createMediaSource(firstVideoUri) val secondSource =

    ProgressiveMediaSource.Factory() .createMediaSource(secondVideoUri) val concatenatedSource = ConcatenatingMediaSource(firstSource, secondSource)
  28. Creating Playlist val firstSource = ProgressiveMediaSource.Factory() .createMediaSource(firstVideoUri) val secondSource =

    ProgressiveMediaSource.Factory() .createMediaSource(secondVideoUri) val concatenatedSource = ConcatenatingMediaSource(firstSource, secondSource)
  29. Creating Playlist val firstSource = ProgressiveMediaSource.Factory() .createMediaSource(firstVideoUri) val secondSource =

    ProgressiveMediaSource.Factory() .createMediaSource(secondVideoUri) val concatenatedSource = ConcatenatingMediaSource(firstSource, secondSource)
  30. Creating Playlist val firstSource = ProgressiveMediaSource.Factory() .createMediaSource(firstVideoUri) val secondSource =

    ProgressiveMediaSource.Factory() .createMediaSource(secondVideoUri) val concatenatedSource = ConcatenatingMediaSource(firstSource, secondSource)
  31. Play only a part of Video ProgressiveMediaSource.Factory(..).createMediaSource(videoUri) val clippingSource =

    ClippingMediaSource( videoSource, '( startPositionUs= )* 15000000, '( endPositionUs= )* 20000000 )
  32. Play only a part of Video ProgressiveMediaSource.Factory(..).createMediaSource(videoUri) val clippingSource =

    ClippingMediaSource( videoSource, '( startPositionUs= )* 15000000, '( endPositionUs= )* 20000000 )
  33. Play only a part of Video ProgressiveMediaSource.Factory(..).createMediaSource(videoUri) val clippingSource =

    ClippingMediaSource( videoSource, '( startPositionUs= )* 15000000, '( endPositionUs= )* 20000000 )
  34. Add Subtitle to a video val videoSource = ProgressiveMediaSource.Factory(...) .createMediaSource(videoUri)

    val subtitleSource = SingleSampleMediaSource.Factory(...) .createMediaSource(subtitleUri, subtitleFormat, C.TIME_UNSET) val mergedSource = MergingMediaSource(videoSource, subtitleSource)
  35. Add Subtitle to a video val videoSource = ProgressiveMediaSource.Factory(...) .createMediaSource(videoUri)

    val subtitleSource = SingleSampleMediaSource.Factory(...) .createMediaSource(subtitleUri, subtitleFormat, C.TIME_UNSET) val mergedSource = MergingMediaSource(videoSource, subtitleSource)
  36. Add Subtitle to a video val videoSource = ProgressiveMediaSource.Factory(...) .createMediaSource(videoUri)

    val subtitleSource = SingleSampleMediaSource.Factory(...) .createMediaSource(subtitleUri, subtitleFormat, C.TIME_UNSET) val mergedSource = MergingMediaSource(videoSource, subtitleSource)
  37. Add Subtitle to a video val videoSource = ProgressiveMediaSource.Factory(...) .createMediaSource(videoUri)

    val subtitleSource = SingleSampleMediaSource.Factory(...) .createMediaSource(subtitleUri, subtitleFormat, C.TIME_UNSET) val mergedSource = MergingMediaSource(videoSource, subtitleSource)
  38. Apk Size class Mp4ExtractorsFactory : ExtractorsFactory { override fun createExtractors():

    Array<Extractor> { return arrayOf<Extractor>(Mp4Extractor()) } } ProgressiveMediaSource.Factory(mediaDataSourceFactory, Mp4ExtractorsFactory()) .createMediaSource(uri)
  39. Apk Size class Mp4ExtractorsFactory : ExtractorsFactory { override fun createExtractors():

    Array<Extractor> { return arrayOf<Extractor>(Mp4Extractor()) } } ProgressiveMediaSource.Factory(mediaDataSourceFactory, Mp4ExtractorsFactory()) .createMediaSource(uri)
  40. Apk Size val player = ExoPlayerFactory.newSimpleInstance( context, AudioOnlyRenderersFactory(context), trackSelector )

    class AudioOnlyRenderersFactory : RenderersFactory { override fun createRenderers($%&): Array<Renderer> { } }
  41. Apk Size val player = ExoPlayerFactory.newSimpleInstance( context, AudioOnlyRenderersFactory(context), trackSelector )

    class AudioOnlyRenderersFactory : RenderersFactory { override fun createRenderers($%&): Array<Renderer> { } }