I spend a year building Picasso for Video and here is it

I spend a year building Picasso for Video and here is it

Google Slide version (so GIF can play): https://docs.google.com/presentation/d/1Yhrnm22lkl6YoFmu20UvbAUAa5MgtOdul-tMle1jEf4/edit?usp=sharing

To Android Tokyo Meetup attendees: this version has a few slide added (the part about why we need you-know-what) and fix a few text.

F8ca3e94570e4dc117f34563687a3b09?s=128

Nam Nguyen Hoai

July 23, 2019
Tweet

Transcript

  1. 1.

    I’ve spent a year building Picasso for Video and here

    is it Tokyo Android Meetup・2019/07/23 Nam Nguyen (eneim)
  2. 9.

    YouTube clone sprint 1 - List of thumbnail - Click

    item thumbnail → open Player - One Video in one screen at one time!
  3. 10.

    Sprint 1 approach - 1 Activity for list & 1

    Activity for player - Click → Parcelize Video information and start PlayerActivity - MediaPlayer or ExoPlayer for playback
  4. 11.

    YouTube clone sprint 2 - List of thumbnail Videos -

    Fully visible Video on top: plays automatically - Click an item → open Player - Many Videos in one screen at one time! - At most one to play
  5. 12.

    Sprint 2 approach - 1 Activity for list & 1

    Activity for player - List: RecyclerView with OnScrollListener - onScrolled: - LinearLayoutManager’s findFirstCompletelyVisibleItemPosition() - Start and Pause item properly - MediaPlayer or ExoPlayer for playback
  6. 13.

    YouTube clone sprint 3 - Single player UX ⇆ Orientation:

    - Portrait: Player + Video detail - Landscape: Fullscreen player - Background playback (to replicate YouTube Premium) - Playback continuity - No reloading/re-buffering
  7. 14.

    Sprint 3 approach - Manifest flag: configChanges + Orientation Detector

    and/or onConfigurationChanged + if/else 祭り - Background playback: foreground Service - No re-creation → No re-buffering
  8. 15.

    Sprint 3 challenges - Manifest flag: configChanges ← How many

    flags you will need? - Background playback: foreground Service ← How? - Foreground Service should be alive even if no Activity is
  9. 19.
  10. 20.

    // fragment_main.xml // <NestedScrollView id="scrollView"> // <LinearLayoutCompat orientation="vertical"> // <PlayerView

    id="playerView"></PlayerView> // <TextView></TextView> // </LinearLayoutCompat> // </NestedScrollView> override fun onActivityCreated(state: Bundle?) { super.onActivityCreated(state) kohii = Kohii[this@MyFragment].also { it.register(this, this.scrollView) } kohii.setUp(videoUrl).bind(playerView) } Easy to start
  11. 21.

    // fragment_main.xml // <NestedScrollView id="scrollView"> // <LinearLayoutCompat orientation="vertical"> // <PlayerView

    id="firstPlayerView"></PlayerView> // <TextView></TextView> // <PlayerView id="secondPlayerView"></PlayerView> // <TextView></TextView> // </LinearLayoutCompat> // </NestedScrollView> override fun onActivityCreated(state: Bundle?) { super.onActivityCreated(state) kohii = Kohii[this@MyFragment].also { it.register(this, this.scrollView) } kohii.setUp(videoUrl).bind(firstPlayerView) kohii.setUp(otherVideoUrl).bind(secondPlayerView) } Many videos scenario is supported out of the box
  12. 23.

    Summary: what Kohii offers? - Works out of the box

    - Implement Video playback as quick as possible - Single Video or many Videos - Safe and resource friendly - Cache and reuse playback resource - All cached resources are torn down at reasonable timing - Flexible & Extensible - Powerful abstraction & default impl using ExoPlayer - DIY on top of Kohii’s abstraction
  13. 28.

    Kohii PlaybackManagerGroup PlaybackManager_A PlaybackManager_B TargetHost_A TargetHost_B Target_A0 Target_A2 Target_A1 Target_B0

    Target_B2 Target_B1 Target_B3 Target_B5 Target_4 Target’s attach/detach/layout events PlaybackManager requests update TargetHost’s scroll/layout event PlaybackManagerGroup talks to all PlaybackManagers: collect all Targets to play and to pause
  14. 29.

    Kohii PlaybackManagerGroup PlaybackManager_A PlaybackManager_B TargetHost_A TargetHost_B Target_A0 Target_A2 Target_A1 Target_B0

    Target_B2 Target_B1 Target_B3 Target_B5 Target_4 Each PlaybackManager talks to its TargetHosts: select the Target to play, others will be paused. PlaybackManagerGroup then decide the final Target to play and pause all others React to user interaction. Using Handler/Messenger to prevent aggressive update requests.
  15. 32.

    TEXT Text text text text text text text text text

    text text text text text text text text text text text text text text text text text text text text text TEXT Text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text Video: not playable
  16. 33.

    TEXT Text text text text text text text text text

    text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text TEXT Text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text Video: playable Player provider Pool Creator Player #1 Give me a Player Here you are
  17. 34.

    TEXT Text text text text text text text text text

    text text text text text text text text text text text text text text text text text text text text text Video: playable Player provider Pool Creator Player #1 TEXT Text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text TEXT Text text text text text text text text text text text text text text text text text text text text I’m done, thanks!
  18. 35.

    TEXT Text text text text text text text text text

    text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text Video: playable Player provider Pool Creator Player #1 Give me a Player Here you are TEXT Text text text text text text text text text text text text text text text text text text text text text text text text text
  19. 36.

    Player provider Pool Creator TEXT Text text text text text

    text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text TEXT Text text text text text text text text text text text text text text text text text text text text text text text text text Lifecycle.Event.ON_DESTROY Player #1 I’m done, thanks!
  20. 38.

    By passing the same resource around, we can switch the

    Player without reloading the content
  21. 40.

    How ExoPlayer works ExoPlayer PlayerView MediaSource // playerView: PlayerView instance

    // player: ExoPlayer instance // mediaSource: MediaSource instance playerView.setPlayer(player) player.prepare(videoSource) player.playWhenReady = true // to play, or false to pause
  22. 48.
  23. 49.

    Abstraction: Playable, Playback, Pool, etc Default impl using ExoPlayer DIY*

    using your own playback API (eg: androidx Media2, YouTube Player API) *Not all API support easy switching Target, eg: YouTube Player API
  24. 51.