Cloud Raspberry Pi

Podcasts at the Command Line with Ecasound

Recently I’ve been tasked with mixing a few podcasts – and me being me (in other words reluctant to bother using a mouse if I don’t have to… and only possessing 50usd raspberry pi computers) I decided to try using command line utils. Really a raspberry pi 3 is easily up to the task – haven’t tried it on my zero, I’m not that much of a masochist!

Happily, a combination of ffmpeg and ecasound has seemed to do a pretty good job. It was fiddly to set up but as tends to be the case with CLI setups, it holds the potential for mixing future episodes to be very fast indeed to mix.

Recording and File Prep

The two ladies recording the podcast are situated on opposite sides of the Atlantic. Therefore each has a mic and recording device and also a phone. That way the call is conducted over the phone and two pristine recordings are made locally so we get the highest possible quality.

Then I need to mix the two recordings at a later date. One of the recordings actually gets saved as m4a (odn’t ask why:) and at 48khz while the other is a wav at 44.1khz. Seeing as I like to mix at 44.1 and ecasound can only really seek effectively with wavs, I used ffmpeg to convert the m4a to a wav at the correct frequency.

  ffmpeg -i input.m4a -ar 44100 output.wav

Synch and Volume

Then I need to synch the two files from the two podcast participants. I’ve used ecasound’s simple cli syntax for this:

  ecasound -c \
  -a:1 -chcopy:1,2 -ea:70 -i:playat,$1,input_A.wav \
  -a:2 -chcopy:1,2 -ea:100 -i:input_B.wav \
  -a:1,2 -o alsahw,1,0

Let’s break that down.

  • ‘-c’ means to go into interactive mode – more on that in a moment…
  • The ‘-a:x’ bits mean an effect chain (ie input followed by a load of cables, followed by output). In this case we’re specifying multiple chains going to the same output so we have to put them in one line (ie the last one). I couldn’t really tell you why, but as long as you only mention any input or output once in the file then it seems happy connecting them to as few or many chains as you like!
  • The ‘-chcopy:1,2’ bits are simply there because the input files are mono and I have headphones and two ears! Therefore I want to be able to hear the mono channel through both sides of my headphones.
  • ‘-ea:’ is an amplifier. The value is a percentage of the natural amplitude of the file.
  • The ‘-i’ part means specifying an input. ‘playat’ means we’ve got an offset for one of the files to get them in synch. It also happens that I’ve made the offset a parameter for the bash script. In this way I can do ‘bash ./ 4’ to start input_A.wav after 4 seconds.
  • The ‘-o alsahw,1,0’ is to play through alsa to my soundcard.

But wait, what if my guess of 4 seconds turns out to be wrong??!:-)

Well if we run our command we’ll have ecasound’s interactive mode which serves as a control surface and more. Unfortunately, pretty much the only thing it can’t edit easily is that little parameter in ‘playat’ that tells it at what point to play the sample.

Therefore we press ‘t’ to start ecasound playing – then probably a whole lot of ‘fw 30’, ‘rw 10’ etc to send the transport back and forward to understand if our guess of 4 seconds to synchronise was close or not. If so then cool… If not then we simply press ‘q’ and start our script with 5.5 seconds etc…

The other thing you’ll want to do is balance the volumes between the files. This is easy interactive mode.

Just type:


You should see something like this:

  ecasound ('h' for help)> cop-status
  ### Chain operator status (chainsetup 'untitled-chainsetup') ###
  Chain "1":
          1. Channel copy: [1] from-channel 1.000, [2] to-channel 2.000
  	2. Amplify: [1] amp-% 70.000
  Chain "2":
          1. Channel copy: [1] from-channel 1.000, [2] to-channel 2.000
  	2. Amplify: [1] amp-% 100.000

Volumes are a percentage – so to change that volume from 70 to 90:

  c-iselect 1
  cop-set 2,1,90

In other words, select chain 1, then set chain-operator 2, parameter 1 to 90.

The beauty of this is you can press the up arrow and change the 90 to 95 etc then press return and execute the command again with a different value.

In this instance you’ll have to note down the two volumes you used as ecasound doesn’t edit the ‘playat’ command interactively unfortunately. When they’re noted down just press ‘q’, edit the two vols in the original script and start up ecasound again (by pressing up arrow a couple of times and return given were in bash…)

Then when you’re done just note down the number you used to synchronise and edit the last line of your script so that the output is ‘output.wav’ instead of alsa.


Everyone’s human and I’ve been asked to cut bits out…

Here I tend to fire up jack so I can have multiple outputs. (something like this: jackstart -d alsa -p 128 -n 2 -r 44100) and set up a screen or tmux session with one terminal showing:

  ecasound -c -i podcast.wav -o jack,system,notransport

This way I can whizz back and forth in playing the file and find the places I want. The ‘notransport’ bit means it doesn’t impact the whizzing back and forth I’ll be doing on the editted copy…

