I saved the audio files in list 'file'. I want to play this audio file using the audioplayers package. I have listed audio files using listview, but I want to play only one selected audio file among multiple audio files. Currently, the entire audio file in the records is played at the same time and an error has occurred.
How can I solve this?
This is part of my code.
class AudioViewer extends StatefulWidget {
@override
_AudioViewerState createState() => _AudioViewerState();
}
class _AudioViewerState extends State<AudioViewer> {
List file = [];
var audioPath;
var directory;
AudioPlayer? audioPlayer;
bool _isplaying = false;
var _icon = Icons.play_arrow;
var _deleteicon = Icons.delete;
Color _color = Colors.deepOrangeAccent;
Duration position = Duration();
Duration duration = Duration(seconds: 1);
int indexindex = 0;
@override
void initState() {
super.initState();
getFiles();
_setupAudioPlayer();
}
void getFiles() async {
directory = (await getExternalStorageDirectory())!.path;
setState(() {
file = Directory("$directory").listSync();
});
print(file.toString());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
title: Text(
"Audio List",
),
),
body: Container(
child: ListView.builder(
reverse: true,
itemCount: widget.records.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Card(
elevation: 5,
child: ExpansionTile(
title: Text(
widget.records[index].path.split('/').last.split(".").first,
style: TextStyle(color: Colors.black),
),
onExpansionChanged: ((newState) {
if (newState) {
indexindex = index;
setState(() {
});
}
}),
children: [
Container(
height: 100,
padding: EdgeInsets.fromLTRB(10,0,10,0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
child: IconButton(
iconSize: 40,
onPressed: () {
if (!_isplaying) {
audioPlayer!.resume();
setState(() {
_isplaying = true;
_icon = Icons.pause;
_color = Colors.blueGrey;
});
} else {
audioPlayer!.release();
setState(() {
position = new Duration();
_isplaying = false;
_icon = Icons.play_arrow;
_color = Colors.deepOrangeAccent;
});
}
},
icon: Icon(_icon),
color: _color,
),
),
Container(
child: IconButton(
iconSize: 30,
onPressed: () {
widget.records[index].delete(recursive: true);
setState(() {
widget.records.removeAt(index);
position = new Duration();
});
},
icon: Icon(_deleteicon),
),
),
]
),
CodePudding user response:
It seems you have your state variables like _isplaying
only once for the whole page/list. You need them per song. This doesn't seem to be a complete example (widget.records
seems to be missing) so I cannot really help a lot here.
What you could do, if widget.records
contains the songs, is to have a currentlyPlaying
variable that is the record that is currently playing, instead of just a generic _isplaying
. This way, you could figure out if the currectly build list entry is actually playing or not. But then maybe I'm misunderstanding something, since your audioplayer is not actually playing that song, it just resumes whatever it was playing before.
Maybe start out with easy steps and first make the icon work. That should be possible with the method I mentioned above: keep track of which record was selected.