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
830
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
46
Git勉強会
yt8492
0
100
なんでもやってみる勇気
yt8492
0
81
Android Autoが思ったよりしんどい話
yt8492
0
190
apollo-kotlinにcontributeした話
yt8492
0
120
今だからこそ知りたいKotlin Multiplatform
yt8492
0
290
State management and API calls in Jetpack Compose: Learning Apollo + Jetpack Compose through React Hooks
yt8492
0
1.2k
サーバーフレームワークの仕組みが気になったので車輪の再発明をしてみた
yt8492
0
200
Compose for Webを始めよう
yt8492
0
400
Other Decks in Programming
See All in Programming
Select API from Kotlin Coroutine
jmatsu
1
190
Datadog RUM 本番導入までの道
shinter61
1
310
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う Swift の仕様 / from Kotlin to Swift
lovee
1
250
Blazing Fast UI Development with Compose Hot Reload (droidcon New York 2025)
zsmb
1
130
Railsアプリケーションと パフォーマンスチューニング ー 秒間5万リクエストの モバイルオーダーシステムを支える事例 ー Rubyセミナー 大阪
falcon8823
3
810
Is Xcode slowly dying out in 2025?
uetyo
1
180
Haskell でアルゴリズムを抽象化する / 関数型言語で競技プログラミング
naoya
17
4.8k
Elixir で IoT 開発、 Nerves なら簡単にできる!?
pojiro
1
150
SODA - FACT BOOK
sodainc
1
1.1k
なぜ「共通化」を考え、失敗を繰り返すのか
rinchoku
1
410
Using AI Tools Around Software Development
inouehi
0
1.2k
WindowInsetsだってテストしたい
ryunen344
1
190
Featured
See All Featured
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.4k
Designing Experiences People Love
moore
142
24k
Navigating Team Friction
lara
187
15k
Intergalactic Javascript Robots from Outer Space
tanoku
271
27k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.2k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Designing for Performance
lara
609
69k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
660
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
228
22k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
20k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
GraphQLとの向き合い方2022年版
quramy
46
14k
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を実装すると便利 •
もっといいやり方あれば教えてください
ありがとうございました!