Intro
I love to listen to music when I work, here are some projects I'm a big fan of : mpd and mopidy.
So I had the idea to create a Music Player daemon in Rust, it could be interesting because it will be easier to install and we will have only one executable without dependencies.
Architecture
I started by writing a very simple playback engine, which takes an audio file and decodes it.
        let mut hint = Hint::new();
        let path = Path::new(song);
        // Provide the file extension as a hint.
        if let Some(extension) = path.extension() {
            if let Some(extension_str) = extension.to_str() {
                hint.with_extension(extension_str);
            }
        }
        let source = Box::new(File::open(path).unwrap());
        // Create the media source stream using the boxed media source from above.
        let mss = MediaSourceStream::new(source, Default::default());
        let symphonia_decoder = |mss: MediaSourceStream, hint| {
            SymphoniaDecoder::new(mss, hint).map(|mut decoder| {
                Box::new(decoder) as Decoder
            })
        };
        let decoder_type = symphonia_decoder(mss, hint);
        let mut decoder = match decoder_type {
            Ok(decoder) => decoder,
            Err(e) => {
                error!("Failed to create decoder: {}", e);
                return;
            }
        };
        let mut sink = backend(None, audio_format);
        sink.start();
        loop {
            match decoder.next_packet() {
                Ok(result) => {
                    if let Some((ref _packet_position, packet, channels, sample_rate)) = result {
                        match packet.samples() {
                            Ok(_) => {
                                let mut converter =
                                    Converter::new(Some(mk_ditherer::<TriangularDitherer>));
                                sink.write(packet, channels, sample_rate, &mut converter);
                            }
                            Err(e) => {
                                error!("Failed to decode packet: {}", e);
                            }
                        }
                    }
                }
                Err(e) => {
                    error!("Failed to decode packet: {}", e);
                }
            };
        }
Then I added a gRPC API to control the player remotely and an audio file scanner that extracts the metadata and the path and organizes them in a small SQLite database.
How it works?
The final application is a single executable without dependencies but which is both a server (Music Player Daemon + gRPC API + GraphQL API) and a client (CLI).
If you run it for the first time it will start the server API and if you open another terminal and start another one, it will behave like a client.
Project Setup
# Install dependencies
brew install protobuf # macOS
sudo apt-get install -y libasound2-dev protobuf-compiler # Ubuntu/Debian
choco install protoc # Windows using Chocolatey Package Manager
# Compile
git clone https://github.com/tsirysndr/music-player.git
cd music-player/webui/musicplayer
nvm install # install node version specified in .nvmrc (optional on windows)
npm install -g yarn
yarn install && yarn build # build webui
cd ../..
cargo install --path .
Usage
USAGE:
    music-player [SUBCOMMAND]
OPTIONS:
    -h, --help       Print help information
    -V, --version    Print version information
SUBCOMMANDS:
    albums      List all albums
    artists     List all artists
    help        Print this message or the help of the given subcommand(s)
    next        Play the next song
    pause       Pause the current song
    open        Open audio file
    playlist    Manage playlists
    prev        Play the previous song
    queue       Manage the queue
    play        Resume the current song
    scan        Scan music library: $HOME/Music
    search      Search for a song, album, artist or playlist
    stop        Stop the current song
    tracks      List all tracks
If you are interested in the project, I invite you to visit the github repo https://github.com/tsirysndr/music-player/ , there are still a lot of features that I haven't done yet
 
 
              


 
    
Top comments (2)
Nice one ❤️
Looks great!