Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Androidでオーディオアプリを作るということ
Search
rmakiyama
September 26, 2020
Technology
1
3.3k
Androidでオーディオアプリを作るということ
Androidでオーディオアプリを作るときに考慮すべきところなどを簡単に。
rmakiyama
September 26, 2020
Tweet
Share
More Decks by rmakiyama
See All by rmakiyama
UI State設計とテスト方針
rmakiyama
4
1.1k
KMPプロジェクトでマニュアルDIを使う選択
rmakiyama
0
440
Jetpack Composeとデザインシステム
rmakiyama
0
1.1k
TextField theme in Compose
rmakiyama
0
310
Androidエンジニアが1人という不安と向き合う
rmakiyama
6
6.9k
Jetpack Compose Canvas入門
rmakiyama
0
1.5k
HiltはDIをどうやってやっているのか
rmakiyama
1
300
Radiotalk Androidアプリにおけるモジュール分割の課題とこれから
rmakiyama
1
330
getChangePayload in DiffUtil
rmakiyama
0
3.2k
Other Decks in Technology
See All in Technology
会社紹介資料 / Sansan Company Profile
sansan33
PRO
11
390k
Oracle Database@AWS:サービス概要のご紹介
oracle4engineer
PRO
0
120
私も懇親会は苦手でした ~苦手だからこそ懇親会を楽しむ方法~ / 20251127 Masaki Okuda
shift_evolve
PRO
4
560
Noを伝える技術2025: 爆速合意形成のためのNICOフレームワーク速習 #pmconf2025
aki_iinuma
2
1.2k
AIにおける自由の追求
shujisado
3
470
翻訳・対話・越境で強いチームワークを作ろう! / Building Strong Teamwork through Interpretation, Dialogue, and Border-Crossing
ar_tama
4
1.6k
Introduction to Sansan, inc / Sansan Global Development Center, Inc.
sansan33
PRO
0
2.9k
手動から自動へ、そしてその先へ
moritamasami
0
200
Sansan Engineering Unit 紹介資料
sansan33
PRO
1
3.3k
なぜフロントエンド技術を追うのか?なぜカンファレンスに参加するのか?
sakito
9
2k
Microsoft Agent 365 を 30 分でなんとなく理解する
skmkzyk
1
320
Bill One 開発エンジニア 紹介資料
sansan33
PRO
4
16k
Featured
See All Featured
KATA
mclloyd
PRO
32
15k
Imperfection Machines: The Place of Print at Facebook
scottboms
269
13k
Become a Pro
speakerdeck
PRO
30
5.7k
Building an army of robots
kneath
306
46k
Documentation Writing (for coders)
carmenintech
76
5.2k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.7k
How to train your dragon (web standard)
notwaldorf
97
6.4k
Side Projects
sachag
455
43k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
How to Ace a Technical Interview
jacobian
280
24k
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Λߋ৽͢Δ } }
શʹཧղͨ͠ʁ
·ͱΊ •ԻΛ࠶ੜ͢Δ͚ͩͳΒ؆୯ʂ& •ΦʔσΟΦΞϓϦͰߟྀ͢Δ͜ͱҙ֎ͱଟ͍ • ࠓ͍ͯ͠ͳ͍͜ͱͨ͘͞Μ͋Δ…ʂ •ڵຯ͕༙͍ͨΒ࡞ͬͯΈΑ͏ʂ' • खΛಈ͔͢ͷେࣄʂ%