Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Implementing Audio on Android

Caren
November 05, 2017
260

Implementing Audio on Android

Caren

November 05, 2017
Tweet

Transcript

  1. How is Audio Processed? Latency - Time delay as a

    signal passes through a system
  2. Latency - Time delay as a signal passes through a

    system How is Audio Processed?
  3. Latency - Time delay as a signal passes through a

    system How is Audio Processed?
  4. Latency - Time delay as a signal passes through a

    system How is Audio Processed?
  5. How is Audio Processed? Audio hardware consumes data at constant

    rate When we pass audio files to be played, we have to make sure it gets processed in time to meet the deadlines
  6. How is Audio Processed? Audio hardware consumes data at constant

    rate When we pass audio files to be played, we have to make sure it gets processed in time to meet the deadlines Otherwise, when deadlines are missed, you can get silent sounds or weird ‘static’ sounds
  7. MediaPlayer Easily fetch, decode and play audio with minimal setup

    Supports :
 Local resources
 Internal URIs (from content resolver)
 External URLs (http streaming)
  8. MediaPlayer void playAudioFile(String audioFilePath) {
 MediaPlayer mediaPlayer = new MediaPlayer();


    try {
 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(audioFilePath);
 mediaPlayer.prepare();
 mediaPlayer.start();
 } catch (IOException e) {
 Log.e(TAG, "Error playing audio file: " + audioFilePath);
 mediaPlayer.release();
 }
 }
  9. MediaPlayer void playAudioFile(String audioFilePath) {
 MediaPlayer mediaPlayer = new MediaPlayer();


    try {
 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(audioFilePath);
 mediaPlayer.prepare();
 mediaPlayer.start();
 } catch (IOException e) {
 Log.e(TAG, "Error playing audio file: " + audioFilePath);
 mediaPlayer.release();
 }
 }
  10. MediaPlayer void playAudioFile(String audioFilePath) {
 MediaPlayer mediaPlayer = new MediaPlayer();


    try {
 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(audioFilePath);
 mediaPlayer.prepare();
 mediaPlayer.start();
 } catch (IOException e) {
 Log.e(TAG, "Error playing audio file: " + audioFilePath);
 mediaPlayer.release();
 }
 }
  11. MediaPlayer void playAudioFile(String audioFilePath) {
 MediaPlayer mediaPlayer = new MediaPlayer();


    try {
 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(audioFilePath);
 mediaPlayer.prepare();
 mediaPlayer.start();
 } catch (IOException e) {
 Log.e(TAG, "Error playing audio file: " + audioFilePath);
 mediaPlayer.release();
 }
 }
  12. MediaPlayer void playAudioFile(String audioFilePath) {
 MediaPlayer mediaPlayer = new MediaPlayer();


    try {
 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(audioFilePath);
 mediaPlayer.prepare();
 mediaPlayer.start();
 } catch (IOException e) {
 Log.e(TAG, "Error playing audio file: " + audioFilePath);
 mediaPlayer.release();
 }
 }
  13. MediaPlayer void playAudioFile(String audioFilePath) {
 MediaPlayer mediaPlayer = new MediaPlayer();


    try {
 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(audioFilePath);
 mediaPlayer.prepare();
 mediaPlayer.start();
 } catch (IOException e) {
 Log.e(TAG, "Error playing audio file: " + audioFilePath);
 mediaPlayer.release();
 }
 }
  14. MediaPlayer void playAudioFile(String audioFilePath) {
 MediaPlayer mediaPlayer = new MediaPlayer();


    try {
 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(audioFilePath);
 mediaPlayer.prepare();
 mediaPlayer.start();
 } catch (IOException e) {
 Log.e(TAG, "Error playing audio file: " + audioFilePath);
 mediaPlayer.release();
 }
 }
  15. MediaPlayer MediaPlayer is state based, can easily caused undesired behaviors

    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(audioFilePath);
 mediaPlayer.prepare();
 mediaPlayer.start(); or mediaPlayer.pause() or mediaPlayer.seekTo(); IDLE
  16. MediaPlayer MediaPlayer is state based, can easily caused undesired behaviors

    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(audioFilePath);
 mediaPlayer.prepare();
 mediaPlayer.start(); or mediaPlayer.pause() or mediaPlayer.seekTo(); INITIALIZED
  17. MediaPlayer MediaPlayer is state based, can easily caused undesired behaviors

    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(audioFilePath);
 mediaPlayer.prepare();
 mediaPlayer.start(); or mediaPlayer.pause() or mediaPlayer.seekTo(); PREPARED
  18. MediaPlayer MediaPlayer is state based, can easily caused undesired behaviors

    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource(audioFilePath);
 mediaPlayer.prepare();
 mediaPlayer.start(); or mediaPlayer.pause() or mediaPlayer.seekTo();
  19. MediaPlayer : Common Errors Not handling onError Performing actions in

    wrong state Unsupported file types Not releasing after use
  20. SoundPool Uses the MediaPlayer service to decode the audio Collection

    of samples from the APK that can be loaded into memory
  21. SoundPool Uses the MediaPlayer service to decode the audio Collection

    of samples from the APK that can be loaded into memory Able to manage number of audio streams
 IE : able to do sound mixing
  22. SoundPool Uses the MediaPlayer service to decode the audio Collection

    of samples from the APK that can be loaded into memory Able to manage number of audio streams
 IE : able to do sound mixing Can set priority when playing sound
  23. SoundPool SoundPool mSoundPool = new SoundPool.Builder()
 .setAudioAttributes(mAudioAttributes)
 .setMaxStreams(MAX_SOUND_STREAMS)
 .build();
 


    int loadedSoundId = mSoundPool.load(audioFilePath, 1);
 
 mSoundPool.play(loadedSoundId,
 volumeToPlaySound, volumeToPlaySound,
 REGULAR_PRIORITY_SOUND, NO_LOOP, DEFAULT_PLAYBACK_RATE);
  24. SoundPool SoundPool mSoundPool = new SoundPool.Builder()
 .setAudioAttributes(mAudioAttributes)
 .setMaxStreams(MAX_SOUND_STREAMS)
 .build();
 


    int loadedSoundId = mSoundPool.load(audioFilePath, 1);
 
 mSoundPool.play(loadedSoundId,
 volumeToPlaySound, volumeToPlaySound,
 REGULAR_PRIORITY_SOUND, NO_LOOP, DEFAULT_PLAYBACK_RATE);
  25. SoundPool SoundPool mSoundPool = new SoundPool.Builder()
 .setAudioAttributes(mAudioAttributes)
 .setMaxStreams(MAX_SOUND_STREAMS)
 .build();
 


    int loadedSoundId = mSoundPool.load(audioFilePath, 1);
 
 mSoundPool.play(loadedSoundId,
 volumeToPlaySound, volumeToPlaySound,
 REGULAR_PRIORITY_SOUND, NO_LOOP, DEFAULT_PLAYBACK_RATE);
  26. ExoPlayer Open source project (not part of Android framework) Pros:


    Ability to update player along with application
  27. ExoPlayer Open source project (not part of Android framework) Pros:


    Ability to update player along with application Fewer device specific issues across different versions of Android
  28. ExoPlayer Open source project (not part of Android framework) Pros:


    Ability to update player along with application Fewer device specific issues across different versions of Android Ability to customize and extend the player
  29. ExoPlayer : Talks ExoPlayer : Flexible Media Playback for Android


    Google IO ‘17 Advanced Exoplayer
 Effie Barak
  30. AudioFocus Audio from different apps can play simultaneously (system does

    not have control over which streams play) If individual apps don’t properly handle audio focus it will result in a bad user experience
  31. AudioFocus : Scenario User is currently in your app and

    playing audio User goes into another media app that plays audio
  32. AudioFocus : Scenario User is currently in your app and

    playing audio User goes into another media app that plays audio If not properly handled, both apps will now play their audio stream and nothing will be heard
  33. AudioFocus : Proper Flow Request audio focus Start playback after

    audio focus is successfully granted Handle audio focus changes through onAudioFocusChangedListener()
  34. AudioFocus : Intentions AUDIOFOCUS_GAIN : Indefinite AUDIOFOCUS_TRANSIENT : temporary (phone

    call) AUDIOFOCUS_TRANSIENT_MAY_DUCK : temporary (notification)
  35. Sounds on the June Oven Common sounds (tap, cancel, accept,

    back) are eagerly loaded into a SoundPool for low latency playback.
  36. Sounds on the June Oven Common sounds (tap, cancel, accept,

    back) are eagerly loaded into a SoundPool for low latency playback. All other sounds are played with the MediaPlayer
  37. Sounds on the June Oven Common sounds (tap, cancel, accept,

    back) are eagerly loaded into a SoundPool for low latency playback. All other sounds are played with the MediaPlayer Sounds can request to be played immediately