playing music in Virtual Terminal and remote-controlling via xterm

Here is a place for your projects which are not officially supported by the Porteus Team. For example: your own kernel patched with extra features; desktops not included in the standard ISO like Gnome; base modules that are different than the standard ISO, etc...
User avatar
Rava
Contributor
Contributor
Posts: 5401
Joined: 11 Jan 2011, 02:46
Distribution: XFCE 5.01 x86_64 + 4.0 i586
Location: Forests of Germany

playing music in Virtual Terminal and remote-controlling via xterm

Post#1 by Rava » 13 Jan 2020, 06:06

Playing music in the background while able to control at lease the pause and unpause?
Most of us do that at least occasionally, some do it every time they use Porteus.

Please be aware that I am using Porteus 5.0rc1 as the system here. Using e.g. x86-64 4.0 Port might give you slightly different results. Please write a reply and tell me about any discrepancies.

I know that doing this playing in VT (the virtual terminals, the standard 6 text terminals you can log into without having any x started.)

Now, I am a great friend of the terminal emulator, but an even greater buddy with the VT.
Usually the first one is used to startx so that would leave you with 5 for using.

Doing it this way has the disadvantage that you have no GUI unless you code it yourself.

It has the huge advantage that you can look into the VT from a root terminal emulator from within your GUI, and you can pause and unpause the playing of the music via remote.

And last but not least, running GUI-free programs from the VT instead of a GUI variant using X uses way less resources. This is especially an issue on older hardware (e.g. single CPU, no multi core = no x86-64 capabilities, little RAM)

You need a music player program that runs in a text terminal. mpv just does fine.
You need a way to look into the VT, I have a script for that, but it needs root rights to do so.
And then I found the gem of a C code called ttyecho.c

You have to compile it for yourself, currently I could create a x86-64 module, but I have no i586 version compiled for right now. But it is very easy to compile yourself. You need to have and activate 05-devel.xzm for the Porteus version you are running.

Lets look into my script, I called it "ct" for "cat terminal" and this is its code:

Code: Select all

#!/bin/sh
VERSION=0.7
MYNAME=ct
# ct (aka catterm) v0.5 (c) Rava@porteus-forum
# usage: ct 1 for cat of tty1 from other tty (console or xterm)
#  ct 1 1 for cat of tty and tail only 1 (=last) line, good for ctorrent or wget or mpv

# Version 0.5 removes whitespace: needs "lf" at the end!
# Version 0.6 recognises exported $COLUMNS
# Version 0.7 uses tput to get "cols", so no exported §COLUMNS needed
COLUMNS=$(tput cols)
if [ "$COLUMNS"x = "x" ] ;then
    echo $MYNAME V$VERSION - could not read \$COLUMNS - assume 80.
    COLUMNS=80
