| MP3-Splitter documentation | view source | Contained in the MP3-Splitter distribution. |
MP3::Splitter - Perl extension for splitting MP3 files
use MP3::Splitter;
# Split 2 chunks from a file: the first starts at 3sec, length 356.25sec;
# the second starts at 389sec, preferable length 615sec, but if EOF is met
# up to 10sec before expected end of chunk, this is not considered a failure.
mp3split('xx.mp3', {verbose => 1}, [3, 356.25], [389, 615, lax => 10]);
mp3split_read('xx.mp3', 'xx.list', {verbose => 1});
The first two arguments of mp3split() is a name of an MP3 file and a reference
to a hash of options, the remaining are
descriptions of pieces. Such a description is an array reference with the
start and duration of the piece (in seconds; or of the forms 03h05m56.45,
03h05m56.45s, or 03:05:56.45; any of the hours/minutes/seconds fields
can be omited if the result is not ambiguous. Alternatively, one
can specify the start field as a relative position w.r.t. the end of
previous piece (or start of file); to do this, prepend > to the
field. Similarly, one can put the absolute position of the end-of-the-piece
in the duration
field by prepending the time by =; if this field has a special value
'INF', it is assumed to go until the start of the next piece, or until
the audio ends. The remaining
elements of a piece description should form a hash of piece-specific
options (arbitrary user data can be stored with the key user).
Similarly, mp3split_read() takes names of an MP3 file and of a file with the description of pieces, followed by optional reference to a hash of options. Each line of the description file should be either empty (except comments), or have the form
START END # OPTIONAL_COMMENT
START and END are exactly the same as in the description of pieces
for mp3split(); however, END may be omited (with the same meaning as 'INF').
Note that this is a format of method output_blocks() of
Audio::FindChunks.
The following callback options should be function references with signatures
name_callback($pieceNum, $mp3name, $piece, $Xing, $opts); # returns file name prepend($pieceNum, $mp3name, $piece, $Xing, $opts, $pieceFileName, $pieceFileHandle); append( $mp3name, $piece, $pieceNum, $cur_total_time, $piece_time, $pieceFileName, $cur_total_frames, $piece_frames, $xing_written, $Xing, $opts, $pieceFileHandle); after_write($mp3name, $piece, $pieceNum, $cur_total_time, $piece_time, $piece_name, $cur_total_frames, $piece_frames, $xing_written, $Xing, $opts);
$pieceNum is 1 for the first piece to write. The default value of piece_name
callback uses the piece names of the form "03_initial_name.mp3", by default
the other callbacks are NO-OPs. The prepend and append callback can
actually write data (with a buffered write) to filehandle, or return the
string to write.
If keep_Xing option is true, and the initial file contained an
Xing frame, an Xing frame with estimated values for the number
of frames and the length of the output file is emited; if
update_Xing option is true, this frame is updated to reflect actual
size of the piece (and positions of 99 intermediate moments) when the piece is
finished. Both these options default to TRUE.
Other recognized options: verbose, overwrite and lax; the
last one means the how early the mp3 file can end before the end of the last
chunk so that an error condition is not rised; the default is 0.02 (in sec),
use some ridiculously large value (such as 1e100 if EOF is never an error).
If overwrite is false (default), it is a fatal error if a file with the
target name exists.
mp3split mp3split_read
The file with piece description
0 # Copy whole file (0..INF), and update Xing header
will (when used with mp3_split_read() and default options) keep all MP3 frames (the current implementation removes all the non-frame information from the file; this may/should change in the future). If Xing frame is present, it is updated with information about actual layout of the file (length, and positions of intermediate seek-by-percentage points).
Here is a more elaborate example of the syntax:
0.15 0h0:0.05 # The first piece of length 0.05sec starting at 0.15sec 0.3s =1 # The 2nd piece starts at 0.3sec, ends at 1sec >2 =1m # The 3rd piece starts 2 seconds after the 2nd, ends at 60sec >0 INF # The 4th piece starts where 3rd ends, ends where 5th starts 1:15 # Last piece starts at 1m15s and goes to the end
The current implementation removes all the non-frame information when extracting the chunks. this may/should change in the future.
The splitting is performed on the level of audio frames; we ignore finer structure of audio stream ("actual" chunks of audio stream may be shared between - up to 3 - consecutive audio frames). This may introduce error for up to duration of 3 frames, which is 1/25sec.
The frames are accessed via MPEG::Audio::Frame module; thus the bugs
of this module may bite us as well. In particular, until MPEG::Audio::Frame
supports skipping RIFF and ID3v1/ID3v2 headers/footers, false
"syncronization marks" in this headers may confuse this module as well.
The latter limitation may be especially relevant to users of Apple software;
due to bugs in Apple's MP3 creators, the ID3v2 headers are not
unsyncronized; note that embedded binary data (images?) have very high
probability to contain false "syncronization marks".
mp3cut, Audio::FindChunks
Ilya Zakharevich, <cpan@ilyaz.org>
Lousely based on code of mp3cut by Johan Vromans <jvromans@squirrel.nl>.
Copyright (C) 2004--2006 by Ilya Zakharevich
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.2 or, at your option, any later version of Perl 5 you may have available.
| MP3-Splitter documentation | view source | Contained in the MP3-Splitter distribution. |