How to play multiple audio files simultaniously in flutter - flutter

I have been trying to run the multiple audio files at the same time each having a separate mute button. I have tried AudioPlayer Flutter plugin.
I have tried the following code but it makes the files run one by one, not simultaniously.
Please help!!
Future play() async {
await audioPlayer.play(url);
await audioPlayer2.play(url2);
setState(() {
playerState = AudioPlayerState.PLAYING;
});
}

May be their are more appropriate solutions but this solved my problem at the moment, I have used the plugin audioplayers and created multiple instances for each audio file.
Updated: For example for two audio files it's done like below:
enum PlayerState { stopped, playing, paused }
enum PlayerState1 { stopped1, playing1, paused1 }
class AudioScreen extends StatefulWidget {
#override
_AudioScreenState createState() =>_AudioScreenState();
}
class _AudioScreenState extends State<AudioScreen> {
//for first audio
AudioPlayer audioPlayer;
PlayerState playerState = PlayerState.stopped;
get isPlaying => playerState == PlayerState.playing;
//for second audio
AudioPlayer audioPlayer1;
PlayerState1 playerState1 = PlayerState1.stopped1;
get isPlaying1 => playerState1 == PlayerState1.playing1;
#override
void initState() {
super.initState();
audioPlayer = new AudioPlayer();
audioPlayer1 = new AudioPlayer();
}
Future play() async {
await audioPlayer.play(url);
setState(() {
playerState = PlayerState.playing;
});
await audioPlayer1.play(url1);
setState(() {
playerState1 = PlayerState1.playing1;
});
}
Future stop() async {
await audioPlayer.stop();
setState(() {
playerState = PlayerState.stopped;
});
await audioPlayer1.stop();
setState(() {
playerState1 = PlayerState1.stopped1;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body:Column(
children:[
IconButton(
onPressed:() play(),
iconSize: 70.0,
icon:Icon(Icons.play_circle_outline, size: 55),
),
IconButton(
onPressed: stop(),
iconSize: 55.0,
icon: Icon(Icons.stop),
),
]
),
);
}
}
This way you can multiple instances or just use a loop to create multiple instances for each audio.

Related

Flutter text to speech (flutter_tts) does not work

I am trying to build this simple text to speech feature using flutter_tts package but it doesn't speak no matter what I tried (official example, tutorials, etc.)
I checked my Audio Output, it's set correctly. I have other MP3 sounds, they play just fine.
I tried ^3.5.0 and ^3.5.3 versions, neither worked.
Here is my code:
class ColorsScreen extends StatefulWidget {
const ColorsScreen({super.key, required this.title});
final String title;
#override
State<ColorsScreen> createState() => _ColorsScreenState();
}
class _ColorsScreenState extends State<ColorsScreen> {
late FlutterTts flutterTts;
bool isPlaying = false;
String _currentColor = "black";
String get currentColorName =>_currentColor;
#override
void initState() {
super.initState();
initTts();
flutterTts.setStartHandler(() {
setState(() {
isPlaying = true;
});
});
flutterTts.setCompletionHandler(() {
setState(() {
isPlaying = false;
});
});
}
initTts() async {
flutterTts = FlutterTts();
}
Future _readColorName() async {
await flutterTts.setVolume(1);
await flutterTts.setSpeechRate(1);
await flutterTts.setPitch(1);
var result = await flutterTts.speak(currentColorName);
if (result == 1) {
setState(() {
isPlaying = true;
});
}
}
#override
void dispose() {
super.dispose();
flutterTts.stop();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: TopBar(widget.title),
body: IconButton(
padding: const EdgeInsets.all(0),
icon: const Icon(
Icons.play_circle_fill_rounded,
color: Colors.red,
size: 50,
semanticLabel: 'Play color name',
),
onPressed: _readColorName,
),
);
}
}
Try in different real android devices such as: Android 11 or Android 12
I had recently upgraded my simulator to iOS 16.0 and now realizing that's the problem. Switched to a iOS 15.5 simulator and it worked fine. When on iOS 16.0, XCode console was showing this error: "unable to list voice folder" Leaving it here in case someone else faces a similar problem. I will continue building in iOS 15.5 version for now and keep checking if the libraries get any updates.

How to properly change video player quality source at runtime after ending loaded buffer?

