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
Chromecast対応を始めてみる
Search
takathemax
June 26, 2023
Programming
300
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Chromecast対応を始めてみる
takathemax
June 26, 2023
More Decks by takathemax
See All by takathemax
ComposeでのPicture in Picture
takathemax
0
270
Other Decks in Programming
See All in Programming
【高い買い物LT会】初任給で話題の国産フィジカルAIを買った話
akagami
PRO
0
130
20260828_品質と開発生産性を両立させる、AI時代のE2Eテストの考え方
magicpod
0
180
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
1.6k
The Good Stuff, Not the Slop: Engineering High-Quality Android Apps with Modern AI Tooling
danybony
1
230
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
520
AgentCore CLI で進化した AWS での AI エージェントの作り方 : 必要な機能を必要な時に
icoxfog417
PRO
2
260
数年滞っていたダークモード対応をおよそ2週間で完了させる
chigichan24
0
700
新卒PdEのリアル
ryu1013
1
480
Swift愛好会100回記念 第1回を振り返る
jollyjoester
0
120
Webの地図
yosuke_furukawa
PRO
4
3.8k
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
160
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
250
Featured
See All Featured
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
490
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Between Models and Reality
mayunak
4
450
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
190
Designing Experiences People Love
moore
143
24k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
450
Discover your Explorer Soul
emna__ayadi
2
1.3k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
57k
Building Applications with DynamoDB
mza
96
7.2k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
370
The browser strikes back
jonoalderson
0
1.7k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
410
Transcript
© DMM Chromecast対応を始めてみる #dmm_android勉強会
© DMM 自己紹介 正木清駿 2020年中途入社 動画配信事業部所属 Android歴四年目くらい
© DMM 目次 1. Chromecast対応の概要 2. Senderの簡単な実装 3. まとめ
© DMM Chromecast対応の概要 https://developers.google.com/cast/docs/overview?hl=ja より引用
© DMM Chromecast対応の概要 モバイルエンジニア が開発するとなるとま ずはこっちが多い https://developers.google.com/cast/docs/overview?hl=ja より引用
© DMM Chromecast対応の概要 モバイルエンジニア が開発するとなるとま ずはこっちが多い AndroidTVアプリや、 Webレシーバーで対応 対応デバイスはGoogle Homeなどもあるので多
種多様 https://developers.google.com/cast/docs/overview?hl=ja より引用
© DMM Senderアプリの実装の流れ 1. Cast Application Framework(CAF)の導入 2. CastContextの初期化とOptionsProviderの準備 3.
キャストボタンの表示 4. 動画をChromecastで再生させる
© DMM ライブラリの導入 dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.mediarouter:mediarouter:1.4.0' implementation
'com.google.android.gms:play-services-cast-framework:21.3.0' }
© DMM CastContextとOptionsProvider • CastContext • ApplicationContextをもとに生成され、アプリ内でシングルトンで管理される • CAFのあらゆる処理に使用される •
OptionsProvider • CastContextの作成と初期化に必要 • ここでReceiverをGoogle Cast SDK Developer Consoleで登録した際にえられ るIDを設定する
© DMM OptionsProvider import android.content.Context import com.google.android.gms.cast.CastMediaControlIntent import com.google.android.gms.cast.framework.CastOptions import
com.google.android.gms.cast.framework.OptionsProvider import com.google.android.gms.cast.framework.SessionProvider class CastOptionsProvider : OptionsProvider { override fun getCastOptions (context: Context): CastOptions { return CastOptions.Builder() .setReceiverApplicationId(CastMediaControlIntent. DEFAULT_MEDIA_RECEIVER_APPLICATION_ID) .build() } override fun getAdditionalSessionProviders (context: Context): MutableList<SessionProvider>? { return null } }
© DMM OptionsProvider <meta-data android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME" android:value="org.takathemax.castsample.ui.player.CastOptionsProvider" />
© DMM CastContextの初期化 CastContext.getSharedInstance( context, Dispatchers.IO.asExecutor() ) .addOnSuccessListener { castContext
-> //TODO: CastContextを使用してやりたいこと } .addOnFailureListener { exception -> //TODO: error handling }
© DMM ボタンの表示 • お手軽にやりたいならCastButtonFactoryを使用すればOK • ダイアログをカスタムしたものにする場合はMediaRouterを使用してルー トの選択状態を更新したりするのを自前で実装する必要がある • 今回はCastButtonFactoryの方法を紹介
© DMM ボタンの表示 @Composable fun CastButton( modifier: Modifier = Modifier
){ AndroidView( modifier = modifier, factory = ::MediaRouteButton , update = { CastButtonFactory .setUpMediaRouteButton( it.context, it) }, ) } Scaffold( modifier = Modifier .fillMaxSize(), topBar = { TopAppBar( title = { Text("CastSample") }, actions = { CastButton() } ) }, content = { PlayerBlock() } )
© DMM 動画をキャストする 1. キャストセッションを監視 • SessionManagerListener 2. セッションが繋がったら動画情報を送る •
RemoteMediaClient
© DMM 動画をキャストする class CastViewModel : ViewModel() ,SessionManagerListener<CastSession> { //
説明しやすい様にViewModelにExoPlayerにMediaItemを持っているとする val mediaItem = MediaItem.fromUri( "streaming url" ) override fun onSessionStarted (session: CastSession , sessionId: String) { // ここでRemoteMediaClient に情報を渡す } } // CastContext にアクセスできるところ castContext .sessionManager .addSessionManagerListener(viewModel , CastSession::class.java)
© DMM 動画をキャストする class CastViewModel : ViewModel() ,SessionManagerListener<CastSession> { val
mediaItem = MediaItem.fromUri( "streaming url" ) override fun onSessionStarted (session: CastSession , sessionId: String) { val mediaInfo = MediaInfo .Builder( mediaItem.localConfiguration ?.uri.toString()) .setStreamType(MediaInfo. STREAM_TYPE_BUFFERED) .setContentType( "videos/mp4") .build() val options = MediaLoadOptions.Builder() .setAutoplay( true) .build() session. remoteMediaClient?.load(mediaInfo , options) } } これで完了
© DMM 動画をキャストする //再生 session.remoteMediaClient?.play() //一時停止 session.remoteMediaClient?.pause() //任意の場所にシーク val targetPosition
= 1000L val mediaSeekOptions = MediaSeekOptions.Builder() .setPosition(targetPosition).build() session.remoteMediaClient?.seek(mediaSeekOptions) // 倍速 session.remoteMediaClient?.setPlaybackRate( 2.0) // 一秒ごとに再生位置を取得する session.remoteMediaClient?.addProgressListener( { progressMs, _ -> // 特定の再生位置になったら何かするとか }, 1000L ) ExoPlayerを利用している場合は CastPlayerを利用できる
© DMM ご清聴ありがとうございました