fi
if [ $# -eq 1 ]; then
    cat /dev/vcs$1 | fold -w $COLUMNS | sed 's/[ \t]*$//'
    echo
elif [ $# -eq 2 ]; then
    cat /dev/vcs$1 | fold -w $COLUMNS | sed 's/[ \t]*$//' | tail -n $2
    echo
else
    echo $MYNAME V$VERSION Unknown Parameter - Aboard.
    exit 1
fi
# Known bug: no check if "$1" is a valid number for /dev/vcs
And then there is ttyecho.c I have no clue where I got it from and it includes no programmer info nor any version info. Here is its code:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>

void print_help(char *prog_name) {
        printf("Usage: %s [-n] DEVNAME COMMAND\n", prog_name);
        printf("Usage: '-n' is an optional argument if you want to push a new line at the end of the text\n");
        printf("Usage: Will require 'sudo' to run if the executable is not setuid root\n");
        exit(1);
}

int main (int argc, char *argv[]) {
    char *cmd, *nl = "\n";
    int i, fd;
    int devno, commandno, newline;
    int mem_len;
    devno = 1; commandno = 2; newline = 0;
    if (argc < 3) {
        print_help(argv[0]);
    }
    if (argc > 3 && argv[1][0] == '-' && argv[1][1] == 'n') {
        devno = 2; commandno = 3; newline=1;
    } else if (argc > 3 && argv[1][0] == '-' && argv[1][1] != 'n') {
        printf("Invalid Option\n");
        print_help(argv[0]);
    }
    fd = open(argv[devno],O_RDWR);
    if(fd == -1) {
        perror("open DEVICE");
        exit(1);
    }
    mem_len = 0;
    for ( i = commandno; i < argc; i++ ) {
        mem_len += strlen(argv[i]) + 2;
        if ( i > commandno ) {
            cmd = (char *)realloc((void *)cmd, mem_len);
        } else { //i == commandno
            cmd = (char *)malloc(mem_len);
        }

        strcat(cmd, argv[i]);
        strcat(cmd, " ");
    }
  if (newline == 0)
        usleep(225000);
    for (i = 0; cmd[i]; i++)
        ioctl (fd, TIOCSTI, cmd+i);
    if (newline == 1)
        ioctl (fd, TIOCSTI, nl);
    close(fd);
    free((void *)cmd);
    exit (0);
}
Like I said, you need to have a terminal emulator window with "su -" already prepared, you could run "ct" as normal user, but it won`t work. You could also run ttyecho as normal user, but like its help info says, you either set the binary to setuid root or you run it as root.
Since you might also want to look into the terminal without the need to actually switch to the terminal you also want my script "ct" and that only runs when being started as root. (I never tried setuid root on any of my scripts, mostly for security reasons)

Here is what it would look like:

Code: Select all

root@porteus:/usr/local/bin/dummyforce# ct 4 2
 (+) Audio --aid=1 (mp3 2ch 44100Hz)
A: 00:00:55 / 00:35:28 (2%) Cache: 10s+53MB
root@porteus:/usr/local/bin/dummyforce# ./ttyecho /dev/tty4 P
root@porteus:/usr/local/bin/dummyforce# ct 4 1
(Paused) A: 00:01:00 / 00:35:28 (2%) Cache: 10s+53MB
root@porteus:/usr/local/bin/dummyforce# ./ttyecho /dev/tty4 P
root@porteus:/usr/local/bin/dummyforce# ct 4 2
A: 00:01:01 / 00:35:28 (2%) Cache: 10s+52MB
Cave! There is something weird with using ttyecho to give mpv the commands. At least on my running 5.0rc1 system.
Usually you use space or "p" for pause or unpause a playing mpc. But that is not working. It is not ttyecho, when I put some test text onto another VT then exactly the text put there is visible on the VT, nothing more, nothing less.

But mpv is not pausing and unpausing when given the "p" character.
It is e.g. pausing and unpausing when given "3" or "P".
Neither "3" nor "P" should be a command understood by mpv, but whatever the reason, it unpauses and pauses when given the "P".

The above should be self explanatory. ct 4 looks into VT 4 aka /dev/vcs4, and the tail only displays the last 2 or 1 line(s).
One ttyecho pauses, the next unpauses mpv.
While I coded "ct" so that you only need to have a number for accessing the VT, ttyecho needs the full /dev/ path, here it is /dev/tty4
Cheers!
Yours Rava

User avatar
Rava
Contributor
Contributor
Posts: 5401
Joined: 11 Jan 2011, 02:46
Distribution: XFCE 5.01 x86_64 + 4.0 i586
Location: Forests of Germany

playing music in Virtual Terminal and remote-controlling via xterm

Post#2 by Rava » 18 Jan 2020, 05:11

Code: Select all

root@porteus:/# type top9x
top9x is a function
top9x () 
{ 
    echo $(date +%d.%m.%Y\ %H:%M:%S) ____________________________________________________________;
    /usr/bin/top -bn 1 | head -n 16 | tail -n 10
}
Now, lets use my function top9x and top|grep to see which resources the VT mpv uses.
I played a video from the XFCE GUI with a rather small resolution - 640x360 to compare it with the resources (mainly the %CPU) the VT mpv uses playing the music.
Prior that I checked via

Code: Select all

cat /proc/1427/cmdline
to ensure that the PID 1427 is indeed the mpv started on the VT playing the background music.

Code: Select all

root@porteus:/# top9x
17.01.2020 07:44:22 ____________________________________________________________
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 1588 root      20   0  617604 349968  56048 S  12.5   8.8  61:39.42 Xorg
 4630 guest     20   0 2863756 532300  65488 S  12.5  13.4 446:53.82 palemoon
14411 guest     20   0 2136556 352804  54312 S  12.5   8.9  15:06.69 mpv
26807 root      20   0    6576   3092   2500 R  12.5   0.1   0:00.03 top
 1427 guest     20   0 1249700 156792  14904 S   6.2   3.9  31:25.48 mpv
 1439 guest     20   0 1357816   8060   5508 S   6.2   0.2  58:00.72 pulseaudio
    1 root      20   0     240      0      0 S   0.0   0.0   0:04.73 init
    2 root      20   0       0      0      0 S   0.0   0.0   0:00.14 kthreadd
    3 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_gp
As you can see, the VT music mpv uses less resources than the one playing the small video in the GUI.

Now looking only at the mpv`s:

Code: Select all

root@porteus:/# top -bn 1|grep mpv
14411 guest     20   0 2136556 352804  54312 S  12.5   8.9  14:59.69 mpv
 1427 guest     20   0 1249700 156792  14904 S   6.2   3.9  31:24.02 mpv
 1426 guest     20   0    5548    392    392 S   0.0   0.0   0:00.00 .mpv_play+
Of course, making these %CPU examinations on a 8 Core CPU machine with 4GB RAM is less impressive; doing the same on a non-x86-64 capable machine (which currently I have only one) would be more impressive, especially since the whole "playing background music in the VT and remote-controlling the pause/unpause via GUI xterminal" is of course especially of interest for folks having a i586 only capable machine, where the %CPU of background tasks like playing background music is of greater importance than on a multi-core CPU machine.
Cheers!
Yours Rava

User avatar
Rava
Contributor
Contributor
Posts: 5401
Joined: 11 Jan 2011, 02:46
Distribution: XFCE 5.01 x86_64 + 4.0 i586
Location: Forests of Germany

playing music in Virtual Terminal and remote-controlling via xterm

Post#3 by Rava » 25 Jan 2020, 03:37

For the first time ever going for the "playing sounds in the VT" approach the VT mpv failed to play the sound. It gave the infamous "[ao/pulse] The stream is suspended. Bailing out." error.

I looked for a solution and found https://superuser.com/questions/1157370 ... sa#1157524 which sounded like a working solution. I tried following the 2nd answer:
load-module module-alsa-sink device=default
load-module module-alsa-source device=default

load-module module-native-protocol-unix
by editing the global settings file /etc/pulse/default.pa - but to no prevail. The VT mpv still gave the same error and refused to play sound.

Then I was thinking "might be a suspend issue" after reading the superuser.com reply and unpaused and paused all mpv's running in the GUI, and by unpausing and pausing the one that was paused the longest and endured more than one suspend in paused mode, the VT mpv played sound once again.

So, if one of you runs into the same issue, trying to play sound via VT or sound and video via xterm and getting the "[ao/pulse] The stream is suspended. Bailing out." error, just try my solution. :)
Cheers!
Yours Rava

Post Reply