Then I have another tab with an sh script open which will look something like this:

  ecasound -c \
  -a:1 -i:playat,0,select,0,30,podcast.wav
  -a:2 -i:playat,30,select,35,60,podcast.wav
  -a:1,2,<and more...> -o jack,system,notransport

Above I just removed a 5 second gap.

Again, when I’m done I just replace the output for ‘podcast_edited.wav’.

Add the Intro and Outro

The last thing you’ll need to do is stick an intro and outro on it:

  ecasound -c \
  -a:1 -ea:60 -i intro.wav
  -a:2 -ea:130 -i playat,30,podcast_edited.wav
  -a:3 -ea:190 -i playat,5030,outro.wav
  -a:1,2,3 -o final.wav

And we’re done!


Multicasting Livestreams to Twitch, Twitter and More with a VPS

I’ve had a couple of people ask me how I do my multicast to both Twitch and Twitter at the same time. If you stream to periscope currently your broadcasts appear in your twitter feed therefore for twitter you need a periscope account linked to your twitter account – probly a good idea to do this soon as Periscope is closing soon.

My solution actually applies to Facebook and Youtube also – though not instagram (for reasons I’ll explain later…). Re periscope closing – according to twitter’s docs we’ll continue to be able to use the periscope api to broadcast direct to twitter until the api is migrated to twitter – so in theory come march 31st we’re still in business…

Anyway… In summary – what I’m doing is broadcasting an RTMP stream of video and audio to a VPS I rent. Then I’m using an NGINX web server on that VPS to multiply that stream to post to more than one source. Then I have the chat feed from both services open in front of me.

Another quick note re twitter – It shows your broadcast live in your feed v but then all that is left aft’r you finish is a seemingly random 30s excerpt. So probably good to then repost another link from twitch/fb/youtube etc…

1. Generating an RTMP Stream

You can do this with a number of apps on Android or iOS or if you have a desktop device then OBS can do it. I use a raspberry pi 4 with installed, a standard pi camera, and a usb interface to grab the audio.

Something like this: should work on Android – probably there is something similar on iOS. You can use a USB audio device to input audio on android and iOS if you have a fairly modern version of the OS. So in theory you can have a mixer going into your tablet pc and balance your mic etc to record a whole band!

More detail is beyond the scope of this article or though at some point I’m likely to post set up instructions for the camera etc on a pi…

2. The VPS

I use for vps’s ‘cos they’re a great company with a reliable service. But you can use digitalocean etc there are a ton of good providers.

Only need a half a gig of RAM and one CPU to do the job so we’re talking no more than a tenner a month. Note also you could conceivably only turn it on when you use it and pay next to nothing – it’s just one button to click in gandi’s dashbaord. I use mine for a ton of other things hence leave it turned on…

Steps are Debian because that’s what I use but probly ubuntu is almost identical and no doubt others can be adapted.

To Install NGinx:

  apt-get install build-essential libpcre3 libpcre3-dev libssl-dev
  tar -zxvf nginx-1.16.1.tar.gz
  cd nginx-1.16.1

You *should* be able to type this line. However with my debian 10 I found two issues.

  ./configure –-with_http_ssl_module –-add-module=../nginx-rtmp-module-master

Firstly the with_http_ssl_module option did not work. My solution was to edit /nginx-1.16.1/auto/options and search for HTTP_SSL=NO and change it to ‘YES’ (without quotes…)

Secondly the add module option syntax was insanely picky… I ended up typing it like this:

  ./configure –-add-module="../nginx-rtmp-module-master"

Then I also found my gcc was set with a different kind of error reporting so I needed to do:

  grep -r 'Werror' 

…in the nginx directory and remove all instances of that option in compile commands otherwise the compilation would break… sigh… linux how I love you…

Anyway, At that point I had a working nginx installation and could edit my /usr/local/nginx/conf/nginx.conf

Just add this to the end:

  server {
  listen 1935;
  chunk_size 4096;
  buflen 4s;
  application <whatever_you_want_as_a_password> {
  live on;
  record off;
  push rtmp:// ;
  push rtmp:// ;

Then the two commands you need (as root) are:


…to start… and…

  /usr/local/nginx/sbin/nginx -s stop

…to stop…

3. Putting it together

The stream url for your rtmp app/pi/OBS whatever will be:

…where ‘this-stream’ is just a random name you gave to this stream… And you’ll get streaming to however many services you’ve listed!

The only thing that is driving me up the wall right now is the quality settings. The command I’m using right now to go live is:

  screen -d -m bash -c "ffmpeg -i tcp:// -c:v copy -b:v 1.5M -maxrate 1.5M -bufsize 500k -x264-params "keyint=48:min-keyint=48" -c:a aac -ar 44100 -ab 112k -ac 2 -strict -2 -flags +global_header -bsf:a aac_adtstoasc -f flv 'rtmp://'" &&
  sleep 5 &&
  /home/pi/picam/picam --alsadev hw:1,0 --tcpout tcp://

Whatever the quality settings are they need to work on all the services you are using… Hopefully you can grab the relavent numbers out of the above to fit into whatever app you are using to stream!

Happy streaming!