Androidでオーディオアプリを作るときに考慮すべきところなどを簡単に。
"OESPJEͰΦʔσΟΦΞϓϦΛ࡞Δͱ͍͏͜ͱZli x ΤΩαΠτ ߹ಉLT2020/09/26 ryo makiyama
View Slide
ɹɹࣗݾհ•ࢁྎ•Radiotalkגࣜձࣾ•AndroidΤϯδχΞ• @_rmakiyama• rmakiyama
ԻΛ࠶ੜ͢Δ
ԻΛ࠶ੜ͢Δʹʁ• AudioTrack• SoundPool• MediaPlayer• ExoPlayer• etc…
ԻΛ࠶ੜ͢Δʹʁ• AudioTrack• ੜͷԻσʔλΛѻ͑Δ• ࠷Ԇ͕গͳ͍• ѻ͍͕͍͠…• SoundPool• ͍Իʹద͍ͯ͠Δ• ޮՌԻͳͲ• ෛՙ͕͍• Ԇ͕গͳ͍
ԻΛ࠶ੜ͢Δʹʁ• MediaPlayer• ࠷Ұൠత• ө૾ʹରԠ• ѻ͍͕؆୯• HLSະରԠ• ExoPlayer• GoogleͷϥΠϒϥϦ• ө૾ʹରԠ• ΧελϚΠζੑ͕ߴ͍• HLSDASHʹରԠ
ExoPlayerval 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ઌੜ͕ͬͯ͘ΕΔ
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-overviewcontroller session playeruidevices/controller
࣮ฤ%
ΦʔσΟΦΞϓϦ֓ཁʢ࣮دΓʣref. https:"//developer.android.com/guide/topics/media-apps/media-apps-overview
MediaBrowserService(session/player)class MyMediaService : MediaBrowserServiceCompat() {private lateinit var mediaSession: MediaSessionCompatprivate lateinit var player: Playeroverride 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>) {"// ΫϥΠΞϯτʹϝσΟΞͷϦετΛฦ͢val list = getMetadata()result.sendResult(list)}…
Activity(UI/controller)class MediaPlayerActivity : AppCompatActivity() {private lateinit var mediaBrowser: MediaBrowserCompatprivate lateinit var mediaController: MediaControllerCompatoverride fun onCreate(savedInstanceState: Bundle?) {…mediaBrowser = MediaBrowserCompat(this,ComponentName(this, MyMediaService"::class.java),connectionCallbacks,null
Activity(UI/controller)class MediaPlayerActivity : AppCompatActivity() {private lateinit var mediaBrowser: MediaBrowserCompatprivate lateinit var mediaController: MediaControllerCompatoverride 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([email protected], 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Λߋ৽͢Δ}}
શʹཧղͨ͠ʁ
·ͱΊ•ԻΛ࠶ੜ͢Δ͚ͩͳΒ؆୯ʂ&•ΦʔσΟΦΞϓϦͰߟྀ͢Δ͜ͱҙ֎ͱଟ͍• ࠓ͍ͯ͠ͳ͍͜ͱͨ͘͞Μ͋Δ…ʂ•ڵຯ͕༙͍ͨΒ࡞ͬͯΈΑ͏ʂ'• खΛಈ͔͢ͷେࣄʂ%