I am using rust with the rodio crate to make a basic command line mp3 player. Everything works fine, except I have no way to display the currently playing song.
I made a Song struct with a title, artist, path, and source. I then made a vector queue of Song structs to keep track of the song that I am playing and songs that will play next. I appended the sources of the songs to a sink, and made a variable queueindex that keeps track of the index of the currently playing song in the queue. The problem? I have no way to tell when a song finishes playing, and thus cannot increment the queueindex variable. sink.empty() doesn't help because it only returns true when the sink is completely empty. Is there any way to tell when a source finishes playing and another one starts?
Edit: Should I add the full source code to the question?
(Yes, providing more of your source would be helpful.)
I don't have
rodioset up locally, but the docs say that the actual samples of aSourceare obtained by simply iterating over it, i.e. aSourcemust also be anIterator<Item = Sample>. So, to execute some code when the iterator finishes (to increment the queue index), we will create astruct SourceWithFn.The
structmust be anIterator, to pass data through from the original source, and to detect when the source finishes.Note that the
unwrapwill panic if the iterator is invoked after it has finished. You can change the implementation toFnMut(and remove theOption) if this is needed.The
structmust also be aSource:And finally, a convenience constructor:
Now, you can wrap an existing source like so:
However, note that
queue_indexis captured mutably by the above! To make this work with multiple sources androdioin general, you might want to put thequeue_indexin aCellor similar.