Using Nodejs to record microphone input to mp3 files on Ubuntu

https://ubuntuforums.org/archive/index.php/t-224748.html was very helpful.

Install lame mp3 encoder if you don’t have it.

sudo apt-get install lame

You should already have arecord, which records audio sends it to stdout.

  1. Run the command alsamixer to see your audio inputs and tweak volumes
  2. Run the command arecord -f cd | lame – out.mp3 to record audio to an mp3 file called out.mp3 until you hit ctrl-c

Now do that with Nodejs!

OK! This will record audio until you exit the script with Ctrl+C.

const spawn = require('child_process').spawn;

// prepare 2 child processes
const recordProcess = spawn('arecord', ['-f', 'cd'])
const encodeProcess = spawn('lame', ['-', 'out.mp3'])

// pipe them
recordProcess.stdout.pipe(encodeProcess.stdin);

// get debug info if you want
/*
recordProcess.stdout.on('data', function (data) {
  console.log('Data: ' + data);
});
recordProcess.stderr.on('data', function (data) {
  console.log('Error: ' + data);
});
recordProcess.on('close', function (code) {
  console.log('arecord closed: ' + code);
});
*/

// this seems like a good idea, but might not be needed 
process.on('exit', (code) => {
  console.log(`About to exit with code: ${code}`);
  recordProcess.kill('SIGTERM');
  encodeProcess.kill('SIGTERM');
});

ffmpeg: concatenate image sequences and audio

Goal

assemble multiple image sequences and audio files into 1 video file

Assumptions/Quirks

  • ffmpeg binary is sitting in my working folder and not in my PATH, so I reference it as ./ffmpeg instead of ffmpeg
  • ffmpeg version info is:
    ffmpeg version N-82143-gbf14393-tessus Copyright (c) 2000-2016 the FFmpeg developers
    built with Apple LLVM version 8.0.0 (clang-800.0.38)
    configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libass --enable-libbluray --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzmq --enable-version3 --disable-ffplay --disable-indev=qtkit --disable-indev=x11grab_xcb
    libavutil      55. 35.100 / 55. 35.100
    libavcodec     57. 65.100 / 57. 65.100
    libavformat    57. 57.100 / 57. 57.100
    libavdevice    57.  2.100 / 57.  2.100
    libavfilter     6. 66.100 /  6. 66.100
    libswscale      4.  3.100 /  4.  3.100
    libswresample   2.  4.100 /  2.  4.100
    libpostproc    54.  2.100 / 54.  2.100
    Hyper fast Audio and Video encoder
    usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...
    
  • all my images in image sequences are the same dimensions and format

  • all my audio files are the same format
  • this page offers a small mp4 file to work with: http://techslides.com/sample-webm-ogg-and-mp4-video-files-for-html5
  • this is helpful https://trac.ffmpeg.org/wiki/Concatenate

Convert Video to Image Sequence:

I need images to work with, so make some!

  • images will go into the frames directory with names like frame_0001.png, frame_0002.png etc
./ffmpeg -i test7.mp4 frames/frame_%04d.png

Convert Image Sequence back to Video

https://ffmpeg.org/pipermail/ffmpeg-devel/2005-August/000523.html

  • -c:v libx264 sets the video codec
  • -crf 23 sets the quality
  • -pix_fmt yuv420p sets the pixel format to something QuickTime can read
  • -r 24 sets input and output framerates
    • input framerate is how fast the images and the sequence are meant to be played back
    • output framerate sets how much time between frames in the output video
    • fast input and slow output results in a slideshow or timelapse
    • slow input and fast output results in duplicate frames (I think)
  • -y to overwrite files without asking
./ffmpeg -r 30 -i frames/frame_%04d.png -c:v libx264 -pix_fmt yuv420p -crf 23 -r 30  -y video-from-frames.mp4

Convert Image Sequence to Video + add audio track

http://trac.ffmpeg.org/wiki/Create%20a%20video%20slideshow%20from%20images

  • -i Bonobo - Kong.mp3 specifies another input stream
  • -c:a aac converts audio to AAC format
  • -shortest limits the length of the output video to the shortest audio or video stream (in this case, the video stream is shorter)
./ffmpeg -r 24 -i frames/frame_%04d.png -i "Bonobo - Kong.mp3" -c:v libx264 -c:a aac -pix_fmt yuv420p -crf 23 -r 24 -shortest -y video-from-frames.mp4

Concatenate multiple image sequences with 1 audio track

Put this into video-input-list.txt. The images in the image sequences must all be the same size and format

file './intro/frame_%04d.png'
file './frames/frame_%04d.png'
file './outro/frame_%04d.png'

then run the command:

  • -f concat tells ffmpeg to use the concat filter
  • -safe 0 has something to do with letting ffmpeg read relative paths in the text file
./ffmpeg -r 24 -f concat -safe 0 -i video-input-list.txt -i "Bonobo - Kong.mp3" -c:v libx264 -c:a aac -pix_fmt yuv420p -crf 23 -r 24 -shortest -y video-from-frames.mp4

Concatenate multiple images sequences and concatenate multiple audio tracks

Put this into audio-input-list.txt.

file 'big_trash_tv_hit.aif.mp3'
file 'recording.mp3'
file 'vocoded-note.aif.mp3'
file 'Bonobo - Kong.mp3'

then run the command:

  • remember to specify -f concat -safe 0 again before the second input source -i audio-input-list.txt
./ffmpeg -r 24 -f concat -safe 0 -i video-input-list.txt -f concat -safe 0 -i audio-input-list.txt -c:a aac -pix_fmt yuv420p -crf 23 -r 24 -shortest -y video-from-frames.mp4

This does what I am looking for!