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
940
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
1
410
モバイルアプリ開発を始めよう!
yt8492
0
95
Git勉強会
yt8492
0
190
なんでもやってみる勇気
yt8492
0
120
Android Autoが思ったよりしんどい話
yt8492
0
240
apollo-kotlinにcontributeした話
yt8492
0
170
今だからこそ知りたいKotlin Multiplatform
yt8492
0
320
State management and API calls in Jetpack Compose: Learning Apollo + Jetpack Compose through React Hooks
yt8492
0
1.3k
サーバーフレームワークの仕組みが気になったので車輪の再発明をしてみた
yt8492
0
230
Other Decks in Programming
See All in Programming
技術検証結果の整理と解析をAIに任せよう!
keisukeikeda
0
130
ふつうの Rubyist、ちいさなデバイス、大きな一年
bash0c7
0
1.1k
PHPのバージョンアップ時にも役立ったAST(2026年版)
matsuo_atsushi
0
210
CSC307 Lecture 15
javiergs
PRO
0
260
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
710
AI活用のコスパを最大化する方法
ochtum
0
260
モックわからないマン卒業記 ~振る舞いを起点に見直した、フロントエンドテストにおけるモックの使いどころ~
tasukuwatanabe
3
410
クライアントワークでSREをするということ。あるいは事業会社におけるSREと同じこと・違うこと
nnaka2992
1
350
存在論的プログラミング: 時間と存在を記述する
koriym
3
290
ふつうのRubyist、ちいさなデバイス、大きな一年 / Ordinary Rubyists, Tiny Devices, Big Year
chobishiba
1
480
GoのDB アクセスにおける 「型安全」と「柔軟性」の両立 - Bob という選択肢
tak848
0
260
モダンOBSプラグイン開発
umireon
0
170
Featured
See All Featured
Art, The Web, and Tiny UX
lynnandtonic
304
21k
Abbi's Birthday
coloredviolet
2
5.5k
My Coaching Mixtape
mlcsv
0
82
Writing Fast Ruby
sferik
630
63k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.1k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
160
Building the Perfect Custom Keyboard
takai
2
720
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
150
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.8k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
120
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を実装すると便利 •
もっといいやり方あれば教えてください
ありがとうございました!