Thursday, August 18, 2005

Removing sound from video files

Just got back from a Bay Area trip, visiting my friend MS et al. While I was down there, we visited the world-famous Monterey Bay Aquarium, where, among other things, I found many reasons to play around with the movie recorder on my new digital camera. The results were impressive --- considering it's a camera and not a camcorder, the Canon PowerShot A95 takes really nice-looking videos at 640x480 --- but the ambient sound inside the aquarium was just crowd noise: murmuring strangers, screaming kids, and such. Sort of ruins the mood when you're looking at a video that looks like this:

The PowerShot A95 doesn't have a way to turn off the sound during video recording either. So, I wanted to strip the sound off my video files, without re-encoding the video (which would reduce the image quality).

"Surely," I thought, "this will be easy. The AVI file format stores audio in separate binary chunks from the video --- it's just a matter of erasing the audio chunks. Even if the software that comes with my camera can't do it, there will be multiple freeware utilities that can. Maybe not for Linux, but surely for Windows..."

Ha, ha.

Anyway, to make a long story short, I couldn't find a good free utility to do this under Windows. I found many programs that let me replace the soundtrack to a movie, but for some reason none of them could remove the sound altogether. I didn't feel like dropping a few hundred bucks on Adobe Premiere either. So, the best option turned out to be --- surprise! --- a Unix utility called transcode. I got mine via the freshrpms yum repository for Fedora Core 4, read the manual pages and the wiki, and came up with the following recipe:

transcode -i foobar.avi -P1 -o foobar_nosound.avi -y raw,null

Geeky details: this instructs transcode to read the video from foobar.avi, pass through the video track only, write the output to foobar_nosound.avi, and use raw encoding for the video and null encoding for the audio.

Here's a Python script that makes transcode batch processing easy; just give it a list of filenames of the format foobar.avi, and it will produce a list of silent video files named foobar_nosound.avi:

#!/usr/bin/env python

import os.path
import subprocess
import sys

def splitExtension(filename):
    lastdot = filename.rfind('.')
    return (filename[:lastdot], filename[lastdot:])

infiles = sys.argv[1:]
for infile in infiles:
    (prefix, ext) = splitExtension(infile)
    outfile = prefix + "_nosound" + ext
    idx = 0
    while os.path.exists(outfile):
        idx = idx + 1
        outfile = prefix + "_nosound_" + str(idx) + ext
    print infile + " stripped to:" + outfile
    retcode = subprocess.call(
        ['transcode',
         '-i', infile,
         '-P1',
         '-o', outfile,
         '-y', 'raw,null'])

4 comments:

  1. Hmm, I seem to be sharing this space with a bunch of spammers. I thought typing in "OOPSLA KDE kook" was cool.

    ReplyDelete
  2. When you put a post up like this, do you think about key words that will help a search engine? My brother just discovered that the guy in his office that he thought was a real computer guru turns out to actually be a search guru which is often as good.

    ReplyDelete
  3. Not really, though I did tag this post with Technorati Tags, mostly just to experiment with tagging. I do hope that this post will be useful to people who find it on a search though.

    ReplyDelete
  4. It's a bit too late, and kinda a kluge, but couldn't you just have used a free sound editor to generate the right duration of silence, and use that "song" to replace the audio?

    ReplyDelete