Old playerctl cli backend added as option (#49)
* Old playerctl cli backend added as option * Move files into directory and only require playerctl lib on enable * Added wrapper functions to select backend based on args * Switched 'player_stopped' signal to 'no_players' in CLI backend * Added support for setting interval directly in enable() for CLI backend * Update docs for both backends
This commit is contained in:
parent
397edcec6b
commit
fb8bf62fae
|
@ -99,7 +99,17 @@ end)
|
|||
```
|
||||
|
||||
### Theme Variables and Configuration
|
||||
By default, this module will output signals from the most recently active player. If you wish to customize the behavior furthur, the following configuration options are available.
|
||||
By default, this module will output signals from the most recently active player. If you wish to customize the behavior furthur, the following configuration options are available depending on the selected backend. Here is a summary of the two backends and which configuration options they support.
|
||||
|
||||
| Option | playerctl_cli | playerctl_lib |
|
||||
| ------------------- | ------------------ | ------------------ |
|
||||
| backend | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| ignore | | :heavy_check_mark: |
|
||||
| player | | :heavy_check_mark: |
|
||||
| update_on_activity | | :heavy_check_mark: |
|
||||
| interval | :heavy_check_mark: | :heavy_check_mark: |
|
||||
|
||||
- `backend`: This is a string containing the name of the backend that will be used to produce the playerctl signals, either `playerctl_cli` or `playertl_lib`. `playerctl_cli` is used by default because it is supported on most if not all systems. That said, if the playerctl package for your distribution supports the `playerctl_lib` backend, it is recommended, because it supports all the configuration options as seen in the table above and uses less system resources. If you are not sure if your package supports the `playerctl_lib` backend you can simply try it and will receive an error message from Awesome upon calling `bling.signal.playerctl.enable()` if it is not supported. See the examples below for how to set configuration options.
|
||||
|
||||
- `ignore`: This option is either a string with a single name or a table of strings containing names of players that will be ignored by this module. It is empty by default.
|
||||
|
||||
|
@ -111,6 +121,7 @@ By default, this module will output signals from the most recently active player
|
|||
|
||||
These options can be set through a call to `bling.signal.playerctl.enable()` or these theme variables:
|
||||
```lua
|
||||
theme.playerctl_backend = "playerctl_cli"
|
||||
theme.playerctl_ignore = {}
|
||||
theme.playerctl_player = {}
|
||||
theme.playerctl_update_on_activity = true
|
||||
|
@ -121,18 +132,25 @@ theme.playerctl_position_update_interval = 1
|
|||
```lua
|
||||
-- Prioritize ncspot over all other players and ignore firefox players (e.g. YouTube and Twitch tabs) completely
|
||||
bling.signal.playerctl.enable {
|
||||
backend = "playerctl_lib",
|
||||
ignore = "firefox",
|
||||
player = {"ncspot", "%any"}
|
||||
}
|
||||
|
||||
-- OR in your theme file:
|
||||
-- Same config as above but with theme variables
|
||||
theme.playerctl_backend = "playerctl_lib"
|
||||
theme.playerctl_ignore = "firefox"
|
||||
theme.playerctl_player = {"ncspot", "%any"}
|
||||
|
||||
-- Prioritize vlc over all other players and deprioritize spotify
|
||||
theme.playerctl_backend = "playerctl_lib"
|
||||
theme.playerctl_player = {"vlc", "%any", "spotify"}
|
||||
|
||||
-- Disable priority of most recently active players
|
||||
theme.playerctl_backend = "playerctl_lib"
|
||||
theme.playerctl_update_on_activity = false
|
||||
|
||||
-- Only emit the position signal every 2 seconds
|
||||
theme.playerctl_position_update_interval = 2
|
||||
```
|
||||
|
|
|
@ -15,6 +15,7 @@ theme.flash_focus_start_opacity = 0.6 -- the starting opacity
|
|||
theme.flash_focus_step = 0.01 -- the step of animation
|
||||
|
||||
-- playerctl signal
|
||||
theme.playerctl_backend = "playerctl_cli" -- backend to use
|
||||
theme.playerctl_ignore = {} -- list of players to be ignored
|
||||
theme.playerctl_player = {} -- list of players to be used in priority order
|
||||
theme.playerctl_update_on_activity = true -- whether to prioritize the most recently active players or not
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
local beautiful = require("beautiful")
|
||||
|
||||
-- Use CLI backend as default as it is supported on most if not all systems
|
||||
local backend_config = beautiful.playerctl_backend or "playerctl_cli"
|
||||
local backends = {
|
||||
playerctl_cli = require(... .. ".playerctl_cli"),
|
||||
playerctl_lib = require(... .. ".playerctl_lib")
|
||||
}
|
||||
|
||||
local function enable_wrapper(args)
|
||||
backend_config = (args and args.backend) or backend_config
|
||||
backends[backend_config].enable(args)
|
||||
end
|
||||
|
||||
local function disable_wrapper()
|
||||
backends[backend_config].disable()
|
||||
end
|
||||
|
||||
return {enable = enable_wrapper, disable = disable_wrapper}
|
|
@ -0,0 +1,133 @@
|
|||
--
|
||||
-- Provides:
|
||||
-- bling::playerctl::status
|
||||
-- playing (boolean)
|
||||
-- bling::playerctl::title_artist_album
|
||||
-- title (string)
|
||||
-- artist (string)
|
||||
-- album_path (string)
|
||||
-- bling::playerctl::position
|
||||
-- interval_sec (number)
|
||||
-- length_sec (number)
|
||||
-- bling::playerctl::no_players
|
||||
--
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
|
||||
local interval = beautiful.playerctl_position_update_interval or 1
|
||||
|
||||
local function emit_player_status()
|
||||
local status_cmd = "playerctl status -F"
|
||||
|
||||
-- Follow status
|
||||
awful.spawn.easy_async({
|
||||
"pkill", "--full", "--uid", os.getenv("USER"), "^playerctl status"
|
||||
}, function()
|
||||
awful.spawn.with_line_callback(status_cmd, {
|
||||
stdout = function(line)
|
||||
local playing = false
|
||||
if line:find("Playing") then
|
||||
playing = true
|
||||
else
|
||||
playing = false
|
||||
end
|
||||
awesome.emit_signal("bling::playerctl::status", playing)
|
||||
end
|
||||
})
|
||||
collectgarbage("collect")
|
||||
end)
|
||||
end
|
||||
|
||||
local function emit_player_info()
|
||||
local art_script = [[
|
||||
sh -c '
|
||||
|
||||
tmp_dir="$XDG_CACHE_HOME/awesome/"
|
||||
|
||||
if [ -z ${XDG_CACHE_HOME} ]; then
|
||||
tmp_dir="$HOME/.cache/awesome/"
|
||||
fi
|
||||
|
||||
tmp_cover_path=${tmp_dir}"cover.png"
|
||||
|
||||
if [ ! -d $tmp_dir ]; then
|
||||
mkdir -p $tmp_dir
|
||||
fi
|
||||
|
||||
link="$(playerctl metadata mpris:artUrl)"
|
||||
|
||||
curl -s "$link" --output $tmp_cover_path
|
||||
|
||||
echo "$tmp_cover_path"
|
||||
']]
|
||||
|
||||
-- Command that lists artist and title in a format to find and follow
|
||||
local song_follow_cmd =
|
||||
"playerctl metadata --format 'artist_{{artist}}title_{{title}}' -F"
|
||||
|
||||
-- Progress Cmds
|
||||
local prog_cmd = "playerctl position"
|
||||
local length_cmd = "playerctl metadata mpris:length"
|
||||
|
||||
awful.widget.watch(prog_cmd, interval, function(_, interval)
|
||||
awful.spawn.easy_async_with_shell(length_cmd, function(length)
|
||||
local length_sec = tonumber(length) -- in microseconds
|
||||
local interval_sec = tonumber(interval) -- in seconds
|
||||
if length_sec and interval_sec then
|
||||
if interval_sec >= 0 and length_sec > 0 then
|
||||
awesome.emit_signal("bling::playerctl::position",
|
||||
interval_sec, length_sec / 1000000)
|
||||
end
|
||||
end
|
||||
end)
|
||||
collectgarbage("collect")
|
||||
end)
|
||||
|
||||
-- Follow title
|
||||
awful.spawn.easy_async({
|
||||
"pkill", "--full", "--uid", os.getenv("USER"), "^playerctl metadata"
|
||||
}, function()
|
||||
awful.spawn.with_line_callback(song_follow_cmd, {
|
||||
stdout = function(line)
|
||||
local album_path = ""
|
||||
awful.spawn.easy_async_with_shell(art_script, function(out)
|
||||
-- Get album path
|
||||
album_path = out:gsub('%\n', '')
|
||||
-- Get title and artist
|
||||
local artist = line:match('artist_(.*)title_')
|
||||
local title = line:match('title_(.*)')
|
||||
-- If the title is nil or empty then the players stopped
|
||||
if title and title ~= "" then
|
||||
awesome.emit_signal(
|
||||
"bling::playerctl::title_artist_album", title,
|
||||
artist, album_path)
|
||||
else
|
||||
awesome.emit_signal("bling::playerctl::no_players")
|
||||
end
|
||||
end)
|
||||
collectgarbage("collect")
|
||||
end
|
||||
})
|
||||
collectgarbage("collect")
|
||||
end)
|
||||
end
|
||||
|
||||
-- Emit info
|
||||
-- emit_player_status()
|
||||
-- emit_player_info()
|
||||
|
||||
local enable = function(args)
|
||||
interval = (args and args.interval) or interval
|
||||
emit_player_status()
|
||||
emit_player_info()
|
||||
end
|
||||
|
||||
local disable = function()
|
||||
awful.spawn.with_shell("pkill --full --uid " .. os.getenv("USER") ..
|
||||
" '^playerctl status -F'")
|
||||
|
||||
awful.spawn.with_shell("pkill --full --uid " .. os.getenv("USER") ..
|
||||
" '^playerctl metadata --format'")
|
||||
end
|
||||
|
||||
return {enable = enable, disable = disable}
|
|
@ -19,7 +19,7 @@
|
|||
local gears = require("gears")
|
||||
local awful = require("awful")
|
||||
local beautiful = require("beautiful")
|
||||
local Playerctl = require("lgi").Playerctl
|
||||
local Playerctl = nil
|
||||
|
||||
local manager = nil
|
||||
local position_timer = nil
|
||||
|
@ -270,6 +270,9 @@ local function playerctl_enable(args)
|
|||
args.interval = args.interval or beautiful.playerctl_position_update_interval
|
||||
parse_args(args)
|
||||
|
||||
-- Grab playerctl library
|
||||
Playerctl = require("lgi").Playerctl
|
||||
|
||||
-- Ensure main event loop has started before starting player manager
|
||||
gears.timer.delayed_call(start_manager)
|
||||
end
|
|
@ -15,6 +15,7 @@ theme.flash_focus_start_opacity = 0.6 -- the starting opacity
|
|||
theme.flash_focus_step = 0.01 -- the step of animation
|
||||
|
||||
-- playerctl signal
|
||||
theme.playerctl_backend = "playerctl_cli" -- backend to use
|
||||
theme.playerctl_ignore = {} -- list of players to be ignored
|
||||
theme.playerctl_player = {} -- list of players to be used in priority order
|
||||
theme.playerctl_update_on_activity = true -- whether to prioritize the most recently active players or not
|
||||
|
|
Loading…
Reference in New Issue