lowfi

repository·main·Indexed 21 days ago

https://github.com/talwat/lowfi

A minimal Rust application for playing lofi music without ads or video. It features a resilient buffering system for inconsistent networks, support for custom track lists (web-based or local), and bookmarking functionality. The player includes a terminal UI with customizable flags, MPRIS support for Linux, and optional audio format extensions for FLAC, Vorbis, and WAV.

Tokens
8.5K
Snippets
39
Records
50
Agent score
73%

What's inside lowfi

  1. Understand the default music sourcing in lowfi

    main

    By default, lowfi comes with an extensive tracklist embedded into the software to provide a "plug and play" experience.

    Currently, the default music source is the chillhop list. While this provides a functional experience similar to the chillhop radio player, users should be aware that it emulates the behavior of their web player in a terminal environment.

    If you prefer the original Lofi Girl tracks, the project maintains an archive.txt list (derived from a local archive and hosted on archive.org) which contains approximately 2700 tracks, though the organization may be less optimal than the default.

  2. Enable optional lowfi features

    main

    Lowfi uses Rust features to include optional functionality. These must be enabled during compilation (e.g., via cargo install or cargo build).

    • scrape: Provides the scrape command for transparency.
    • mpris: Enables MPRIS support (Linux only).
    • extra-audio-formats: Allows playing formats other than MP3 (specifically FLAC, Vorbis, and WAV) when using custom track lists.
  3. Install lowfi via Cargo

    main

    To install lowfi using Cargo, ensure you have Rust 1.83.0+ installed.

    Linux Dependencies: You must install openssl and alsa headers. Depending on your distribution:

    • Arch: alsa-lib, openssl
    • Ubuntu: libasound2-dev, libssl-dev
    • Fedora: alsa-lib-devel, openssl-devel

    If using PulseAudio, also install pulseaudio-alsa.

    Ensure $HOME/.cargo/bin is in your $PATH after installation.

    # Standard installation
    cargo install lowfi
    
    # Installation with MPRIS support (Linux only)
    cargo install lowfi --features mpris
  4. Use lowfi playback controls

    main

    Once running, use the following keyboard shortcuts to control playback:

    KeyFunction
    s, n, lSkip Song
    p, SpacePlay/Pause
    +, =, k, Volume Up 10%
    Volume Up 1%
    -, _, j, Volume Down 10%
    Volume Down 1%
    q, CTRL+CQuit
    bBookmark

    Note: lowfi also supports Media Keys and MPRIS (if the mpris feature was enabled during compilation).

  5. Disable the default music tracklist for distributions

    main

    If you are packaging lowfi for a Linux distribution and wish to avoid shipping the default embedded music (due to sourcing/legal concerns), you can use the default-tracklist feature. When this feature is used, the default tracklist will not be compiled into the binary or shipped at all.

    Note: This is an optional feature available as of April 2026.

  6. Create and use custom track lists

    main

    You can provide your own list of tracks using the --track-list flag. The flag accepts a path to a file or a filename (without .txt) located in the application's data directory.

    Data Directories:

    • Linux: ~/.local/share/lowfi
    • macOS: ~/Library/Application Support/lowfi
    • Windows: %appdata%\Roaming\lowfi

    Track List Format: The first line is the header (base URL). Subsequent lines are the track paths. Lowfi concatenates the header and the track path.

    • Trailing Slashes: Most headers should end with a / because lowfi does not automatically insert one.
    • Full URLs: If a track line starts with a protocol (e.g., https://), the header is ignored for that track.
    • Custom Display Names: Use ! to separate the file path from a custom display name (e.g., path/to/file.mp3!My Song).
    • Local Files: Use the file:// prefix for both the header and tracks to play local files.
    # Example: Web-based list
    https://lofigirl.com/wp-content/uploads/
    2023/06/Foudroie-Finding-The-Edge-V2.mp3
    2023/04/2-In-Front-Of-Me.mp3!Custom Name
    https://file-examples.com/storage/fe85f7a43b689349d9c8f18/2017/11/file_example_MP3_1MG.mp3
    
    # Example: Local file list
    file:///home/user/Music/
    file.mp3
    file:///home/user/Other Music/second-file.mp3
  7. Install lowfi via system package managers

    main

    You can install lowfi using various package managers depending on your operating system:

    • Arch Linux (AUR): Use yay.
    • openSUSE: Use zypper.
    • Debian/Ubuntu: Uses an unofficial repository maintained by Dario Griffo.
    • Fedora: Uses an unofficial COPR repository by FurqanHun.
    # AUR
    yay -S lowfi
    
    # openSUSE
    zypper install lowfi
    
    # Debian and Ubuntu
    sudo install -d -m 0755 /etc/apt/keyrings
    curl -fsSL https://deb.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/deb.griffo.io.gpg
    echo "deb [signed-by=/etc/apt/keyrings/deb.griffo.io.gpg] https://deb.griffo.io/apt $(lsb_release -sc 2>/dev/null) main" | sudo tee /etc/apt/sources.list.d/deb.griffo.io.list
    sudo apt update
    sudo apt install -y lowfi
    
    # Fedora (COPR)
    sudo dnf copr enable furqanhun/lowfi
    sudo dnf install lowfi
  8. How the downloader and handle work together

    main

    The downloader operates as a background task that continuously picks random tracks from a tracks::List, downloads them, and pushes them into an internal asynchronous queue (mpsc::Sender).

    Consumers interact with this via a Handle, which holds the receiving end of that queue. When a consumer calls handle.track():

    1. If a track is in the queue, it is returned as Output::Queued.
    2. If the queue is empty, the downloader is signaled that it is currently LOADING, and the consumer receives Output::Loading along with a Progress handle to monitor the active download.
  9. The Track List format

    main

    A track list in lowfi is a text-based format where lines are separated by newlines.

    • Header/Base URL: The first line (lines[0]) is treated as the base URL or header. All subsequent tracks are appended to this header unless the track line contains a protocol (e.g., ://).
    • Custom Display Names: You can specify a custom display name for a track by using an exclamation mark (!) as a separator. The part before the ! is the path/URL, and the part after is the display name.
    • Special Prefix: If a text block starts with the literal string noheader, it is stripped, treating the rest of the content as the track list without a base URL.
    • Local Files: Tracks can use the file:// protocol. If the path uses ~, it is expanded to the user's home directory.
  10. Understand the track lifecycle: Queued vs Decoded

    main

    In lowfi, tracks progress through different stages of readiness. Understanding these stages is key to managing memory and playback:

    1. Queued: Represents a track waiting in the queue. It contains the raw Bytes and the download path. This is memory-efficient because the audio data is not yet decoded.
    2. Decoded: Represents a track ready for playback. It is generated from a Queued track via the .decode() method. It contains DecodedData (compatible with rodio) and an Info struct containing metadata like duration.

    Transitioning from Queued to Decoded is a lazy operation performed only when it is time to play the track.