MOV AX, AX

main
Jay Moore 4 days ago
parent f315c44d4e
commit 3fd89311da

@ -1,8 +1,6 @@
# konversation-mpd - an mpd script for the Konversation IRC client
Currently only spams an IRC channel (or msg window) with some stats about what mpd is currently playing using whatever shortcut you assign it to. You can customize the output sent by editing the script; however I haven't generated a list of currently available variables.
Future plans include doing nice things if you're not in playback mode; as well as basic playback control from within Konversation.
An mpd interface for Konversation. Functions as a scrobbler/announcer for a window, as well as allows control of MPD by passing commands.
## Requirements
@ -11,21 +9,101 @@ Future plans include doing nice things if you're not in playback mode; as well a
mpd is obvious. bc is used to do math on sample rates.
## Installation/Usage
## Installation
- Make any changes to the formatting of the output you wish, and copy the script to wherever Konversation looks for scripts on your system.
- Assign `/exec mpdirc` to an alias of your choosing.
- Start playback in mpd.
- Issue your alias in the channel you wish to spam.
- Annoy your friends!
That's it.
## Usage
The script functions as both a ~~spa~~announcer and as an MPD client. We'll assume you assigned it to `/mpd` in Konversation.
### Playback Announcer
Simply feeding `/mpd` will ~~spa~~announce your plaback information to the current window.
`/me mpd: Song Title - Artist (From: Album) [ elapsed/duration | audioformat | bitrate | codec]`
`[Paused]` will be appended to the song title if in paused state. `mpd: Not Playing` will be shown if in stop state.
The format in which this is sent can be modified in the script itself. Simply rearrange and/or remove information you don't want. A list of variables are provided in this readme in case you want to add something.
### MPD client
The script can function as a "full" client by feeding commands/arguments to `/mpd`. Anything you send to the script will be passed to mpd as a command.
```
play [position] - Starts playback. Optional: Position to start playback at. Otherwise, uses current position.
pause - Toggles Pause.
next - skip track
previous - go back a track
```
These are just the commonly used examples. A full set of commands are available in mpd's command reference. If the command fails, the mpd error is returned to the chat window. If you want to type out the stupid long command to add a file to your playlist; it will take it and pass it.
But it's mostly to be able to go `/mpd next`.
## How It Works
The script talks to mpd (directly) using a file-handler to /dev/tcp/localhost/6600. After dropping it's banner response, we send it the `status` and `currentsong` commands; mpd responds with a ton of fields. We convert all of those fields in to a variable=value. We then check if the format is DSD or a sample rate and either specify a rate or divide by 1000. The extension of the file is obtained and some logic is done to determine which codec information we're going to display. We slap all of this in to a variable formatted the way we want; and send it to koversation over dBus.
Arguments passed to the script beyond Konversation's server and target are passed directly to mpd as a client command.
## TODO
- List of variables, in case there's something you want I'm not already listing.
- Playback controls: start, stop, pause, skip...all from within IRC.
- ~~List of variables, in case there's something you want I'm not already listing.~~
- ~~Playback controls: start, stop, pause, skip...all from within IRC.~~
- Use, test, fix edge cases.
## CHANGES
```
30-AUG-2025: Initial Release. Only announcer.
31-AUG-2025: Stop/Pause states. Added remote/client features.
```
## Variables
Since mpd reports things in the `name: value` format, it's easy to convert everything in to a script variable. As a result we pull in some additional information that's not used; whether any of it is useful I don't know. I'm just getting a full look at this list myself.
```
repeat=0
random=0
single=0
consume=0
partition=default
playlist=14
playlistlength=12
mixrampdb=0
state=play
song=0
songid=1
time=65:176
elapsed=64.992
bitrate=5644 # kbps
duration=176.360
audio=44100:16:2 (dsdxx:2) # DSD content does not report a bit-depth, and it reports it's DSD rate as sample rate. Please don't use this directly.
nextsong=1
nextsongid=2
file=Path/To/File.ext
Added=2014-10-31T00:26:24Z
Track=1 # This is album track title.
Date=2014
Album=Album Title
Artist=Artist
Title=Track Title
Performer=Performer
Time=176
duration=176.360
Pos=0
Id=1
```
Additionally, here are some script-specific variables you can use in the output:
```
audio_result - This generates samplerate khz/bitdepth-bit/stereo|format_part. It divides the sample rate by 1000, formats it from : to /, and it
also handles the DSD formatting. Inserts the MHz sample rate and appends the DSD format_part if it exists.
format_part - The audio format portion of audio_result containing sample rate, bith depth, and stereo.
codec_result - This determines what to show for codec, capitialized file extension or DSD stuff. Also reports Super Audio CD if ISO is detected.
```

