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
DMM TVのSDカードダウンロード機能を実装した話
Search
Yuta Tomiyama
June 23, 2023
Programming
1k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
DMM TVのSDカードダウンロード機能を実装した話
2023/06/20 DMM Android勉強会にて発表
Yuta Tomiyama
June 23, 2023
More Decks by Yuta Tomiyama
See All by Yuta Tomiyama
ビルドプロセスをデバッグしよう!
yt8492
2
520
モバイルアプリ開発を始めよう!
yt8492
0
130
Git勉強会
yt8492
0
240
なんでもやってみる勇気
yt8492
0
140
Android Autoが思ったよりしんどい話
yt8492
0
260
apollo-kotlinにcontributeした話
yt8492
0
200
今だからこそ知りたいKotlin Multiplatform
yt8492
0
360
State management and API calls in Jetpack Compose: Learning Apollo + Jetpack Compose through React Hooks
yt8492
0
1.4k
サーバーフレームワークの仕組みが気になったので車輪の再発明をしてみた
yt8492
0
260
Other Decks in Programming
See All in Programming
phperだってパンチカードでコーディングしたい
o0h
PRO
0
320
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
600
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.7k
Compiling a real-world CLI tool to native with Static Hermes
tmikov2023
0
110
AIに “答え“を書かせるのを やめてみた
___akari11
0
120
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
5
5.1k
sbt 2.0: takeoff
eed3si9n
0
160
速習iPhone Duo対応
yuukiw00w
2
990
dotNET_vulnclicker_intro.pdf
deka_morita
0
140
全ての永続トークンを、生まれる前に消し去りたい!
sylph01
2
720
The Rails Doctrine Decade
koic
2
570
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
410
Featured
See All Featured
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
2
950
Leo the Paperboy
mayatellez
10
2.4k
The Pragmatic Product Professional
lauravandoore
37
7.5k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Why Our Code Smells
bkeepers
PRO
340
58k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
410
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
Mobile First: as difficult as doing things right
swwweet
225
10k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
77k
Optimizing for Happiness
mojombo
378
71k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
410
Balancing Empowerment & Direction
lara
6
1.3k
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を実装すると便利 •
もっといいやり方あれば教えてください
ありがとうございました!