Pro Yearly is on sale from $80 to $50! »

Androidでオーディオアプリを作るということ

E6d26a51159a7863cac28e9d12ccd389?s=47 rmakiyama
September 26, 2020

 Androidでオーディオアプリを作るということ

Androidでオーディオアプリを作るときに考慮すべきところなどを簡単に。

E6d26a51159a7863cac28e9d12ccd389?s=128

rmakiyama

September 26, 2020
Tweet

Transcript

  1. "OESPJEͰ ΦʔσΟΦΞϓϦΛ ࡞Δͱ͍͏͜ͱ Zli x ΤΩαΠτ ߹ಉLT 2020/09/26 ryo makiyama

  2. ɹɹࣗݾ঺հ •຀ࢁྎ •Radiotalkגࣜձࣾ •AndroidΤϯδχΞ • @_rmakiyama • rmakiyama

  3. Ի੠Λ࠶ੜ͢Δ

  4. Ի੠Λ࠶ੜ͢Δʹ͸ʁ • AudioTrack • SoundPool • MediaPlayer • ExoPlayer •

    etc…
  5. Ի੠Λ࠶ੜ͢Δʹ͸ʁ • AudioTrack • ੜͷԻ੠σʔλΛѻ͑Δ • ࠷΋஗Ԇ͕গͳ͍ • ѻ͍͕೉͍͠… •

    SoundPool • ୹͍Ի੠ʹద͍ͯ͠Δ • ޮՌԻͳͲ • ෛՙ͕௿͍ • ஗Ԇ͕গͳ͍
  6. Ի੠Λ࠶ੜ͢Δʹ͸ʁ • MediaPlayer • ࠷΋Ұൠత • ө૾ʹ΋ରԠ • ѻ͍͕؆୯ •

    HLSະରԠ • ExoPlayer • Google੡ͷϥΠϒϥϦ • ө૾ʹ΋ରԠ • ΧελϚΠζੑ͕ߴ͍ • HLS΍DASH౳ʹରԠ
  7. 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)
  8. ؆୯

  9. ؆୯

  10. ΦʔσΟΦΞϓϦʹٻΊΒΕΔ͜ͱ • όοΫάϥ΢ϯυͰ࠶ੜͰ͖Δ • ΠϠϗϯ͕ൈ͚ͨΒԻ੠͕ࢭ·Δ • ผͷΞϓϦͰԻ੠Λ࠶ੜ͢Δͱఀࢭ͢Δ • ༷ʑͳσόΠε͔Βૢ࡞͕Ͱ͖Δ •

    etc…
  11. Ͳ͏΍ͬͯ΍ͬͯΔͷ

  12. ΦʔσΟΦΞϓϦʹٻΊΒΕΔ͜ͱ • όοΫάϥ΢ϯυͰ࠶ੜͰ͖Δ • ΠϠϗϯ͕ൈ͚ͨΒԻ੠͕ࢭ·Δ • ผͷΞϓϦͰԻ੠Λ࠶ੜ͢Δͱఀࢭ͢Δ • ༷ʑͳσόΠε͔Βૢ࡞͕Ͱ͖Δ •

    etc… AndroidͷServiceΛར༻͢Δ
  13. ΦʔσΟΦΞϓϦʹٻΊΒΕΔ͜ͱ • όοΫάϥ΢ϯυͰ࠶ੜͰ͖Δ • ΠϠϗϯ͕ൈ͚ͨΒԻ੠͕ࢭ·Δ • ผͷΞϓϦͰԻ੠Λ࠶ੜ͢Δͱఀࢭ͢Δ • ༷ʑͳσόΠε͔Βૢ࡞͕Ͱ͖Δ •

    etc… ExoPlayerઌੜ͕΍ͬͯ͘ΕΔ
  14. ΦʔσΟΦΞϓϦʹٻΊΒΕΔ͜ͱ • όοΫάϥ΢ϯυͰ࠶ੜͰ͖Δ • ΠϠϗϯ͕ൈ͚ͨΒԻ੠͕ࢭ·Δ • ผͷΞϓϦͰԻ੠Λ࠶ੜ͢Δͱఀࢭ͢Δ • ༷ʑͳσόΠε͔Βૢ࡞͕Ͱ͖Δ •

    etc…
  15. headset watch tv auto

  16. ༷ʑͳσόΠε͔Β ૢ࡞͞ΕΔ͜ͱΛ ૝ఆ͢Δඞཁ͕͋Δ

  17. ΦʔσΟΦΞϓϦͷਪ঑ΞʔΩςΫνϟ • ΫϥΠΞϯτ/αʔόʔઃܭ • ϝσΟΞίϯτϩʔϥʔ(ΫϥΠΞϯτ) • ϝσΟΞηογϣϯ(αʔόʔ) • UI౳ʹΑΔૢ࡞ͱ
 ίϯςϯπ৘ใɾϓϨΠϠʔૢ࡞Λ෼͚ͨ

    ref. https:"//developer.android.com/guide/topics/media-apps/media-apps-overview
  18. UI/ϝσΟΞίϯτϩʔϥʔ(ΫϥΠΞϯτ) • UI͸ίϯτϩʔϥʔͷΈͱ΍ΓͱΓ • ϓϨΠϠʔࣗମͱ͸௚઀΍ΓऔΓΛ͠ͳ͍ • ΞΫγϣϯ͸ηογϣϯ΁ͷίʔϧόοΫʹ • ۂ৘ใͷมߋͳͲ͸ηογϣϯ͔Β
 ίϯτϩʔϥʔ͕ίʔϧόοΫܗࣜͰड͚औΔ

  19. ϝσΟΞηογϣϯ/ϓϨΠϠʔ(αʔόʔ) • 1ͭͷηογϣϯͰෳ਺ͷίϯτϩʔϥʔ͔Β
 ίʔϧόοΫΛड͚Δ͜ͱ͕Ͱ͖Δ • ϓϨΠϠʔ͸ηογϣϯ͔ΒͷΈૢ࡞͞ΕΔ • ίϯτϩʔϥʔ͔ΒͷίʔϧόοΫʹΑΓૢ࡞

  20. ΦʔσΟΦΞϓϦ֓ཁ ref. https:"//developer.android.com/guide/topics/media-apps/media-apps-overview controller session player ui devices/controller

  21. ࣮૷ฤ%

  22. ΦʔσΟΦΞϓϦ֓ཁʢ࣮૷دΓʣ ref. https:"//developer.android.com/guide/topics/media-apps/media-apps-overview

  23. 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) ɹɹɹɹɹɹ …
  24. MediaBrowserService(session/player) override fun onCreate() { … } private val myCallback

    = object : MediaSessionCompat.Callback() { override fun onPrepare() {} override fun onPlay() {} override fun onPause() {} override fun onStop() {} … }
  25. MediaBrowserService(session/player) … override fun onGetRoot( clientPackageName: String, clientUid: Int, rootHints:

    Bundle? ): BrowserRoot? { "// ઀ଓ͞ΕͨΫϥΠΞϯτͷݕূΛ͢Δ "// ઀ଓΛڋ൱͢Δͱ͖͸nullΛฦ͢ return BrowserRoot("root", null) }
  26. MediaBrowserService(session/player) …
 override fun onLoadChildren( parentId: String, result: Result<MutableList<MediaBrowserCompat.MediaItem">> )

    { "// ΫϥΠΞϯτʹϝσΟΞͷϦετΛฦ͢ val list = getMetadata() result.sendResult(list) } …
  27. 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
  28. 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()
  29. 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()
  30. Activity(UI/controller) class MediaPlayerActivity : AppCompatActivity() { … private var controllerCallback

    = object : MediaControllerCompat.Callback() { override fun onMetadataChanged(metadata: MediaMetadataCompat?) { "// ࠶ੜதͷίϯςϯπ৘ใͷมԽʹԠͯ͡UIΛߋ৽ } override fun onPlaybackStateChanged(state: PlaybackStateCompat?) { "// ࠶ੜͷঢ়ଶ(࠶ੜத΍ఀࢭ)ͷมԽʹԠͯ͡UIΛߋ৽͢Δ } }
  31. ׬શʹཧղͨ͠ʁ

  32. ·ͱΊ •Ի੠Λ࠶ੜ͢Δ͚ͩͳΒ؆୯ʂ& •ΦʔσΟΦΞϓϦͰߟྀ͢Δ͜ͱ͸ҙ֎ͱଟ͍ • ࠓ೔࿩͍ͯ͠ͳ͍͜ͱ΋ͨ͘͞Μ͋Δ…ʂ •ڵຯ͕༙͍ͨΒ࡞ͬͯΈΑ͏ʂ' • खΛಈ͔͢ͷେࣄʂ%