audio_session 0.0.1 audio_session: ^0.0.1 copied to clipboard
Sets the iOS audio session category and Android audio attributes for your app, and manages your app's audio focus, mixing and ducking behaviour.
import 'dart:math';
import 'package:audio_session/audio_session.dart';
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart' as ja;
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _player = ja.AudioPlayer();
@override
void initState() {
super.initState();
AudioSession.instance.then((audioSession) async {
// This line configures the app's audio session, indicating to the OS the
// type of audio we intend to play. Using the "speech" recipe rather than
// "music" since we are playing a podcast.
await audioSession.configure(AudioSessionConfiguration.speech());
// Listen to audio interruptions and pause or duck as appropriate.
_handleInterruptions(audioSession);
// Use another plugin to load audio to play.
await _player.setUrl(
"https://s3.amazonaws.com/scifri-episodes/scifri20181123-episode.mp3");
});
}
@override
void dispose() {
AudioSession.instance.then((audioSession) {
audioSession.close();
});
super.dispose();
}
void _handleInterruptions(AudioSession audioSession) {
bool playInterrupted = false;
audioSession.becomingNoisyEventStream.listen((_) {
_player.pause();
});
_player.playingStream.listen((playing) {
playInterrupted = false;
// Temporary as the just_audio 0.3.4 doesn't activate the audio session.
if (playing) {
audioSession.setActive(true);
}
});
audioSession.interruptionEventStream.listen((event) {
if (event.begin) {
switch (event.type) {
case AudioInterruptionType.duck:
if (audioSession.androidAudioAttributes.usage ==
AndroidAudioUsage.game) {
_player.setVolume(_player.volume / 2);
}
playInterrupted = false;
break;
case AudioInterruptionType.pause:
case AudioInterruptionType.unknown:
if (_player.playing) {
_player.pause();
// Although pause is async and sets playInterrupted = false,
// this is done in the sync portion.
playInterrupted = true;
}
break;
}
} else {
switch (event.type) {
case AudioInterruptionType.duck:
_player.setVolume(min(1.0, _player.volume * 2));
playInterrupted = false;
break;
case AudioInterruptionType.pause:
if (playInterrupted) _player.play();
playInterrupted = false;
break;
case AudioInterruptionType.unknown:
playInterrupted = false;
break;
}
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('audio_session example'),
),
body: Center(
child: StreamBuilder<ja.PlayerState>(
stream: _player.playerStateStream,
builder: (context, snapshot) {
final playerState = snapshot.data;
if (playerState?.processingState != ja.ProcessingState.ready) {
return Container(
margin: EdgeInsets.all(8.0),
width: 64.0,
height: 64.0,
child: CircularProgressIndicator(),
);
} else if (playerState?.playing == true) {
return IconButton(
icon: Icon(Icons.pause),
iconSize: 64.0,
onPressed: _player.pause,
);
} else {
return IconButton(
icon: Icon(Icons.play_arrow),
iconSize: 64.0,
onPressed: _player.play,
);
}
},
),
),
),
);
}
}