-- Leo's gemini proxy

-- Connecting to it.omarpolo.com:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini;lang=it

Ho scritto un player musicale!


Spinto dalla curiosità ho scritto un piccolo player musicale. L’idea era più che altro vedere se fosse possibile effettuare il decoding di file musicali in un processo fortemente limitato (sandboxed).


È stato un errore. Ho scritto qualcosa che mi piace, non posso cestinarlo.


amused


Si tratta di un piccolo programmino che riproduce la musica in background ed è controllabile da una semplice interfaccia da riga di comando:


$ amused add *.mp3	# mette in coda tutti gli mp3
$ amused play		# avvia la riproduzione
playing /path/to/music.mp3
$ amused pause		# mette in pausa
$ amused status
paused /path/to/music.mp3

Tutto qui. Beh, c’è poco di più in realtà! Ha un modo unico (nel suo genere intendo) di comportarsi per quanto riguarda la gestione della lista di riproduzione.


Inizialmente ho aggiunto un comando ‘show’ per stampare la lista di file in coda. Ho subito pensato che potevo usare il comando ‘show’ per salvare lo stato del player e più tardi recuperarlo, quindi ho aggiunto un comando ‘load’ per caricare una lista di file nella coda di riproduzione.


A questo punto ho avuto un’illuminazione “unix”: perché scrivere codice specifico per azioni come rimuovere file dalla playlist, mescolarla, togliere i duplicati ecc… quando posso usare le pipeline? Dopo un po’ di smanettamento per evitare possibili race conditions questo è diventato possibile:


$ # mescolare la coda:
$ amused show | sort --random | amused load
$ # rimuovere i duplicati:
$ amused show | sort | uniq | amused load
$ # rimuovere tutte le canzoni di Guccini
$ amused show | grep -vi guccini | amused load

Le possibilità sono infinite!


Ovviamente è un programma volutamente risicato: il divertimento è stato proprio rendere il più minimale possibile garantendo comunque una certa quantità di funzioni e di comodità.


Credo comunque sia divertente e simpatico da usare dato che è banale collegarlo ad altri programmi. Qualche altro esempio per mostrare l’idea:


$ # carica la discografia dei dream theater
$ find ~/music/dream-theater -iname \*.flac | amused load
$ # riproduce una canzone selezionandola con fzf
$ amused jump "$(amused show | fzf +s)"
$ # … o con dmenu
$ amused jump "$(amused show | dmenu)"
$ # salva lo stato attuale
$ amused show > state
$ # ricarica uno stato precedente
$ amused load < state

e il tutto in un quantitativo di codice modesto:


% wc -l *.c | tail -1
    2791 total

di cui molto è stato rubato^W preso in prestito da altri demoni di OpenBSD.


La parte più difficile è stata il decoding delle tracce audio, che non avevo mai fatto prima in vita mia. Avrei dovuto immaginare che ogni formato audio (mp3, ogg vorbis, flac, …) avesse le proprie librerie dedicate, ognuna con le proprie API.


In particolare libvorbisfile e libopusfile non sono risultate troppo male da usare. libopusfile mi sembra documentata un po’ meglio, ma anche libvorbisfile si riesce ad addomesticare alla fine. libmad (mp3) ha delle API basate su callback che non mi fanno impazzire ma ci si riesce a lavorare. libflac è oscena. ‘player_flac.c’ non è un file per i deboli di cuore ;)


La vera sorpresa, anche se è più una delusione, è l’assenza di una documentazione decente per le librerie menzionate. Con “documentazione” intendo della *vera* documentazione, delle pagine di manuale. Roba autogenerata con doxigen e header con intere pagine web nei commenti (di nuovo, grazie doxigen di esistere) non contano come documentazione, sono spazzatura ad essere generosi.


amused ha come target OpenBSD. Non ho prestato molta attenzione alla portabilità, o meglio, l’ho fatto nel modo sensato, ma su questo ci tornerò in un post futuro. Non credo di provare a portare amused per altri sistemi perché si tratta di un programma incredibilmente minimale che supporta solo sndio (OK, sndio è stato portato su linux e FreeBSD.) Sarei molto più curioso se qualcun altro che usasse questi sistemi provasse ad implementarsi “il proprio” amused: che interfaccia avrebbe? Come si comporterebbe? Troverebbe qualche modo di renderlo egualmente comodo ma più minimale ancora? Toglierebbe qualche funzionalità?


Per concludere, giusto una lista di cose che sto valutando di aggiungere:


supporto per i tag: adoro i tag, ma non ho molta voglia di tornare a toccare il codice per il decoding

seeking (andare avanti/indietro di tot secondi): non lo uso molto e non voglio tornare a toccare il codice per il decoding

‘amused monitor’: uno stream di eventi interni, tornerebbe utile con programmi come lemonbar

ripeti tutti e singola traccia: implementate quasi completamente ma non ancora personalizzabili dall’utente


e ovviamente sistemare i bug :)


$BlogIt: amused.gmi,v 1.2 2022/02/17 19:30:03 op Exp $

-- Response ended

-- Page fetched on Fri May 3 01:49:05 2024