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

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. I’ve spent a year building Picasso for Video and here

    is it Tokyo Android Meetup・2019/07/23 Nam Nguyen (eneim)
  2. Picasso? A powerful image downloading and caching library for Android

    https://square.github.io/picasso/
  3. Picasso? Picasso.get() .load(photoUrl) .into(imageView) source: https://square.github.io/picasso/

  4. Picasso for Video? HOW?

  5. Picasso for Video? A powerful image downloading and caching video

    playback library for Android
  6. Picasso for Video? OKAY...

  7. MediaPlayer, ExoPlayer, ffmpeg, etc exist. Why do we need another

    Video playback library?
  8. Scenario: cloning YouTube client

  9. YouTube clone sprint 1 - List of thumbnail - Click

    item thumbnail → open Player - One Video in one screen at one time!
  10. Sprint 1 approach - 1 Activity for list & 1

    Activity for player - Click → Parcelize Video information and start PlayerActivity - MediaPlayer or ExoPlayer for playback
  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
  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
  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
  14. Sprint 3 approach - Manifest flag: configChanges + Orientation Detector

    and/or onConfigurationChanged + if/else 祭り - Background playback: foreground Service - No re-creation → No re-buffering
  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
  16. Not done yet ! https://github.com/google/ExoPlayer/issues/867

  17. Need more power!

  18. ‘Picasso for Video’ is a powerful Video playback library for

    Android Named it Kohii
  19. DEMO

  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
  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
  22. Reusability: Unlimited items using only one PlayerView!

  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
  24. Under the hood

  25. Kohii manages playbacks like managing an organization

  26. Application FragmentActivity Fragment Fragment RecyclerView RecyclerView PlayerViews

  27. Application FragmentActivity Fragment Fragment RecyclerView RecyclerView Kohii (BOSS) PlaybackManagerGroup PlaybackManager

    TargetHost Target(s) PlayerView
  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
  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.
  30. Limited resource for unlimited demand: Caching

  31. ExoPlayer pool and PlayerView pool

  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
  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
  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!
  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
  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!
  37. Non-blocking playback experience (a.k.a Playback continuity)

  38. By passing the same resource around, we can switch the

    Player without reloading the content
  39. This mechanism learns from how ExoPLayer works

  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
  41. Target Playable ExoPlayer, MediaSource PlayerView

  42. Target Playable Screen A Screen B Target

  43. Target Playable PlayerView ExoPlayer, MediaSource Playback play/pause/etc

  44. Target Playable Playback Application scope Activity scope Activity scope Target

    Playback
  45. Target Playable Playback Application List Fullscreen Player Target Playback

  46. One Playable (= one ExoPlayer) Video in List Overlay Player

    Background Player
  47. Q: Looks good. But I don’t want to use ExoPlayer.

  48. A: Kohii is extensible. i.e You can support other playback

    API on top of Kohii’s abstraction
  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
  50. Source code https://github.com/eneim/kohii

  51. Thanks