Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
DMM TVのSDカードダウンロード機能を実装した話
Search
Yuta Tomiyama
June 23, 2023
Programming
1
680
DMM TVのSDカードダウンロード機能を実装した話
2023/06/20 DMM Android勉強会にて発表
Yuta Tomiyama
June 23, 2023
Tweet
Share
More Decks by Yuta Tomiyama
See All by Yuta Tomiyama
なんでもやってみる勇気
yt8492
0
27
Android Autoが思ったよりしんどい話
yt8492
0
140
apollo-kotlinにcontributeした話
yt8492
0
66
今だからこそ知りたいKotlin Multiplatform
yt8492
0
230
State management and API calls in Jetpack Compose: Learning Apollo + Jetpack Compose through React Hooks
yt8492
0
1.1k
サーバーフレームワークの仕組みが気になったので車輪の再発明をしてみた
yt8492
0
170
Compose for Webを始めよう
yt8492
0
340
Compose Multiplatform 1.0.0
yt8492
0
140
Kotlin/NativeからCの標準ライブラリを呼び出そう
yt8492
0
310
Other Decks in Programming
See All in Programming
Our Websites Need a Lifestyle Change, Not a Diet
ryantownsend
0
150
Modular Monolith Go Server with GraphQL Federation + gRPC
110y
1
580
Pythonで改めて考える「クラス(class)」の使いどころ
os1ma
1
300
大公開!iOS開発の悩みトップ5 〜iOSDC Japan 2024〜
ryunakayama
0
190
Crafting Cross-Platform Adventures: Building a Game Engine with Kotlin Multiplatform
dwursteisen
0
120
Amazon BedrockでサーバレスなAIお料理ボットを作成する!!
tosuri13
0
230
Scala アプリケーションのビルドを改善してデプロイ時間を 1/4 にした話 | How I improved the build of my Scala application and reduced deployment time by 4x
nomadblacky
1
180
A New Era of Testing
mannodermaus
2
510
watsonx.ai Dojo #2 生成AIを使ったアプリ開発入門編
oniak3ibm
PRO
0
180
いつか使える ObjectSpace / Maybe useful ObjectSpace
euglena1215
2
140
XStateでReactに秩序を与えたい
gizm000
0
730
KSPの導入・移行を前向きに検討しよう!
shxun6934
PRO
0
280
Featured
See All Featured
Navigating Team Friction
lara
183
13k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
190
16k
GitHub's CSS Performance
jonrohan
1030
450k
The Cult of Friendly URLs
andyhume
76
6k
Build your cross-platform service in a week with App Engine
jlugia
228
18k
Infographics Made Easy
chrislema
239
18k
Product Roadmaps are Hard
iamctodd
PRO
48
10k
Creatively Recalculating Your Daily Design Routine
revolveconf
215
12k
Rails Girls Zürich Keynote
gr2m
93
13k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
45
4.8k
The Power of CSS Pseudo Elements
geoffreycrofte
71
5.3k
Building Better People: How to give real-time feedback that sticks.
wjessup
359
19k
Transcript
DMM TVのSDカード ダウンロード機能を実装した話 #dmm_android勉強会
自己紹介 HN: マヤミト 本名: 富山 雄太 GitHub: https://github.com/yt8492 趣味: Kotlin,
Twitter, ウマ娘 22新卒 動画配信事業部 Androidエンジニア Twitter: yt8492
DMM TVの開発をしています
SDカード対応をしたのでその話をします
DMM TVのダウンロード仕様について • 配信形式 ◦ MPEG-DASH • コンテンツ保護 ◦ Widevine
→ MP4などの動画ファイルを単純にダウンロードして保存して終わり!ではない
ExoPlayerのダウンロード関連の主要な登場人物 • Cache ◦ ExoPlayerのCache。ダウンロードの保存先の情報をもつ。 • Download ◦ ダウンロードしたデータ。 •
DownloadIndex ◦ Downloadを保存・取得する。 • DownloadManager ◦ Downloadを管理する。CacheとDownloadIndexをもつ。Downloadを取得したり、Download中 のものをキャンセルしたりする。 • DownloadRequest ◦ ダウンロードするために必要な情報。ダウンロードしたい URIやライセンスキーなどを持つ。 • DownloadService ◦ DownloadをするService。
ExoPlayerでダウンロードして再生するまで 1. DownloadRequest を組み立てる 2. DownloadService.sendAddDownload を呼び出しダウンロードする 3. DownloadManager から
DownloadIndex を取得し、ダウンロードしたデータを 表す Download のインスタンスを取得する 4. Download のインスタンスから MediaItem を生成する 5. CacheDataSource.Factory を MediaSource.Factory (DMM TVの場合は DashMediaSource.Factory)に渡す 6. MediaSource.Factory の createMediaSource メソッドに4の MediaItem を 渡し、MediaSource を取得する 7. MediaSource をExoPlayer で再生する
MediaItemの設定 • uriは動画のURL • ここで使っているUtilはExoPlayer側で用意されているもの
DownloadHelperの設定 • DownloadHelper.forMediaItemで先程のmediaItemを渡し、 DownloadHelperを取得する
DownloadRequestの取得 • 先程の downloadHelper の getDownloadRequest を呼び出し、 DownloadRequest を取得する •
引数にuniqueなidを渡す(今回は動画のid)
DownloadService.sendAddDownload を呼び出す • requestは先程の DownloadRequest • DownloadManager を返すメソッドを実装した DownloadService のclassオブ
ジェクトを渡す
Downloadのインスタンスを取得する • DownloadRequest の取得の際に設定したidをもとに Download を取得する
MediaSource を取得する • CacheDataSource.Factory を設定する • DashMediaSource.Factory を設定する • createMediaSource
で生成する • あとはExoPlayerに渡して再生する
ExoPlayerのダウンロード関連の主要な登場人物(復習) • Cache ◦ ExoPlayerのCache。ダウンロードの保存先の情報をもつ。 • Download ◦ ダウンロードしたデータ。 •
DownloadIndex ◦ Downloadを保存・取得する。 • DownloadManager ◦ Downloadを管理する。CacheとDownloadIndexをもつ。Downloadを取得したり、Download中 のものをキャンセルしたりする。 • DownloadRequest ◦ ダウンロードするために必要な情報。ダウンロードしたい URIやライセンスキーなどを持つ。 • DownloadService ◦ DownloadをするService。
ここまでが事前知識
DMM TVではダウンロードをどのように実装していたか • もともとはSDカードに対応しておらず、内部ストレージへのみのダウンロード機能 だった • Cache, DownloadManagerをDIコンテナ(Koin)でシングルトンで管理し、使うとこ ろにDIしていた
SDカード対応でどうなったか • もともとはSDカードに対応しておらず、内部ストレージへのみのダウンロード機能 だった • Cache, DownloadManagerをDIコンテナ(Koin)でシングルトンで管理し、使うとこ ろにDIしていた → CacheとDownloadManagerは複数の保存先に対応していない😇
SDカードに対応させるには、内部ストレージ用とSDカード用でCacheと DownloadManagerを別々に用意し、必要に応じて出し分ける必要がある😇 SDカードの状態も考えると直接DIするとまずいので結構直さなきゃいけない😇
やったこと 1. 保存先の設定の項目をアプリに追加する 2. 必要に応じて出し分けるProviderクラスを用意 3. Cache, DownloadManagerを直接DIするのをやめ、ProviderをDIする 4. 保存時は保存先の設定を見てどちらのDownloadManagerを使うか決める
5. 再生時は両方のDownloadManagerから取得を試み、取得できたほうを使う
必要に応じてCacheを出し分けるProviderの実装 1. 保存先の設定をもとに保存先のディレクトリを取得する処理の実装 2. 保存先の設定を受け取り、Cacheのインスタンスを生成するFactoryの実装 3. Cacheのインスタンスを管理するProviderの実装
保存先のディレクトリを 取得する処理の実装
Cacheのインスタンスを生成するFactoryの実装 • SDカードが挿入されていない場合、downloadDirectoryがnullになる
Cacheのインスタンスを管理するProviderの実装 • 同じ保存先ディレクトリのCacheは2 つ以上同時に保持するとエラーになる ため、synchronizedで対策
DownloadManagerを出し分けるProviderの実装 1. DownloadIndexインスタンスを内部ストレージとSDカードで分ける 2. 保存先の設定を受け取り、DownloadManagerインスタンスを生成するFactoryの 実装 3. DownloadManagerのインスタンスを管理するProviderの実装
DownloadIndexを内部ストレージとSDカードで分ける • 内部ストレージとSDカードどちらに保存しているかの判断のために分ける
DownloadManagerを 生成するFactoryの実装
DownloadManagerを管理する Providerの実装
DownloadService.sendAddDownload呼び出し修正前 • DownloadManagerを返すDownloadServiceのメソッドで直接DIコンテナから取 得している • DownloadService.sendAddDownloadに内部ストレージのDownloadService のclassオブジェクトを固定で渡している
DownloadService.sendAddDownload呼び出し修正 • DownloadManagerを返すDownloadServiceのメソッドでProviderから取得して いる • DownloadService.sendAddDownloadで渡すclassオブジェクトを設定から出し 分ける
Downloadインスタンス取得の修正前 • 直接DIした内部ストレージのDownloadManagerから単純に取得する
Downloadインスタンス取得の修正 • 内部ストレージとSDカード両方から取得を試み、どちらに保存されているか判断
MediaSource取得の修正前 • 直接DIした内部ストレージのCacheをDataSourceに使う
MediaSource取得の修正 • 前述の処理で判定した保存先をもとに、cacheを取得するように修正
これでSDカードでも 保存・再生できるように🎉
まとめ • ExoPlayerのCacheやDownloadManagerは、複数の保存先を管理するような仕 組みがない • そのため、内部ストレージとSDカードでCacheとDownloadManagerを分ける必要 がある • CacheとDownloadManagerを管理するProviderを実装すると便利 •
もっといいやり方あれば教えてください
ありがとうございました!