Skip to content

Is there able to make cava RAW out in the sketchybar? I try with sbar.exec but this is unale to update per second. #703

@xbunax

Description

@xbunax

this is my lua config

local icons = require("icons")
local colors = require("colors")

local whitelist = { ["Spotify"] = true, ["Music"] = true, ["Cider"] = true, ["Arc"] = true, ["spotify_player"] = true }

local M = {}

sbar.add("item", {
	width = 5,
})

M.cava = sbar.add("item", "cava", {
	position = "left",
	icon = {
		drawing = false,
	},
	update_freq = 1,
	y_offset = -5,
})

M.cava:subscribe({ "media_change" }, function(env)
	print(env.INFO.app)
	if whitelist[env.INFO.app] then
		local drawing = (env.INFO.state == "playing")
		sbar.exec("python3 ~/.local/bin/cava_single.py", function(cava_output)
			local label = cava_output
			M.cava:set({
				label = {
					string = label,
					-- width = 50,
				},
				drawing = drawing,
			})
		end)
	end
end)
return M

this is the cava output

#!/usr/bin/python3
import os
import struct
import subprocess
import tempfile

BARS_NUMBER = 15
OUTPUT_BIT_FORMAT = "16bit"
RAW_TARGET = "/dev/stdout"

conpat = """
[general]
bars = %d
[output]
method = raw
raw_target = %s
bit_format = %s
"""

config = conpat % (BARS_NUMBER, RAW_TARGET, OUTPUT_BIT_FORMAT)
bytetype, bytesize, bytenorm = (
    ("H", 2, 65535) if OUTPUT_BIT_FORMAT == "16bit" else ("B", 1, 255)
)


GLYPHS = ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"]


def run():
    with tempfile.NamedTemporaryFile() as config_file:
        config_file.write(config.encode())
        config_file.flush()

        process = subprocess.Popen(
            ["cava", "-p", config_file.name], stdout=subprocess.PIPE
        )
        chunk = bytesize * BARS_NUMBER
        fmt = bytetype * BARS_NUMBER

        if RAW_TARGET != "/dev/stdout":
            if not os.path.exists(RAW_TARGET):
                os.mkfifo(RAW_TARGET)
            source = open(RAW_TARGET, "rb")
        else:
            source = process.stdout

        try:
            while True:
                data = source.read(chunk)
                if len(data) < chunk:
                    break
                sample = [i / bytenorm for i in struct.unpack(fmt, data)]

                max_glyph_index = len(GLYPHS) - 1
                bar = "".join(
                    [
                        GLYPHS[min(max(int(v * max_glyph_index), 0), max_glyph_index)]
                        for v in sample
                    ]
                )

                print("\r" + bar, end="", flush=True)
        finally:
            process.kill()
            if RAW_TARGET != "/dev/stdout":
                source.close()


if __name__ == "__main__":
    run()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions