PDA

View Full Version : scripting audio compression and cutting


DaveQB
21st April 2005, 04:15
Ok, its easy enough to script lame to encode but i also wont to output to 10min chunks rather then the ful length 1+ hour etc.


What would do this ??
I can do it Audacity, but i want to automate it with a script.

sox ??


edit: ahh i found something i think ...
mpgsplit from the mpgtx package.
Now to script it, a pipe would save on file system space and a little on time but not fluent in bash scripting..

six6
23rd April 2005, 15:00
I originally wrote a response to your question, but then didn't post. On second thought, here is my response, with a warning:

Since lame doesn't do video, you're better off using a pipe to mencoder and using -oac mp3lame to do the audio. Unless of course you're doing just audio (like an mp2 or mp3 file). Either way, you'll have to do a script since multiple input files will be problematic for final output. Anyway, I (conveniently) wrote a perl script to do this for you:

perl -e 'for ($time=0;$time<=MOVIE_TIME;$time+=10,$file_name++)
{ $time2=(sort{$a<=>$b}($time+10,MOVIE_TIME))[0];
$time2=undef if ($time2==MOVIE_TIME);
system "mpgtx -s file.mp2 [$time-$time2] -o - |
lame --mp2input [options] - file"."$file_name".".mp3"; }'
will process an mp2 file to mp3. Just substitute file.mp2 with the input, MOVIE_TIME with movie duration (31:52 is 31.867, etc), and [options] with whatever lame options you use, and enter it on the command line as all one line. Of course, just changing the 'system' portion to reflect using mencoder with -oac mp3lame you can do the video and lame audio all at once. Also, you can change the input from mp2 to mp3, but then specifiy --mp3input rather than --mp2input.

Warning: mpgtx seems broken. When I tried this script, mpgtx couldn't "read" mp3 files. Upon further inspection, just trying "mpgtx -s file.mp3 [0-10] -o file1.mp3" it says something about "Does not even begin with a 00 00 01 xx sequence!". Anyway, maybe you'll have better luck, and if not, find a different program but the script still works correctly :rolleyes:

Here is the lines it'd send to the system as an example (MOVIE_TIME=31.867, [options] removed):

mpgtx -s file.mp2 [0-10] -o - | lame --mp2input - file.mp3
mpgtx -s file.mp2 [10-20] -o - | lame --mp2input - file1.mp3
mpgtx -s file.mp2 [20-30] -o - | lame --mp2input - file2.mp3
mpgtx -s file.mp2 [30-] -o - | lame --mp2input - file3.mp3

PS Changing the script to bash wouldn't be too hard, but I bet it'd be more characters :)

DaveQB
23rd April 2005, 15:48
Thanx for that informative reply.

It is indeed simply audio i am using as the source.
Here is what i used with mpgsplit in a bash script



lame -f --resample 44100 -b 80 $1
mpgsplit "$1".mp3 [1/4] -o "$1"a.mp3
mpgsplit "$1".mp3 [2/4] -o "$1"b.mp3
mpgsplit "$1".mp3 [3/4] -o "$1"c.mp3
mpgsplit "$1".mp3 [4/4] -o "$1"d.mp3



Worked once and never worked again with the same errors you mention.

I'll give that perl script a shot!!

outlyer
25th April 2005, 04:18
EDIT: If you want to try with a different program than mpgtx, try mp3splt (http://mp3splt.sourceforge.net/) (haven't tested it).

After reading this thread I thought such an script may prove helpful... and incredibly tough to write for a n00b, so I took it as a challenge, here's what I came with, quite long and hackish but seems to work. If will decode the source to a raw file (with mplayer) and then encode it in chunks.
I'm a near-to-n00b to bash/*nix scripting so I'm probably doing some stupid thing.
The usual warnings apply. Multiplied,


#!/bin/sh

# chunky script - v0.1

# --- Variables ---
br=80
max_minutes=10
samplerate=44100 # target sample rate
lame_freq=44.1 # sample rate / 1000, I feel lazy to calculate it here
tempfile=temp # temporal file name

# below this, change at your own risk
samplebits=16 # temporal file sample bits
channels=2
endianness=le # I have no clue about other endiannesses...
lame_endianness="-x" # ...try to comment this if the segments sound like noise


sample_size=`expr $samplerate \* $samplebits \* $channels / 8` # PCM Bytes/Sample

# --- Parse command line ---

if [ -z "$1" ];
then
echo "Usage: $0 <input_file> [output_prefix]" >&2
exit 2
fi

input=$1

if [ -z "$2" ];
then
out_prefix="segment-"
else
out_prefix=$2
fi

# --- Check for the required commands ---
# I'm not checking for base/common *nix tools (sed, awk, dd...)
if ( ! which mplayer >/dev/null ) || ( ! which lame >/dev/null )
then
echo "[ $0 ] Some of the required commands can't be found, exiting." >&2
echo "Requirements:" >&2
echo "mplayer: `which mplayer`" >&2
echo "lame: `which lame`" >&2
fi

# --- Decode the source audio to raw pcm ---
# (a.k.a. all your disk are belong to us)
echo "[ $0 ] Decoding to raw pcm... " >&2

if [ ! -f "$input" ];
then
echo "$input not found!" >&2
exit 4
fi

# mplayer doesn't seem to like using unneeded audio filters, let's guess which
# ones to use
filterchain=
#format=s${samplebits}${endianness}

id=`mplayer -vo null -ao null -vc dummy -frames 1 -identify "$input" 2>/dev/null`
if [ $? -ne 0 ];
then
echo "[ $0 ] Error identifying source file." >&2
exit 8
fi

# FIXME: yup, this is nasty
freq=`echo $id | sed 's/ID_/\nID_/g' | grep ID_AUDIO_RATE | awk --field-separator '=' '{print $2}'`
if [ $freq -ne $samplerate ];
then
filterchain="${filterchain},resample=${samplerate}"
fi

nchan=`echo $id | sed 's/ID_/\nID_/g' | grep ID_AUDIO_NCH | awk --field-separator '=' '{print $2}'`
if [ $nchan -ne $channels ];
then
filterchain="${filterchain},channels=${channels}"
fi

if [ ! -z "$filerchain" ];
then
filterchain="-af ${filterchain}"
fi

mplayer $filterchain -vc dummy \
-vo null -ao "pcm:nowaveheader:file=${tempfile}" "$input"

if [ $? -ne 0 ];
then
echo "[ $0 ] Error creating PCM file." >&2
exit 1
fi

# --- Encode to mp3 in chunks ---
skip=0
chunk_size=`expr $sample_size \* $max_minutes \* 60` # size in bytes of $max_minutes of audio
segment=1
bytes_remaining=`ls -l "$tempfile" | tr -s ' ' | cut -d' ' -f5` # get the size

echo "[ $0 ] Encoding in segments of $chunk_size bytes..." >&2

while [ "$bytes_remaining" -gt 0 ];
do
echo "[ $0 ] Encoding loop ${segment}..." >&2
dd if="$tempfile" bs=$chunk_size count=1 skip=$skip | lame -r -s $lame_freq \
--bitwidth $samplebits -f -b $br $lame_endianness --resample $samplerate - \
"${out_prefix}${segment}.mp3"

skip=`expr $skip + 1`
segment=`expr $skip + 1`
bytes_remaining=`expr $bytes_remaining - $chunk_size`
done


# --- Cleanup ---
echo "[ $0 ] Removing the temporal file..." >&2
rm -f "$tempfile"