Add audio control
In Android apps you should always be able to control audio. When using MediaPlayer, you should implement buttons to call the start), pause) and stop) methods.
It is a best practice to play audio through the correct channel. Android has introduced AudioAttributes as a replacement of the STREAM types defined in AudioManager.
AudioAttributes defines the following content types:
CONTENT_TYPE_MOVIE: used for soundtracks, typically in moviesCONTENT_TYPE_MUSIC: used for musicCONTENT_TYPE_SONIFICATION: used for accompanying sounds, such as beepsCONTENT_TYPE_SPEECH: used for speechCONTENT_TYPE_UNKNOWN: used when the content type is unknown, or other than the available options
AudioAttributes defines the following usages:
USAGE_ALARM: used for alarmsUSAGE_ASSISTANCE_ACCESSIBILITY: used for accessibility, e.g. for screen reader usersUSAGE_ASSISTANCE_NAVIGATION_GUIDANCE: used for navigation directions, e.g. while drivingUSAGE_ASSISTANCE_SONIFICATION: used for user interface soundsUSAGE_ASSISTANT: used for user queries, audio instructions or help utterances.USAGE_GAME: used for audio inside gamesUSAGE_MEDIA: used for audio in media, such as moviesUSAGE_NOTIFICATION: used for notification soundsUSAGE_NOTIFICATION_EVENT: used to attract the user's attention, such as a reminder or low battery warning.USAGE_NOTIFICATION_RINGTONE: used for telephony ringtonesUSAGE_UNKNOWN: used when the usage is unknown, or not definedUSAGE_VOICE_COMMUNICATION: used for voice communication, such as telephony or VoIPUSAGE_VOICE_COMMUNICATION_SIGNALLING: used for in-call signalling, such as with a "busy" beep, orDTMFtones.
AudioManager defines the following legacy channels:
STREAM_ACCESSIBILITY: channel for accessibility, such as assistive technologiesSTREAM_ALARM: channel for alarmsSTREAM_DMTF: channel for dual-tone multi-frequency signaling, such as phone dialing tonesSTREAM_MUSIC: channel for musicSTREAM_NOTIFICATION: channel for notificationsSTREAM_RING: channel for incoming phone callsSTREAM_SYSTEM: channel for system soundsSTREAM_VOICE_CALL: channel for voice calls
kotlin
// Set audio attributes
val player = MediaPlayer()
player.setAudioAttributes(
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.setLegacyStreamType(AudioManager.STREAM_ACCESSIBILITY)
.build()
)
// Provide media controls
button.setOnClickListener {
if (player.isPlaying()) {
player.pause()
} else {
player.start()
}
} In Jetpack Compose apps, you should always be able to control audio. When using MediaPlayer, you should implement buttons to call the start), pause) and stop) methods.
It is a best practice to play audio through the correct channel. Android has introduced AudioAttributes as a replacement of the STREAM types defined in AudioManager.
AudioAttributes defines the following content types:
CONTENT_TYPE_MOVIE: used for soundtracks, typically in moviesCONTENT_TYPE_MUSIC: used for musicCONTENT_TYPE_SONIFICATION: used for accompanying sounds, such as beepsCONTENT_TYPE_SPEECH: used for speechCONTENT_TYPE_UNKNOWN: used when the content type is unknown, or other than the available options
AudioAttributes defines the following usages:
USAGE_ALARM: used for alarmsUSAGE_ASSISTANCE_ACCESSIBILITY: used for accessibility, e.g. for screen reader usersUSAGE_ASSISTANCE_NAVIGATION_GUIDANCE: used for navigation directions, e.g. while drivingUSAGE_ASSISTANCE_SONIFICATION: used for user interface soundsUSAGE_ASSISTANT: used for user queries, audio instructions or help utterances.USAGE_GAME: used for audio inside gamesUSAGE_MEDIA: used for audio in media, such as moviesUSAGE_NOTIFICATION: used for notification soundsUSAGE_NOTIFICATION_EVENT: used to attract the user's attention, such as a reminder or low battery warning.USAGE_NOTIFICATION_RINGTONE: used for telephony ringtonesUSAGE_UNKNOWN: used when the usage is unknown, or not definedUSAGE_VOICE_COMMUNICATION: used for voice communication, such as telephony or VoIPUSAGE_VOICE_COMMUNICATION_SIGNALLING: used for in-call signalling, such as with a "busy" beep, orDTMFtones.
kotlin
// Set audio attributes
val player = remember {
MediaPlayer().apply {
setAudioAttributes(
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.setLegacyStreamType(AudioManager.STREAM_ACCESSIBILITY)
.build()
)
}
}
// Provide media controls
Button(
onClick = {
if (player.isPlaying) {
player.pause()
} else {
player.start()
}
}
) {
// Button content...
} In iOS apps you should always be able to control audio. When using AVPlayer, you should use play and pause methods.
You should also make sure that audio is played through the correct channel. Use AVAudioSession in combination with AVAudioSessionCategory to achieve this.
The following channels are available:
AVAudioSessionCategoryAmbient: use this channel if the sound is not important for the functioning of the appAVAudioSessionCategoryMultiRoute: use this channel if you are sending the sound to multiple output devices at the same timeAVAudioSessionCategoryPlayAndRecord: use this channel for sound recording and playbackAVAudioSessionCategoryPlayback: use this channel to play recorded music and other sounds that are important for the app's functioningAVAudioSessionCategoryRecord: use this channel for sound recording; other sound is mutedAVAudioSessionCategorySoloAmbient: the default channel to play sound
swift
// Set audio channel
try AVAudioSession.sharedInstance().setCategory(
.playback,
mode: .default,
options: []
)
// Provide media controls
@objc private func click(_ sender: UIButton) {
if player.timeControlStatus == .playing {
player.pause()
} else {
player.play()
}
} In SwiftUI apps you should always be able to control audio. When using AVPlayer, you should use play and pause methods.
You should also make sure that audio is played through the correct channel. Use AVAudioSession in combination with AVAudioSessionCategory to achieve this.
The following channels are available:
AVAudioSessionCategoryAmbient: use this channel if the sound is not important for the functioning of the appAVAudioSessionCategoryMultiRoute: use this channel if you are sending the sound to multiple output devices at the same timeAVAudioSessionCategoryPlayAndRecord: use this channel for sound recording and playbackAVAudioSessionCategoryPlayback: use this channel to play recorded music and other sounds that are important for the app's functioningAVAudioSessionCategoryRecord: use this channel for sound recording; other sound is mutedAVAudioSessionCategorySoloAmbient: the default channel to play sound
swift
// Set audio channel
try AVAudioSession.sharedInstance().setCategory(
.playback,
mode: .default,
options: []
)
// Provide media controls
@State private var player = AVPlayer()
@State private var isPlaying = false
var body: some View {
Button(isPlaying ? "Pause" : "Play") {
if player.timeControlStatus == .playing {
player.pause()
isPlaying = false
} else {
player.play()
isPlaying = true
}
}
} In Flutter apps you should always be able to control audio. Two popular options for playing media are video_player and just_audio. Both packages have options for controlling audio through play() and pause() methods.
dart
final player = AudioPlayer();
final duration = await player.setUrl('https://appt.org/audio.mp3');
IconButton(
icon: Icon(Icons.play_arrow),
iconSize: 64.0,
onPressed: await player.play(),
);
IconButton(
icon: Icon(Icons.pause),
iconSize: 64.0,
onPressed: await player.pause(),
); In React Native apps you should always be able to control audio. A popular option for media is the react-native-video package. You can use the audioOnly property to play audio files. The react-native-video package offers native controls for playing and pausing by default.
jsx
<Video
audioOnly
post={require('appt.png')}
source={require('appt.mp3')} /> In MAUI apps you should be able to control audio. There is no built-in audio control, but you can use the MediaElement from the MAUI Community Toolkit, which surfaces the following native components:
C# example
csharp
var mediaElement = new MediaElement
{
ShouldAutoPlay = true,
Source = "TheUrlOrPathForYouAudio.mp3"
}; xml
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
<toolkit:MediaElement
Source="TheUrlOrPathForYouAudio.mp3"
ShouldAutoPlay="True" /> In Xamarin apps you should always be able to control audio. You can use MediaElement to embed media. The ShowsPlaybackControls needs to be set to True to show controls for playing and pausing. The value is False by default.
xml
<MediaElement Source="https://appt.org/video.mp4"
ShowsPlaybackControls="True" />