9. December 2014

Access a website in bash and react to it

Categories: Linux – Ronny Schmatzler 22:47

nolf2Sometimes specific scripts I wrote run for years and suddenly I realize, that essential parts are missing in them, which breaks everything.

I wrote the article Host Windows games on a Linux server a while ago – the setup described in this article is running on this machine since a lot of years. A bash script is checking if the process of a gameserver is running (it doesn’t matter if it’s a wine process or a native one). If it doesn’t run, it will be started. This ensures that all my game servers are available for 99% of the year.

If a program is written fairly well, this isn’t even a problem. When a fault happens, these ones kill themselves and get restarted after some seconds.

The server executable of “No One Lives Forever 2″ was a bit more difficult. When I started it, people could play on the machine for some hours straight, until it lost the connection to the internet. The .exe was still running, so there was no way for my bash script to react to it.

But on this adress I have a web frontend running, which is displaying to me very reliably if the NOLF2 server is still running or not.

First I thought, I would only have to check if the phrase “OFFLINE” is appearing on that website and if it is, kill the server and restart it. This idea was very dumb, because when a player gives himself the name “OFFLINE” he can kill the server with that. Also, the program needs some time to load up the maps and the web interface is caching requests for some seconds, too.

I ended up with this solution – this script is checking if the server is online. If it is, it immediately aborts. When the server is offline, the scripts checks for the status again after 90 seconds. That’s simple enough to make it accessible most of the time:

# if online is NULL, it's down. May change maps, so wait and check again:
if [ -z "$(curl -sSf http://hirnschwund.net/?s=4 | grep "ONLINE")"]; then
echo "Shit is offline"
sleep 90
if [ -z "$(curl -sSf http://hirnschwund.net/?s=4 | grep "ONLINE")"]; then
echo "Shit is still offline"
echo "Killing process"
pkill NOLF2Srv.exe
sleep 2
echo "Starting server"
nohup xvfb-run -n 666 wine NOLF2Srv.exe >/dev/null 2>/dev/null &
echo "NOLF2 is running, leave."

29. November 2014

SimpleScreenRecorder: Record audio with ALSA only (no Pulseaudio, no JACK)

Categories: Linux – Ronny Schmatzler 17:28

I’ve started recording video game sessions a while ago, since I think they’re fun. Needless to say that I don’t want to just see the screen, but also hear and record the game.

The problem with this is: A screen recording application always takes control of the sound card. Using ALSAs default settings, I can either hear the audio of the game or record it. So in order to record the audio stream, I would have to play muted.

First, I’ve tried different approaches:

glc. As it seems, this program is not being developed anymore and it just works with OpenGL. Ancient DirectDraw games can not be recorded with this.

PulseAudio. Yeah, I really installed this junk on my computer, hoping that the system was improved in the last years. I was very wrong. The attempt to access my internal sound card (VT1705) resulted in PulseAudio crashing. Granted, it could access my external one (CM6206), but I already had enough of it. Thanks Lennart Poettering, your software is making the Linux world way more complicated than it should be.

Finally, I found SimpleScreenRecorder. Although it is listing ALSA devices in the interface, they didn’t work. All of them. Of course, this program has been written with Pulseaudio in mind, too…

But I was lucky, because ALSA has a loopback interface. This is basically a virtual sound card. It creates to devices, Loopback 1 and Loopback 2. I can throw everything I want into one side and it comes out at the other.

The virtual devices can be created with this command:

modprobe snd_aloop pcm_substreams=1

So I took my original .asoundrc as a base and put this code at the bottom:

pcm.loopsnoop {
    type dsnoop
    ipc_key 321456 # any unique value
    hint { show on
           description "(Loopback-Aufnahme)"
    slave {
        pcm "hw:3,1,0" #Loopback.2
        channels 2
        #rate 48000

pcm.split {
    type plug
    slave {
        pcm {
          type multi
          slaves {
            a { channels 2 pcm "upmix" } #sound card (default/hw:x,x)
            b { channels 2 pcm "hw:3,0,0" } #Loopback.1
          bindings {
            0 { slave a channel 0 } # Left
            1 { slave a channel 1 } # Right
            2 { slave b channel 0 } # left
            3 { slave b channel 1 } # right
       #rate 48000
    ttable [
[ 1 0 1 0 ] # left
[ 0 1 0 1 ] # right

After that, I changed the segment pcm.softvol in a way, that every audio is routed through the split device by default:

pcm.softvol {
    type            softvol
    slave {
        pcm         "split"

Done! Now the SimpleScreenRecorder has a new device in the list, called ” (Loopback-Aufnahme)”. Using this, I can record the audio of my games while playing them.