i'm building video app base on video_player . i'd to change video quality like YouTube without any loading and screen blinking (after finish loaded buffer new selected quality source will play )
i create sample code but when i change video controller data source loading is show on screen affter that screen blinking and after all new data source video play (that is not smooth like youTube)
this is my vide player code
VideoPlayerController? _videoPlayerController;
#override
void initState() {
super.initState();
_videoPlayerController = VideoPlayerController.network('video url')
..initialize().then((_) {
_videoPlayerController!.play();
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return _videoPlayerController == null
? const Center(
child: LoadingWidget(),
)
: _videoPlayerController!.value.isInitialized
? Stack(
children: [
VideoPlayer(_videoPlayerController!),
Button(text: 'chnage video quality to 720p', onClick: (){
_startPlay('vide 720p url ');
})
],
)
: Center(child: LoadingWidget());
}
#override
void dispose() {
_videoPlayerController!.dispose();
super.dispose();
}
for change quality data source i use this code
Future<bool> _clearPrevious() async {
await _videoPlayerController?.pause();
return true;
}
//The values that are passed when changing quality
late Duration newCurrentPosition;
int _playBackTime = 0;
Future<void> _initializePlay(String videoPath) async {
_videoPlayerController = VideoPlayerController.network(videoPath);
_videoPlayerController!.addListener(() {
setState(() {
_playBackTime = _videoPlayerController!.value.position.inSeconds;
});
});
_videoPlayerController!.initialize().then((_) {
_videoPlayerController!.seekTo(newCurrentPosition);
_videoPlayerController!.play();
});
}
void _getValuesAndPlay(String videoPath) {
newCurrentPosition = _videoPlayerController!.value.position;
_startPlay(videoPath);
print(newCurrentPosition.toString());
}
Future<void> _startPlay(String videoPath) async {
Future.delayed(const Duration(milliseconds: 200), () {
_clearPrevious().then((_) {
_initializePlay(videoPath);
});
});
}

How to open audio file from file manager and play that audio file using Flutter app

I'm new in flutter development and I got stuck in a program where I want to play an audio file by selecting it from file manager.i am able to open audio file from file manager but I don't know how to play that audio file.
Please help me out with this.
I am using this code -
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class FilePickerDemo extends StatefulWidget {
#override
_FilePickerDemoState createState() => _FilePickerDemoState();
}
I am using this for file picking and save file I want to know how to play save file
class _FilePickerDemoState extends State<FilePickerDemo> {
void _pickFiles() async {
_resetState();
try {
_directoryPath = null;
_paths = (await FilePicker.platform.pickFiles(
type: _pickingType,
allowMultiple: _multiPick,
onFileLoading: (FilePickerStatus status) => print(status),
allowedExtensions: ['mp3'],
))
?.files;
} on PlatformException catch (e) {
_logException('Unsupported operation' + e.toString());
} catch (e) {
_logException(e.toString());
}
if (!mounted) return;
setState(() {
_isLoading = false;
_fileName =
_paths != null ? _paths!.map((e) => e.name).toString() : '...';
_userAborted = _paths == null;
});
}
You can use https://pub.dev/packages/just_audio package to play audio.
import 'package:just_audio/just_audio.dart';
final _player = AudioPlayer();
playAudio() async {
try {
await _player.setFilePath(widget.audioPath);
} catch (e) {
log("Error loading audio source: $e");
}
_player.play();
}
Another handy package is AudioPlayers that can also cache local audio files.
Here is a very basic example, that has buttons to play, pause and stop a reference to local audio that is passed into a stateful widget, to get you started (based mainly off this Medium article) Medium Article
Reminder to save your audio in your local files like below
and add a reference in your yaml file and get dependencies
assets:
- assets/audio/
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
class AudioManagerExample extends StatefulWidget {
const AudioManagerExample({required this.audioName, Key? key}) : super(key: key);
final String audioName;
#override
_AudioManagerExampleState createState() => _AudioManagerExampleState();
}
class _AudioManagerExampleState extends State<AudioManagerExample> {
AudioPlayer audioPlayer = AudioPlayer();
late AudioCache audioCache;
#override
void initState() {
audioCache = AudioCache(fixedPlayer: audioPlayer);
audioCache.load('audio/${widget.audioName}.mp3');
super.initState();
}
#override
void dispose() {
audioCache.clearAll();
audioPlayer.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
setState(() {
audioCache.play('audio/${widget.audioName}.mp3');
});
},
child: Text('Play ${widget.audioName}'),
),
ElevatedButton(
onPressed: () {
setState(() {
audioPlayer.pause();
});
},
child: Text('Pause ${widget.audioName}'),
),
ElevatedButton(
onPressed: () {
setState(() {
audioPlayer.stop();
});
},
child: Text('Stop ${widget.audioName}'),
),
],
);
}
}