@ -1,8 +1,19 @@
#!/bin/bash
# mpd announcer for Konversation - dewdude/Jay - dewdude@pickmy.org
# requires mpd and bc
#
# makes direct connection to mpd, polls for information
# spams it as an action to the current channel
# does some sample rate converstion - detects SACD playback
# Kompozer's always passed arguements
SERVER=$1
TARGET=$2
shift
shift
[[ -n "$@" ]] && COMMAND="$@"
# Initialize dbus
_qdbus=${KONVERSATION_DBUS_BIN:-qdbus-qt6}
if ! [ "$(which $_qdbus 2> /dev/null)" ]; then
_qdbus=qdbus
@ -12,6 +23,10 @@ if ! [ "$(which $_qdbus 2> /dev/null)" ]; then
fi
fi
# Script Functions
# Converts decimal seconds to "normal" format
# Arguments: seconds (floating point)
seconds_to_mmss() {
local total_seconds="$1"
@ -26,6 +41,8 @@ seconds_to_mmss() {
printf "%02d:%02d" "$minutes" "$seconds"
}
# Reparses the audio format tag, converts it to khz, and does stuff for DSD/SACD
# Argument: number:number:number (44100:16:2 - usually $audio)
format_audio() {
local audio_format="$1"
@ -34,6 +51,7 @@ format_audio() {
# Fix it all to stereo!
local channel_text="Stereo"
# DSD is silly, but I still <3 it.
case $samplerate in
dsd64)
local samplerate="2.822MHz"
@ -56,9 +74,10 @@ format_audio() {
dsd="DSD512"
;;
*)
# Converts from Hz to kHz
local trate="$(echo "scale=1; $samplerate / 1000" | bc)"
# Drops the trailing zero on sample rates like 192khz
samplerate="${trate%.0}kHz"
dsd=""
;;
esac
@ -79,7 +98,9 @@ get_extension() {
}
get_mpd_data() {
# Send commands
# This calls status and currentsong from mpd. writes result as a variable with it's value
# performs some sanitization. TODO: Get you a list of what's used.
# Send commands to mpd
printf "command_list_begin\r\nstatus\r\ncurrentsong\r\ncommand_list_end\r\n" >&3
# Read responses until we get empty line or OK
@ -87,29 +108,66 @@ get_mpd_data() {
[[ "$name" == "" ]] && break # Empty line = end of response
[[ "$name" == "OK" ]] && break
# Process the data
# Read each response and convert it in to variable=value
if [[ -n "$name" && -n "$value" && "$name" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]]; then
declare -g "$name=$value" # Use -g for global scope
declare -g "$name=$value" # Use -g for global scope - which works here.
fi
done
}
sendtokonversation() {
# Send output to channel and leave
$_qdbus org.kde.konversation /irc say $SERVER "$TARGET" "$spam"
# Open non-blocking connection MPD
exec 3<&-
exit
}
# We need (or I needed) non-blocking raw TCP. I don't think MPD has a command to close the client connection. I can send Quit or QUIT; and
# it works, but only ineractively. Any attempts to automatically script the commands to nc fail. It's like it doesn't care it saw 5 commands
# before quit...sent in order...or even in command list; you'll get the OK MPD banner and nothing. But this trick right here doesn't care.
# It's just raw TCP directly in shell. All I have to do is remember to read from it.
exec 3<>/dev/tcp/localhost/6600
# Clears the connection string from the buffer
read -r greeting <&3
# Request Data
# Control MPD
# If we're just sending a command, we can just do it here without polling for data.
#
if [[ -n "$COMMAND" ]]; then
printf "$COMMAND\r\n" >&3
read -r response <&3
if [[ $response != "OK" ]]; then
$_qdbus org.kde.konversation /irc error "mpd: $response"
fi
exec 3<&-
exit
fi
# It's all a giant work around for the fact format_audio can't set globals!
#
# Get the data from MPD
get_mpd_data
# This is part of the global varible hack junk.
case $state in
stop)
spam="/me mpd: Not Playing"
sendtokonversation
;;
pause)
Artist="[Paused] $Artist"
;;
*)
;;
esac
# Send $audio to format_audio so it can do it's magic. Also is here now due to variable hack.
audio_result=$(format_audio $audio)
# It splits the result in to new variables
# Splits audio_result since we couldn't directly set variables from the function. For some reason. I hate bash.
format_part="${audio_result%|*}" # Everything before the |
dsd_part="${audio_result#*|}" # Everything after the |
# Generate codec - either extension, DSD??, or DSD64/Super Audio CD.
# Literally determines if it should display DSD, the extension, or DSD/SuperAudioCD
fileext=$(get_extension "$file")
if [[ -z "$dsd_part" ]]; then
codec_result="$fileext"
@ -120,10 +178,6 @@ else
fi
# Format output to send to konversation
spam="/me mpd: $Artist - $Title (From: $Album) [$(seconds_to_mmss $elapsed)/$(seconds_to_mmss $duration) | $format_part | $bitrate kbps | $codec_result]"
# Spam that IRC channel!
$_qdbus org.kde.konversation /irc say $SERVER "$TARGET" "$spam"
exec 3<&-
sendtokonversation

Loading…
Cancel
Save