<?xml version="1.0" encoding="windows-1252"?>
<node id="212713" title="mp3uncue" created="2002-11-13 17:34:23" updated="2005-08-10 14:17:38">
<type id="1748">
sourcecode</type>
<author id="114691">
Aristotle</author>
<data>
<field name="doctext">
&lt;code&gt;#!/usr/bin/perl -w
use strict;
# mp3uncue: cut a multiple track MP3 into individual tracks using a .CUE sheet
#           requires:
#           - mpgedit &lt;http://mpgedit.org&gt;
#           - id3tool &lt;http://freshmeat.net/projects/id3tool/&gt;
# 
# Version 0.1: Nov 12, 2002, A. Pagaltzis
#
# (c)2002 A. Pagaltzis, licensed under the GPL
# see http://www.gnu.org/copyleft/gpl.html

use Env qw(@PATH);
use File::Path;
use File::Basename;
use File::Spec::Functions;
use Getopt::Long;

use constant SEPARATOR =&gt; "TRACK";
use constant NAME_FMT =&gt; "%02d %s - %s.mp3";
use constant NAME_FIELDS =&gt; qw(TRACK PERFORMER TITLE);

my %keyword = (
	PERFORMER =&gt; sub { $_[0] },
	TITLE     =&gt; sub { $_[0] },
	TRACK     =&gt; sub { $_[0] },
	INDEX     =&gt; sub {
		my ($m, $s, $f) = split /:/, $_[1], 3;
		"$m:" . sprintf("%06.3f", $s + $f / 75);
	},
	FILE      =&gt; sub { $_[0] },
);

my ($infile, $outdir, $album, @exec, $mpgedit, $id3tool);


## parse cmdline options and check existence of tools
(
	GetOptions(
	 	'infile|i=s', \$infile,
	 	'outdir|d=s', \$outdir,
	)
	&amp;&amp; (@ARGV &gt; 0)
	&amp;&amp; (@exec = grep { -f and -x _ } map {
		my $dir = $_;
		opendir my($dh), $dir;
		map catfile($dir, $_), readdir $dh;
	} @PATH)
	&amp;&amp; (($mpgedit) = grep basename($_) eq 'mpgedit', @exec)
	&amp;&amp; (($id3tool) = grep basename($_) eq 'id3tool', @exec)
) or die &lt;&lt; 'USAGE';
usage: mp3uncue [-i infile] [-d outdir] sheet.cue
       --infile -i  defaults to filename from cue sheet
       --outdir -d  defaults to current directory

       You need mpgedit &lt;http://mpgedit.org&gt; and
       id3tool &lt;http://freshmeat.net/projects/id3tool&gt;
       in your PATH to run this utility.
USAGE


## parse cue sheet
my $rx = do { local $" = "|"; qr/(@{[keys %keyword]})\s+(.*)/ };
my @track = ({});
while(&lt;&gt;) {
	chomp;
	(my ($key), $_) = /$rx/ or next;
	push @track, {} if $key eq SEPARATOR;
	$track[-1]-&gt;{$key} =
		$keyword{$key}-&gt;(/"?((?&lt;!")\S+(?&lt;!")|[^"]+)"?\s*/g);
}
push @track, { INDEX =&gt; '' };


## set overall defaults
for(shift @track) {
	$infile ||= $_-&gt;{FILE};
	$album  ||= $_-&gt;{TITLE};
	$outdir ||= '.';
}

## process
mkpath [$outdir] if not -d $outdir;
for my $i (0 .. $#track-1) {
	for($track[$i]) {
		(my $filename = sprintf NAME_FMT, @$_{NAME_FIELDS()}, ('')x10) =~ tr/ _/_/s;
		my $time = $_-&gt;{INDEX} . '-' . $track[$i+1]-&gt;{INDEX};
		printf STDERR "%-19s = $filename\n", $time;
		$filename = catfile($outdir, $filename);
		system(
			$mpgedit, '-s',
			-e =&gt; $time,
			-f =&gt; $infile,
			-o =&gt; $filename,
		) == 0 or die basename($0).": mpgedit failed creating $filename\n";
		system(
			$id3tool,
			"--set-title="  . ($_-&gt;{TITLE} || ""),
			"--set-artist=" . ($_-&gt;{PERFORMER} || ""),
			"--set-album="  . ($album || ""),
			"--set-track="  . ($_-&gt;{TRACK} || ""),
			$filename,
		);
	}
}&lt;/code&gt;</field>
<field name="codedescription">
Some people archive their CD audio albums as a single MP3 with a CUE sheet supplied. This script uses [http://mpgedit.org|mpgedit] to slice such a monolithic MP3 album into individual MP3 tracks (without reencoding any audio data) and [http://freshmeat.net/projects/id3tool/|id3tool] to tag them with the information from the CUE sheet.</field>
<field name="codecategory">
Audio Related Programs</field>
<field name="codeauthor">
/msg Aristotle</field>
</data>
</node>