How to loop the audio to keep playing until 3 times-Flutter

I am currently using audioplayers: ^0.20.1 to play and resume the video, right now I would like to loop the audio 3 times (keep looping to play the audio). As I know audioplayers package has loop property but I still don't know how to custom the loop property
Here is how you can loop the audio player:
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: AudioPlayerLoopTesting()));
}
class AudioPlayerLoopTesting extends StatefulWidget {
#override
_AudioPlayerLoopTestingState createState() => _AudioPlayerLoopTestingState();
}
class _AudioPlayerLoopTestingState extends State<AudioPlayerLoopTesting> {
AudioCache audioCache = AudioCache();
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
void _playLoopAudio() {
int timesPlayed = 0;
const timestoPlay = 3;
//audio.mp3 is the local asset file
audioCache.play('audio.mp3').then((player) {
player.onPlayerCompletion.listen((event) {
timesPlayed++;
if (timesPlayed >= timestoPlay) {
timesPlayed = 0;
player.stop();
} else {
player.resume();
}
});
});
}
Widget localAsset() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Loop Local Asset'),
ElevatedButton(
child: const Text('Loop the audio'),
onPressed: _playLoopAudio,
),
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: localAsset(),
),
);
}
}
Thumbs up if problem resolved
to loop the audio try this :-
static AudioCache musicCache;
static AudioPlayer instance;
void playLoopedMusic() async {
musicCache = AudioCache(prefix: "audio/");
instance = await musicCache.loop("bgmusic.mp3");
// await instance.setVolume(0.5); you can even set the volume
}
void pauseMusic() {
if (instance != null) {
instance.pause(); }}
to loop it 3 time only :-
int numberOftimesToPlay=0;
playThreeTimes(){
_audioPlayer = AudioPlayer();
int res = await _audioPlayer.play("https://192.168.1.66/$sUrl");
//await _audioPlayer.play("http://192.168.1.5/00001.mp3");
if (res == 1 & numberOftimesToPlay>4) {
numberOftimesToPlay ++;
playThreeTimes()
print("ok");
} else {
print("done");
}}

getting code to run upon widget creation flutter

I have a flutter camera app and am able to get a recorded video to play. The problem is, I am only able to get it to play when a button is pressed. How do I get the code to run when the widget(screen) is created instead of when the button is pressed so I don't have to press a button to get it to play? Here is my code:
Here is the code for when the button is pressed:
//raised button
RaisedButton(
onPressed: () {stopButtonPressed();},
//stopButtonPressed
void stopButtonPressed() {
print('stopButtonPressed hit');
stopVideoRecording().then((_) {
print('StopVideoRecording complete');
});
}
//stopVideoRecording
Future<void> stopVideoRecording() async {
print('stopVideoRecording hit');
await _startVideoPlayer();
}
//_startVideoPlayer
Future<void> _startVideoPlayer() async {
print('_startVideoPlayer hit');
print(Provider.of<SendDataModel>(context, listen: false).displayImageVideo());
final VideoPlayerController vcontroller =
VideoPlayerController.file(File(Provider.of<SendDataModel>(context, listen: false).displayImageVideo()));
videoPlayerListener = () {
if (videoController != null && videoController.value.size != null) {
if (mounted) setState(() {});
videoController.removeListener(videoPlayerListener);
}
};
vcontroller.addListener(videoPlayerListener);
await vcontroller.setLooping(true);
await vcontroller.initialize();
await videoController?.dispose();
if (mounted) {
setState(() {
//saveImagePath = null;
videoController = vcontroller;
});
}
await vcontroller.play();
} //startVideoPlayer
Thanks!
You can call the function from initState(). initState() is called only once when the StatefulWidget is inserted into the Widget tree, so it's a good place to initialize variables or do what you're trying to do.
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
super.initState();
// Do anything you need done here
_startVideoPlayer();
// If you want a slight delay, use Future.delayed
Future.delayed(Duration(seconds: 1), (){
_startVideoPlayer();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
// rest of app