Skip to content

A command-line music player with time-synced lyrics support.

License

Notifications You must be signed in to change notification settings

br0kenpixel/rustyplay

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

br0kenpixel's Music Player

A terminal based music player with time-synced lyrics support.

Intro

This is a remade version of the original, which was written in C.
⚠️ Playlist features (Next, Previous) are not implemented yet.

Parts

Building

First make sure you have the Rust toolchain installed.
If not, use the following command on *nix based systems:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

To run the player follow these steps:

  1. Clone this repo
    • git clone https://github.com/br0kenpixel/rustyplay
  2. Build the binary
    • cargo build --release
    • ⚠️ It's highly recommended to build in release mode for better performance!

  3. Run the binary like this:
    • musicplayer [FILE]
      • Example:
      • musicplayer call_me.wav
  4. You can also build the documentation:
    • cargo doc --open

Supported audio formats

  • WAV
  • OGG
  • FLAC
    • ⚠️ FLAC support is temporarily disabled due to issues with playback.

    • ✅ FLAC playback has been fixed thanks to this!

    • ✅ FLAC playback has been fixed by using optimizations instead of the fix mentioned above

Supported systems:

As of now, it was only tested on macOS Monterey 12.6.1 (Intel). But theoretically it should work on any other OS, as all dependencies have cross-platform support.

Dependencies

  • rodio
    • An audio playback library
  • sndfile
    • Used to read metadata from audio files
  • ncurses
    • A popular terminal UI library
  • pausable_clock
    • Provides a pausable/resumable clock type
  • serde
    • A data serialization/deserialization framework
  • serde_json
    • Allows serialization/deserialization to/from JSON using serde.

Lyrics

The time-synced lyrics are provided by Spotify/Musixmatch. In order to be able to use this feature, you must obtain a JSON file containing the time-synced lyrics data. Such data can be obtained by using either akashrchandran/spotify-lyrics-api or br0kenpixel/spotify-lyrics-api-rust. "End times" are also supported under certain conditions.

Setting up

First, you need to use one of the tools listed above to obtain the lyrics data from Spotify. You'll need to save this data into a .json file. This file must be located in the same directory as the audio file it "belongs" to!
For example, if you run musicplayer Documents/Music/hello.wav then Documents/Music/hello.json must be a valid path and this file must contain the lyrics data obtained from Spotify. If this .json file does not exist, lyrics functionality will be disabled, however playback will work. If the .json file contains invalid data, the program will panic!().

"End time" support

So far I haven't noticed any lyrics data with endTimeMs set, however if the lyrics contain a line with a singe character (or is empty), the lyrics parser will automatically "adjust" the lyrics data. This line will be ignored and it's startTimeMs is changed to the previous line's endTimeMs.

Documentation

You can use cargo doc to generate the documentation.
The "homepage" of the documentation is target/doc/musicplayer/index.html.

FAQ/Troubleshooting

Why are MP3s and M4As not supported if rodio supports them?

Even though rodio can play these files, the problem is sndfile, which does not support those formats.

Could the player automatically obtain lyrics? Yes, it could, however it would need to know the Spotify track ID of the song.
I hear "crackling" when playing FLAC files.

This issue should now be fixed, however, if you're still experiencing it, check if you're using a debug build. If yes, such behavior can be expected. Please use release builds instead.

Why is it taking so long to open the player? ("Launching..." takes long)

The player is designed to initialize rodio, load the audio file and lyrics first, before creating and drawing the UI. I personally like having a longer startup time, rather than a "laggy-looking" UI.

Also, debug builds have significantly higher loading times!