raitonoberu / sptlrx

Synchronized lyrics in your terminal
MIT License
396 stars 21 forks source link

Output *only* ONE lyric line to the pipe? #27

Closed XenHat closed 1 year ago

XenHat commented 1 year ago

Hi! I'm trying to use this application in a setup where I would like to only show the current line to terminal then exit. I can't seem to get this working because the application never exits.

I would like to suggest the following improvements:

My current actual use case is the following:

image

I have several other use cases I can think about, that would be solved by making this behaviour work.

Related: #1, #8

raitonoberu commented 1 year ago

Hello!! This idea has certainly crossed my mind, but there are some visible limitations. Although we can cache song lyrics between calls, we still need to make an HTTP request (in the case of using Spotify) to get the current track and position. By default, the app does this every 2 seconds, but doing it more often (500 ms) will potentially lead to a rate limit and/or high resource usage (also it is not instantaneous and will add latency). Moreover, updates even every 500 ms are not enough for real-time lyrics, the delay will be noticeable. By default, the internal timer of the app is updated every 200 ms.

What I suggest you do is use the current pipe implementation to run it in the background. And then use another script on your panel to access this "daemon" to get the current line.

raitonoberu commented 1 year ago

Here's a Python script that will do just that. It uses a named unix pipe to prevent writing to disk.

import os
import subprocess

pipe_path = "/tmp/lyrics"
try:
    os.mkfifo(pipe_path)
except FileExistsError:
    pass

process = subprocess.Popen(["sptlrx",  "pipe"], stdout=subprocess.PIPE)

for line in iter(process.stdout.readline, ""):
    with open(pipe_path, "wb") as pipe:
        pipe.write(line)

Leave it running in the background. Then in your panel you will need to do something like cat /tmp/lyrics as often as possible (don't forget to check the "wait for completion" box).

Original code (writing to disk) ```python import subprocess process = subprocess.Popen(["sptlrx", "pipe"], stdout=subprocess.PIPE) for line in iter(process.stdout.readline, ""): with open("/tmp/lyrics", "wb") as file: file.write(line) ```
XenHat commented 1 year ago

Hi! This is working great!

image

I can make do with this :)

m-GDEV commented 1 year ago

Hey just wanted to say I was trying to the same thing and this was really helpful!

I wanted to display lyrics "lyric-by-lyric" in my polybar bar.

Here is my bash solution:

#!/bin/bash

# Simple script that determines what my polybar music module prints
# If spotify is playing it prints each lyric, if not then it prints
# last sources title

STATUS=$(playerctl -p spotify status)

# Check if programs installed
if ! command -v "playerctl" &> /dev/null && ! command -v "sptlrx" &> /dev/null ; then
    echo "Proper programs not installed!"
    exit
fi

# Check if pipe is running
if [ -z "$(ps aux | grep -v 'grep' | grep 'sptlrx pipe' )" ]; then
    sptlrx pipe >> /tmp/lyrics &
fi

# Script's logic
if [ "$STATUS" == "Paused" ]; then
    echo "$(playerctl metadata title | cut -c -50)"
elif [ "$STATUS" == "Playing" ]; then
    echo "$(tail -1 /tmp/lyrics)"
else
    echo "Issue, check out script"
fi