I have been trying to dynamically populate AudioSource.uri() with data from firestore.
I uploaded some songs into firestore database and I wanted to use the data for a just_audio playlist in my app. I have done everything possible, and I really am not sure why its not working.
I don't want to add the song urls and other data statically as shown in the plugin example.
Here are my attempts:
First I fetched the song data using a StreamBuilder and passed it as a DocumentSnapshot List to the JustAudioPlaylist() page;
List<DocumentSnapshot> _list;
_list = snapshot.data.docs;
Flexible(
child: ListView.builder(
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => JustAudioPlaylist(
songs: [_list[index]],
),
));
},
child:
Container(child: Center(child: Text('My Playlists'))),
);
}),
)
Then, here's the JustAudioPlaylist page where I expected to retrieve and populate the AudioSource.uri().
class JustAudioPlaylist extends StatefulWidget {
final List songs;
JustAudioPlaylist({this.songs});
@override
_JustAudioPlaylistState createState() => _JustAudioPlaylistState();
}
class _JustAudioPlaylistState extends State<JustAudioPlaylist> {
AudioPlayer _player;
int _addedCount = 0;
var _playlist;
@override
void initState() {
_playlist
.addAll(widget.songs.map((song) => ConcatenatingAudioSource(children: [
AudioSource.uri(
Uri.parse(song['song']),
tag: AudioMetadata(
album: "Science Friday",
title: song['songTitle'],
artwork: song['songImage'],
),
),
])));
I am not sure why its not working, but it produces an error "addAll was called on null". Please can anyone help?
Your relevant code is:
_playlist.addAll(...);
The error means _playlist
is null
. That is, _playlist
is an uninitialised variable and doesn't actually contain any playlist object. I can see you declare the variable so it starts off empty:
var _playlist;
But you never actually store anything into this variable, like _playlist = ...something...
. So your _playlist
variable starts off null
and continues to remain null
.
You could do this instead:
_playlist = ConcatenatingAudioSource(children: []);
// and then later...
_playlist.addAll(widget.songs.map(...etc...));
Although addAll
is intended for dynamically modifying the playlist after it's already created. But in your case, you know which songs you want to play at initialisation time, so you may as well just initialise the playlist right at the beginning and you won't have to add to it later:
_playlist = ConcatenatingAudioSource(
children: widget.songs.map(...etc...)
);