Holiday Soundboard

11 Dec 2013

For our first annual, digital, family newsletter, we decided to have a soundboard that played some of our daughter’s first words. This post describes the process of putting it together.

Recording

I ordered an iPhone 5s as soon as I was able, and have been using it to record many videos. I had been using a Droid Incredible for at least 4 years, having forfeitted one of my biannual upgrades. Seeing the lackluster quality of the video and pictures compared to my wife’s iPhone 4, I became increasingly disinclined to record media of either kind. When my iPhone 5s came and I experienced the quality difference, the shutterbug in me was disinterred.

So, I had been recording lots of video of our child, capturing several firsts, and everyday moments of play and babble. When sourcing for the sound board, we encouraged our daughter to say some of her most common words. While she often spoke unprompted in little morsels of sound, it seemed our insistence (or my recording) dampened her loquaciousness. Still, I captured what I could, thankful for a few choice morsels.

Importing

On OS X, you can use the Image Capture program to import videos from an iPhone. I imported the videos I had recorded in order to capture the sounds. Opening and viewing each one, in turn, in Quicktime, I found the starting position of a sound. I followed the process described below to extract each.

Clipping

Once the starting position of a sound was found, I used ffmpeg to isolate that clip. On OS X, it’s easy to install if you have brew: brew install ffmpeg. Once it is installed, you’ll have the ffmpeg command on your $PATH. Assuming you identify a clip at 3 seconds into IMG_0000.mov, with duration of approximately 5 seconds, you can issue the following command to extract it into a file called clip.mov:

ffmpeg -i IMG_0000.mov \
  -ss 00:00:03.000 -t 00:00:05.000 \
  -acodec copy -vcodec copy
  clip.mov

Listing the options used (with explanations from ffmpeg’s man page):

  • -i filename: input file name
  • -t duration: Stop writing the output after its duration reaches duration. duration may be a number in seconds, or in “hh:mm:ss[.xxx]” form.
  • -ss position: When used as an output option (before an output filename), decodes but discards input until the timestamps reach position.
  • -acodec codec: Set the audio codec.
  • -vcodec codec: Set the video codec.

Unfortunately, I would often get the duration or the exact starting point incorrect. To improve the evaluation cycle, I would view the clip.mov file as soon as it was created, and adjust the -ss and -t options accordingly.

ffmpeg -i IMG_0000.mov \
  -ss 00:00:03.000 -t 00:00:05.000 \
  -acodec copy -vcodec copy
  clip.mov && \
open clip.mov

Once I was happy with the clip, I’d convert the clip to just audio (in mp3 format), since this was an audio-only soundboard, and rename the file accordingly.

ffmpeg -i clip.mov -acodec mp3 clip.mp3

Rough HTML Page

Once that was done, with a bunch of mp3’s, I wanted to get a quick and dirty page up to play the sounds. I generated a bunch of audio tags using a bash loop.

INDEX=index.html
echo "<!DOCTYPE html><html><body>" > $INDEX
for i in *.mp3
  echo "<audio controls>
    <source src=\"$i\" type=\"audio/mpeg\">
    </audio>" >> $INDEX
echo "</body></html>" >> $INDEX

This created an ugly page, but one that I could use to display sounds. See fb1a873.

Refinement

When I was ready to improve the look of the page, I kept most of what had been already done, but added some CSS classes, and some JavaScript code to execute after the document was loaded. I kept the existing audio elements so that the page could be responsive.

Mainly, the scripts look for audio elements and use them to determine what new DOM elements to create. Sound buttons are displayed using div’s styled to look like rounded buttons. These elements are each associated with an audio element whose play function is invoked when the div element is clicked. The original audio elements are hidden from display.

Conclusion

See the gh-pages branch of the baby-sounds repository for the code, and you can visit the baby-sounds site to see it for yourself.

Looking for more content? Check out other posts with the same tags: