Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Jetpack Compose の動画表示対応 をまとめてみた
Search
nagayan
September 01, 2023
Programming
1.3k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Jetpack Compose の動画表示対応 をまとめてみた
Android Jetpack Compose で動画表示対応 をまとめました。
nagayan
September 01, 2023
Other Decks in Programming
See All in Programming
Event is what happens
moro
2
860
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.7k
phperだってパンチカードでコーディングしたい
o0h
PRO
0
350
個人開発者よ、Honoを使え(おじさんver)
tanahiro2010
2
260
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
35
17k
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
300
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
190
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
0
510
[ハンズオン]AIへの指示だけで「五目並べ」を作ってみよう
satoshi256kbyte
1
380
IBM Bob でAI駆動開発『QC-Playbook』
ichirokano2
0
110
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.6k
JIS keyboard support in Omarchy
lef237
0
130
Featured
See All Featured
The agentic SEO stack - context over prompts
schlessera
0
970
The SEO Collaboration Effect
kristinabergwall1
1
590
Product Roadmaps are Hard
iamctodd
55
13k
Large-scale JavaScript Application Architecture
addyosmani
516
110k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
7k
Faster Mobile Websites
deanohume
310
32k
Mind Mapping
helmedeiros
1
400
Statistics for Hackers
jakevdp
799
230k
[SF Ruby Conf 2025] Rails X
palkan
3
1.5k
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
Are puppies a ranking factor?
jonoalderson
2
4.1k
Scaling GitHub
holman
464
140k
Transcript
株式会社 Gunosy テクノロジー本部 永山 雄 2023年9月1日 Jetpack Compose の動画表示対応 をまとめてみた
(C) Gunosy Inc. All Rights Reserved. PAGE | 2 ▪
名前:nagayan / 永山 雄 ▪ 所属:株式会社Gunosy – Android エンジニア auサービスToday を担当 ▪ X:@nagayan_dev 自己紹介
(C) Gunosy Inc. All Rights Reserved. PAGE | 3 アジェンダ
背景・方針 Jetpack Compose の動画実装 • Exoplayer、AndroidViewを使った、基本実装 • デフォルトの動画パーツを OFF にする • VideoStateの定義と実装 • 動画パーツの実装 • 動画の進捗とシークバーを連動させる • ライフサイクルで再生・停止・解放 まとめ
(C) Gunosy Inc. All Rights Reserved. PAGE | 4 ▪
auサービスTodayでは Compose 実装への置き換えを随時進めて います ▪ Jetpack Compose の動画実装を調べていましたが、情報が散見 されていました ▪ 動画部分のCompose化をしたため、その対応をまとめました ▪ 既存のデザインを踏襲するため、デフォルトの動画パーツは使用し ない方針です 背景・方針
(C) Gunosy Inc. All Rights Reserved. PAGE | 5 ▪
Android Jetpack Compose で動画表示 – https://tech.gunosy.io/entry/android_compose_video_player 今回の内容
(C) Gunosy Inc. All Rights Reserved. Jetpack Compose の動画実装
(C) Gunosy Inc. All Rights Reserved. PAGE | 7 dependencies
{ implementation "androidx.media3:media3-exoplayer:1.1.1" 使用するライブラリ Jetpack Compose の動画実装
(C) Gunosy Inc. All Rights Reserved. PAGE | 8 val
exoPlayer = remember(context) { ExoPlayer.Builder(context).build().apply { setMediaItem(MediaItem.fromUri(Uri.parse(url))) prepare() seekTo(0L) } } Exoplayer、AndroidViewを使った、基本実装 Jetpack Compose の動画実装 ▪ 動画を再生する Exoplayerを 作成します
(C) Gunosy Inc. All Rights Reserved. PAGE | 9 Exoplayer、AndroidViewを使った、基本実装
Jetpack Compose の動画実装 ▪ 作成したExoplayerを、 AndroidView の PlayerView に設定します val exoPlayer = remember(context) ~~~ Box(~~~) { AndroidView( modifier = ~~~, factory = { context -> PlayerView(context).apply { this.player = exoPlayer } })}
(C) Gunosy Inc. All Rights Reserved. PAGE | 10 パーツがデフォルトのもの
→パーツを自前実装する Jetpack Compose の動画実装 Exoplayer、AndroidViewを使った、基本実装
(C) Gunosy Inc. All Rights Reserved. PAGE | 11 val
exoPlayer = remember(context) ~~~ Box(~~~) { AndroidView( modifier = ~~~, factory = { context -> PlayerView(context).apply { useController = false this.player = exoPlayer } })} デフォルトの動画パーツを OFF にする Jetpack Compose の動画実装 ▪ PlayerView の useController を false に指定することで、デ フォルトの動画パーツを非表 示にできます
(C) Gunosy Inc. All Rights Reserved. PAGE | 12 ▪
UIを更新するため、独自の VideoState を定義します ▪ remember で State を保持します VideoStateの定義と実装 Jetpack Compose の動画実装 var videoState by remember { mutableStateOf(VideoState.LOADING) } enum class VideoState { LOADING, PAUSE, START, ENDED }
(C) Gunosy Inc. All Rights Reserved. PAGE | 13 ▪
onPlaybackStateChan ged で VideoState の 更新をします。 VideoStateの定義と実装 Jetpack Compose の動画実装 exoPlayer.addListener(object : Player.Listener { override fun onPlaybackStateChanged(playbackState: Int) { videoState = when { playbackState == Player.STATE_READY && playWhenReady -> VideoState.START playbackState == Player.STATE_ENDED && playWhenReady -> VideoState.ENDED ~~~ -> VideoState.LOADING ~~~ --> VideoState.PAUSE
(C) Gunosy Inc. All Rights Reserved. PAGE | ▪ 再生停止ボタンを実装します
▪ 先ほどの State を元に、Start と Pause を切り替えます 14 動画パーツの実装 Jetpack Compose の動画実装 var videoState by remember { ~~~ } ~~~ if (videoState == VideoState.START) { Image( painter = ~中断ボタン画像~, contentDescription = ~~~, ) } else { Image( painter = ~再生ボタン画像~, contentDescription = ~~~, ) } ~~~
(C) Gunosy Inc. All Rights Reserved. PAGE | 15 動画パーツの実装
Jetpack Compose の動画実装 var currentTime by remember { mutableStateOf(0L) } ~~~ Slider( ~~~ value = currentTime.toFloat(), valueRange = 0f..exoPlayer.duration.~~~, colors = SliderDefaults.colors( ~~~ ))} ▪ シークバーの実装です ▪ Slider を用いて実装します ▪ 動画の進捗度として currentTime を定義します ▪ Slider の value に指定し、 valueRange は 0 から 動画 の長さを設定します
(C) Gunosy Inc. All Rights Reserved. PAGE | 16 ▪
シークバーの操作を反映させ ます ▪ onValueChange はシーク バー操作時に通知される Callback で、ここで通知され た値を currentTime に設定し ます 動画の進捗とシークバーを連動させる Jetpack Compose の動画実装 var currentTime by remember { mutableStateOf(0L) } ~~~ Slider( ~~~ value = currentTime.toFloat(), onValueChange = { timeMs -> val time = timeMs.toLong() exoPlayer.seekTo(time) currentTime = time }, valueRange = 0f..exoPlayer.duration.~~~, ~~~
(C) Gunosy Inc. All Rights Reserved. PAGE | 17 ▪
動画が再生されてても、シーク バーが動いてくれません ▪ 再生状態の時に LaunchedEffect 内で repeat をし、動画時間を取得して currentTime に反映させます。 動画の進捗とシークバーを連動させる Jetpack Compose の動画実装 var currentTime by remember { mutableStateOf(0L) } ~~~ if (videoState == VideoState.START) { LaunchedEffect(Unit) { repeat(Int.MAX_VALUE) { delay(1000) currentTime = exoPlayer.contentPosition }}}
(C) Gunosy Inc. All Rights Reserved. PAGE | 18 ▪
アプリがバックグラウンドに行っ た時に再生しっぱなしになってし まう ▪ DisposableEffect を用いて、ラ イフサイクルに合わせて処理を 実行 – onResume:再生 – onPause:停止 ライフサイクルで再生・停止・解放 Jetpack Compose の動画実装 DisposableEffect(lifecycleOwner) { val observer = LifecycleEventObserver { _, event -> if (event == Lifecycle.Event.ON_RESUME) { if (videoState == VideoState.START) { exoPlayer.play() } } else if (event == Lifecycle.Event.ON_PAUSE) { exoPlayer.pause() } } lifecycleOwner.lifecycle.addObserver(observer) ~~~
(C) Gunosy Inc. All Rights Reserved. PAGE | 19 ▪
DisposableEffect の onDispose で解放処理を実行 します ライフサイクルで再生・停止・解放 Jetpack Compose の動画実装 DisposableEffect(lifecycleOwner) { ~~~ onDispose { exoPlayer.run { playWhenReady = false ~~~ release() } lifecycleOwner.lifecycle.removeObserver(observer) } }
(C) Gunosy Inc. All Rights Reserved. PAGE | 20 完成
Jetpack Compose の動画実装
(C) Gunosy Inc. All Rights Reserved. PAGE | 21 ▪
Jetpack Compose で基本的な動画表示の実装について紹介しま した ▪ デフォルトの動画パーツを表示するだけなら簡単に実装できます が、カスタマイズしたパーツを表示するとなるとちょっと工夫が必要 になります ▪ 動画再生が一定時間経過した後に動画パーツを非表示にしたり、 動画終了時に End Screen を表示できるようになれば、より高機 能な動画が実現できると思います まとめ Jetpack Compose ライフを楽しみましょう!
中表紙 情報を世界中の人に最適に届ける (C) Gunosy Inc. All Rights Reserved.