-- Leo's gemini proxy

-- Connecting to thrig.me:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

Late Stage Music Player


Granted I do not much listen to music these years—or too much if I'm obsessing over something like the second section of a Menuet, but that's not really what most would call listening to music. If I want some background noise there is the "music player"


    #!/bin/sh
    setvol 40 /mpv 100
    cd ~/share/video/aquatic && exec mpv --shuffle --no-video .

and that directory has various ambient schlock linked to from somewhere, probably it was


gemini://rawtext.club/~hut/aquatic.gmi


as "Dronny Darko" was pretty easy to search for. setvol(1) is a pretty obvious wrapper around sndioctl(1) on OpenBSD, except it takes 0..100 for the volume instead of the 0.0 to 1.0 that sndioctl(1) wants, and is easier for me to type.


    $ sndioctl
    input.level=0.600
    input.mute=0
    output.level=0.549
    output.mute=0
    server.device=0
    app/aucat0.level=1.000
    app/audacit0.level=1.000
    app/fluidsy0.level=1.000
    app/lmms0.level=1.000
    app/midipla0.level=1.000
    app/mpv0.level=1.000
    app/play0.level=1.000

Otherwise play(1) from the sox package sometimes gets used, but that lacks the easy spacebar to pause the playback like mpv(1) has. midiplay(1) is a custom fluidsynth wrapper that defaults to the generaluser-gs-soundfont; that and most of the rest are for music production.


/music/samples/eriks-bamboo-flute2.mp3


My life would probably be easier if I didn't pick hard to play end-blown flutes.


Some Older Script Rediscovered in ~/bin


    #!/usr/bin/env perl
    #
    # playmusic - plays MP3 files found in the given or otherwise current
    # directory. the shuffle is modified so that some number of recently
    # played files are not repeated

    use 5.28.0;
    use warnings;
    use Curses;
    use File::Find::Rule;
    use Getopt::Long 'GetOptions';
    use List::Util qw(all min shuffle);
    use POSIX ':sys_wait_h';

    use constant { CONTROL_C => chr(3) };

    GetOptions( 'delay|d=i' => \my $Flag_Delay ) or exit 1;

    if (@ARGV) {
        for (@ARGV) {
            die "no such directory '$_'\n" unless -d;
        }
    } else {
        @ARGV = '.';
    }

    my %files;
    @files{ File::Find::Rule->file()->name('*.mp3')->in(@ARGV) } = ();

    die "no matching files found\n" unless keys %files;

    my $remember = min 5, int sqrt keys %files;
    my @recent;

    initscr;
    curs_set(0);
    keypad(0);
    noecho;
    nodelay(1);
    raw;

    while (1) {
        for my $f (
            shuffle grep {
                my $f = $_;
                all { $_ ne $f } @recent
            } keys %files
        ) {
            shift @recent if @recent > $remember;
            push @recent, $f;

            move( 0, 0 );
            clrtobot();
            addstring($f);
            my $pid     = play($f);
            my $playing = 1;
            while ( 0 == waitpid( $pid, WNOHANG ) ) {
                my $ch = getchar() // next;
                if ( $ch eq 'q' or $ch eq CONTROL_C ) {
                    endwin;
                    my $self = getpgrp(0);
                    kill INT => -$self;
                    exit;
                } elsif ( $ch eq 'r' ) {
                    kill INT => $pid;
                    endwin;
                    exec $^X, $0, @ARGV;
                } elsif ( $ch eq 'n' ) {
                    kill INT => $pid;
                    last;
                } elsif ( $ch eq ' ' ) {
                    kill $playing ? 'STOP' : 'CONT', $pid;
                    $playing ^= 1;
                }
            } continue {
                napms(100);
            }
            napms( int rand $Flag_Delay ) if $Flag_Delay;
        }
    }

    sub play {
        my $pid = fork() // die "fork failed: $!\n";
        if ( $pid == 0 ) {
            exec qw(play -q --buffer 65536), $_[0];
            die "exec failed: $!\n";
        }
        return $pid;
    }

-- Response ended

-- Page fetched on Wed May 22 03:22:43 2024