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
Androidでオーディオアプリを作るということ
Search
rmakiyama
September 26, 2020
Technology
1
3.2k
Androidでオーディオアプリを作るということ
Androidでオーディオアプリを作るときに考慮すべきところなどを簡単に。
rmakiyama
September 26, 2020
Tweet
Share
More Decks by rmakiyama
See All by rmakiyama
UI State設計とテスト方針
rmakiyama
4
1k
KMPプロジェクトでマニュアルDIを使う選択
rmakiyama
0
260
Jetpack Composeとデザインシステム
rmakiyama
0
780
TextField theme in Compose
rmakiyama
0
250
Androidエンジニアが1人という不安と向き合う
rmakiyama
6
6.7k
Jetpack Compose Canvas入門
rmakiyama
0
1.4k
HiltはDIをどうやってやっているのか
rmakiyama
1
250
Radiotalk Androidアプリにおけるモジュール分割の課題とこれから
rmakiyama
1
290
getChangePayload in DiffUtil
rmakiyama
0
3k
Other Decks in Technology
See All in Technology
2025/3/1 公共交通オープンデータデイ2025
morohoshi
0
100
30→150人のエンジニア組織拡大に伴うアジャイル文化を醸成する役割と取り組みの変化
nagata03
0
290
Amazon Athenaから利用時のGlueのIcebergテーブルのメンテナンスについて
nayuts
0
110
AIエージェント入門
minorun365
PRO
33
19k
DeepSeekとは?何がいいの? - Databricksと学ぶDeepSeek! 〜これからのLLMに備えよ!〜
taka_aki
1
170
【詳説】コンテンツ配信 システムの複数機能 基盤への拡張
hatena
0
290
Ruby on Railsで持続可能な開発を行うために取り組んでいること
am1157154
3
160
4th place solution Eedi - Mining Misconceptions in Mathematics
rist
0
150
Exadata Database Service on Cloud@Customer セキュリティ、ネットワーク、および管理について
oracle4engineer
PRO
2
1.6k
ABWG2024採択者が語るエンジニアとしての自分自身の見つけ方〜発信して、つながって、世界を広げていく〜
maimyyym
1
200
Snowflake ML モデルを dbt データパイプラインに組み込む
estie
0
110
What's new in Go 1.24?
ciarana
1
110
Featured
See All Featured
Thoughts on Productivity
jonyablonski
69
4.5k
Bash Introduction
62gerente
611
210k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.3k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
27
1.9k
Into the Great Unknown - MozCon
thekraken
35
1.6k
Scaling GitHub
holman
459
140k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
Making the Leap to Tech Lead
cromwellryan
133
9.1k
Large-scale JavaScript Application Architecture
addyosmani
511
110k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Automating Front-end Workflow
addyosmani
1369
200k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Transcript
"OESPJEͰ ΦʔσΟΦΞϓϦΛ ࡞Δͱ͍͏͜ͱ Zli x ΤΩαΠτ ߹ಉLT 2020/09/26 ryo makiyama
ɹɹࣗݾհ •ࢁྎ •Radiotalkגࣜձࣾ •AndroidΤϯδχΞ • @_rmakiyama • rmakiyama
ԻΛ࠶ੜ͢Δ
ԻΛ࠶ੜ͢Δʹʁ • AudioTrack • SoundPool • MediaPlayer • ExoPlayer •
etc…
ԻΛ࠶ੜ͢Δʹʁ • AudioTrack • ੜͷԻσʔλΛѻ͑Δ • ࠷Ԇ͕গͳ͍ • ѻ͍͕͍͠… •
SoundPool • ͍Իʹద͍ͯ͠Δ • ޮՌԻͳͲ • ෛՙ͕͍ • Ԇ͕গͳ͍
ԻΛ࠶ੜ͢Δʹʁ • MediaPlayer • ࠷Ұൠత • ө૾ʹରԠ • ѻ͍͕؆୯ •
HLSະରԠ • ExoPlayer • GoogleͷϥΠϒϥϦ • ө૾ʹରԠ • ΧελϚΠζੑ͕ߴ͍ • HLSDASHʹରԠ
ExoPlayer val audioUri = Uri.parse(“https:"//sample.jp/media/media1.mp3”) val player = SimpleExoPlayer.Builder(context).build() val
sourceFactory = DefaultDataSourceFactory( context, Util.getUserAgent(context, "sample") ) val extractorsFactory = DefaultExtractorsFactory() val source = ProgressiveMediaSource.Factory(sourceFactory, extractorsFactory) .createMediaSource(audioUri) player.prepare(source)
؆୯
؆୯
ΦʔσΟΦΞϓϦʹٻΊΒΕΔ͜ͱ • όοΫάϥϯυͰ࠶ੜͰ͖Δ • ΠϠϗϯ͕ൈ͚ͨΒԻ͕ࢭ·Δ • ผͷΞϓϦͰԻΛ࠶ੜ͢Δͱఀࢭ͢Δ • ༷ʑͳσόΠε͔Βૢ࡞͕Ͱ͖Δ •
etc…
Ͳ͏ͬͯͬͯΔͷ
ΦʔσΟΦΞϓϦʹٻΊΒΕΔ͜ͱ • όοΫάϥϯυͰ࠶ੜͰ͖Δ • ΠϠϗϯ͕ൈ͚ͨΒԻ͕ࢭ·Δ • ผͷΞϓϦͰԻΛ࠶ੜ͢Δͱఀࢭ͢Δ • ༷ʑͳσόΠε͔Βૢ࡞͕Ͱ͖Δ •
etc… AndroidͷServiceΛར༻͢Δ
ΦʔσΟΦΞϓϦʹٻΊΒΕΔ͜ͱ • όοΫάϥϯυͰ࠶ੜͰ͖Δ • ΠϠϗϯ͕ൈ͚ͨΒԻ͕ࢭ·Δ • ผͷΞϓϦͰԻΛ࠶ੜ͢Δͱఀࢭ͢Δ • ༷ʑͳσόΠε͔Βૢ࡞͕Ͱ͖Δ •
etc… ExoPlayerઌੜ͕ͬͯ͘ΕΔ
ΦʔσΟΦΞϓϦʹٻΊΒΕΔ͜ͱ • όοΫάϥϯυͰ࠶ੜͰ͖Δ • ΠϠϗϯ͕ൈ͚ͨΒԻ͕ࢭ·Δ • ผͷΞϓϦͰԻΛ࠶ੜ͢Δͱఀࢭ͢Δ • ༷ʑͳσόΠε͔Βૢ࡞͕Ͱ͖Δ •
etc…
headset watch tv auto
༷ʑͳσόΠε͔Β ૢ࡞͞ΕΔ͜ͱΛ ఆ͢Δඞཁ͕͋Δ
ΦʔσΟΦΞϓϦͷਪΞʔΩςΫνϟ • ΫϥΠΞϯτ/αʔόʔઃܭ • ϝσΟΞίϯτϩʔϥʔ(ΫϥΠΞϯτ) • ϝσΟΞηογϣϯ(αʔόʔ) • UIʹΑΔૢ࡞ͱ ίϯςϯπใɾϓϨΠϠʔૢ࡞Λ͚ͨ
ref. https:"//developer.android.com/guide/topics/media-apps/media-apps-overview
UI/ϝσΟΞίϯτϩʔϥʔ(ΫϥΠΞϯτ) • UIίϯτϩʔϥʔͷΈͱΓͱΓ • ϓϨΠϠʔࣗମͱΓऔΓΛ͠ͳ͍ • ΞΫγϣϯηογϣϯͷίʔϧόοΫʹ • ۂใͷมߋͳͲηογϣϯ͔Β ίϯτϩʔϥʔ͕ίʔϧόοΫܗࣜͰड͚औΔ
ϝσΟΞηογϣϯ/ϓϨΠϠʔ(αʔόʔ) • 1ͭͷηογϣϯͰෳͷίϯτϩʔϥʔ͔Β ίʔϧόοΫΛड͚Δ͜ͱ͕Ͱ͖Δ • ϓϨΠϠʔηογϣϯ͔ΒͷΈૢ࡞͞ΕΔ • ίϯτϩʔϥʔ͔ΒͷίʔϧόοΫʹΑΓૢ࡞
ΦʔσΟΦΞϓϦ֓ཁ ref. https:"//developer.android.com/guide/topics/media-apps/media-apps-overview controller session player ui devices/controller
࣮ฤ%
ΦʔσΟΦΞϓϦ֓ཁʢ࣮دΓʣ ref. https:"//developer.android.com/guide/topics/media-apps/media-apps-overview
MediaBrowserService(session/player) class MyMediaService : MediaBrowserServiceCompat() { private lateinit var mediaSession:
MediaSessionCompat private lateinit var player: Player override fun onCreate() { super.onCreate() mediaSession = MediaSessionCompat(this, "MyMediaService").apply { … setCallback(myCallback) ɹɹɹɹɹɹ …
MediaBrowserService(session/player) override fun onCreate() { … } private val myCallback
= object : MediaSessionCompat.Callback() { override fun onPrepare() {} override fun onPlay() {} override fun onPause() {} override fun onStop() {} … }
MediaBrowserService(session/player) … override fun onGetRoot( clientPackageName: String, clientUid: Int, rootHints:
Bundle? ): BrowserRoot? { "// ଓ͞ΕͨΫϥΠΞϯτͷݕূΛ͢Δ "// ଓΛڋ൱͢Δͱ͖nullΛฦ͢ return BrowserRoot("root", null) }
MediaBrowserService(session/player) … override fun onLoadChildren( parentId: String, result: Result<MutableList<MediaBrowserCompat.MediaItem">> )
{ "// ΫϥΠΞϯτʹϝσΟΞͷϦετΛฦ͢ val list = getMetadata() result.sendResult(list) } …
Activity(UI/controller) class MediaPlayerActivity : AppCompatActivity() { private lateinit var mediaBrowser:
MediaBrowserCompat private lateinit var mediaController: MediaControllerCompat override fun onCreate(savedInstanceState: Bundle?) { … mediaBrowser = MediaBrowserCompat( this, ComponentName(this, MyMediaService"::class.java), connectionCallbacks, null
Activity(UI/controller) class MediaPlayerActivity : AppCompatActivity() { private lateinit var mediaBrowser:
MediaBrowserCompat private lateinit var mediaController: MediaControllerCompat override fun onCreate(savedInstanceState: Bundle?) { … } override fun onStart() { super.onStart() "// MediaBrowserServiceʹଓ mediaBrowser.connect()
Activity(UI/controller) class MediaPlayerActivity : AppCompatActivity() { … private lateinit var
mediaController: MediaControllerCompat … private val connectionCallbacks = object : MediaBrowserCompat.ConnectionCallback() { override fun onConnected() { "// sessionͷτʔΫϯ͔ΒcontrollerΛੜ mediaController = MediaControllerCompat(this@MediaPlayerActivity, mediaBrowser.sessionToken) .apply { registerCallback(controllerCallback) } "// UIͷૢ࡞ʹԠͯ͡controllerΛհͯ͠ΦʔσΟΦΛૢ࡞ "// ྫ) ࠶ੜɿmediaController.transportControls.play()
Activity(UI/controller) class MediaPlayerActivity : AppCompatActivity() { … private var controllerCallback
= object : MediaControllerCompat.Callback() { override fun onMetadataChanged(metadata: MediaMetadataCompat?) { "// ࠶ੜதͷίϯςϯπใͷมԽʹԠͯ͡UIΛߋ৽ } override fun onPlaybackStateChanged(state: PlaybackStateCompat?) { "// ࠶ੜͷঢ়ଶ(࠶ੜதఀࢭ)ͷมԽʹԠͯ͡UIΛߋ৽͢Δ } }
શʹཧղͨ͠ʁ
·ͱΊ •ԻΛ࠶ੜ͢Δ͚ͩͳΒ؆୯ʂ& •ΦʔσΟΦΞϓϦͰߟྀ͢Δ͜ͱҙ֎ͱଟ͍ • ࠓ͍ͯ͠ͳ͍͜ͱͨ͘͞Μ͋Δ…ʂ •ڵຯ͕༙͍ͨΒ࡞ͬͯΈΑ͏ʂ' • खΛಈ͔͢ͷେࣄʂ%