Play audio and video at the same time in Android

11,690

You can handle this with Audio Focus. Two or more Android apps can play audio to the same output stream simultaneously. The system mixes everything together. While this is technically impressive, it can be very aggravating to a user. To avoid every music app playing at the same time, Android introduces the idea of audio focus. Only one app can hold audio focus at a time.

When your app needs to output audio, it should request audio focus. When it has focus, it can play sound. However, after you acquire audio focus you may not be able to keep it until you’re done playing. Another app can request focus, which preempts your hold on audio focus. If that happens your app should pause playing or lower its volume to let users hear the new audio source more easily.

Beginning with Android 8.0 (API level 26), when you call requestAudioFocus() you must supply an AudioFocusRequest parameter. To release audio focus, call the method abandonAudioFocusRequest() which also takes an AudioFocusRequest as its argument. The same AudioFocusRequest instance should be used when requesting and abandoning focus.

To create an AudioFocusRequest, use an AudioFocusRequest.Builder. Since a focus request must always specify the type of the request, the type is included in the constructor for the builder. Use the builder's methods to set the other fields of the request.

The following example shows how to use an AudioFocusRequest.Builder to build an AudioFocusRequest and request and abandon audio focus:

audioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
playbackAttributes = new AudioAttributes.Builder()
        .setUsage(AudioAttributes.USAGE_GAME)
        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
        .build();
focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
        .setAudioAttributes(playbackAttributes)
        .setAcceptsDelayedFocusGain(true)
        .setOnAudioFocusChangeListener(afChangeListener, handler)
        .build();
mediaPlayer = new MediaPlayer();
final Object focusLock = new Object();

boolean playbackDelayed = false;
boolean playbackNowAuthorized = false;

// ...
int res = audioManager.requestAudioFocus(focusRequest);
synchronized(focusLock) {
    if (res == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
        playbackNowAuthorized = false;
    } else if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
        playbackNowAuthorized = true;
        playbackNow();
    } else if (res == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
       playbackDelayed = true;
       playbackNowAuthorized = false;
    }
}

// ...
@Override
public void onAudioFocusChange(int focusChange) {
    switch (focusChange) {
        case AudioManager.AUDIOFOCUS_GAIN:
            if (playbackDelayed || resumeOnFocusGain) {
                synchronized(focusLock) {
                    playbackDelayed = false;
                    resumeOnFocusGain = false;
                }
                playbackNow();
            }
            break;
        case AudioManager.AUDIOFOCUS_LOSS:
            synchronized(focusLock) {
                resumeOnFocusGain = false;
                playbackDelayed = false;
            }
            pausePlayback();
            break;
        case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
            synchronized(focusLock) {
                resumeOnFocusGain = true;
                playbackDelayed = false;
            }
            pausePlayback();
            break;
        case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
            // ... pausing or ducking depends on your app
            break;
        }
    }
}

Hope this helps! Also you can check Android's official documentation. If this doesn't help, you can check this site and this site for more documentation.

Share:
11,690
TheMohanAhuja
Author by

TheMohanAhuja

Updated on June 11, 2022

Comments

  • TheMohanAhuja
    TheMohanAhuja almost 2 years

    I'm trying to play two different files at the same time.

    I have tried to find players and tried to extend the default player achieving the same but couldn't get success in that. so please help me with it, by letting me know what's the best way to play audio file and video at the same time?

    The reason I'm taking separate files is to save space, because the app will be localized, having multiple audio files for each language instead of having multiple videos saves space. That's important because android doesn't allow the download of app size above 50MB.

    Any help in this would be extremely helpful. And providing me code for this would be a great help.

    Thanks in advance.