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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
490
モバイルアプリ開発を始めよう!
yt8492
0
120
Git勉強会
yt8492
0
220
なんでもやってみる勇気
yt8492
0
140
Android Autoが思ったよりしんどい話
yt8492
0
250
apollo-kotlinにcontributeした話
yt8492
0
200
今だからこそ知りたいKotlin Multiplatform
yt8492
0
340
State management and API calls in Jetpack Compose: Learning Apollo + Jetpack Compose through React Hooks
yt8492
0
1.4k
サーバーフレームワークの仕組みが気になったので車輪の再発明をしてみた
yt8492
0
250
Other Decks in Programming
See All in Programming
Japan Community Day at Kubecon + CloudNativeCon Japan 2026: Learning Container Privilege Control by Building My Own Low-Level Container Runtime
ternbusty
1
150
AI時代に設計が 最大の生産性レバーになる 意図駆動開発とデータを消さない設計|Don't Delete Your Data or Your Intent — Design as the Deepest Lever in the AI Era
tomohisa
1
850
プロポーザルを書いてもらう
pvcresin
0
500
これって Effect でできたのでは? / TSKaigi Mashup Kansai #2
susisu
0
240
【QA Test Talk Vol.8】AI-DLC による Whole Team Approach の加速
pkshadeck
PRO
0
180
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
920
the container ship “Apple Silicon”@WWDC26 Recap -Japan-\(region).swift
shingangan
0
120
仕様書を書く前にハーネスを作る - Agent Native開発は「探索を速く、判定を固く」
gotalab555
4
1.6k
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
1
230
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
180
自動化したのに回らない テスト運用の壁―AI時代の品質責任と生産性
mfunaki
0
170
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
550
Featured
See All Featured
Tell your own story through comics
letsgokoyo
1
1k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
4 Signs Your Business is Dying
shpigford
187
22k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
370
The Mindset for Success: Future Career Progression
greggifford
PRO
0
440
Ruling the World: When Life Gets Gamed
codingconduct
0
300
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
430
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.2k
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を実装すると便利 •
もっといいやり方あれば教えてください
ありがとうございました!