2015-09-04 03:59:46 +02:00
< ? php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
// also https://github.com/JamesHeinrich/getID3 //
/////////////////////////////////////////////////////////////////
// //
// /demo/demo.joinmp3.php - part of getID3() //
// Sample script for splicing two or more MP3s together into //
// one file. Does not attempt to fix VBR header frames. //
2015-12-20 12:20:04 +01:00
// Can also be used to extract portion from single file. //
2015-09-04 03:59:46 +02:00
// See readme.txt for more details //
// ///
/////////////////////////////////////////////////////////////////
// sample usage:
2015-12-20 12:20:04 +01:00
// $FilenameOut = 'combined.mp3';
// $FilenamesIn[] = 'first.mp3'; // filename with no start/length parameters
// $FilenamesIn[] = array('second.mp3', 0, 0); // filename with zero for start/length is the same as not specified (start = beginning, length = full duration)
// $FilenamesIn[] = array('third.mp3', 0, 10); // extract first 10 seconds of audio
// $FilenamesIn[] = array('fourth.mp3', -10, 0); // extract last 10 seconds of audio
// $FilenamesIn[] = array('fifth.mp3', 10, 0); // extract everything except first 10 seconds of audio
// $FilenamesIn[] = array('sixth.mp3', 0, -10); // extract everything except last 10 seconds of audio
// if (CombineMultipleMP3sTo($FilenameOut, $FilenamesIn)) {
// echo 'Successfully copied '.implode(' + ', $FilenamesIn).' to '.$FilenameOut;
// } else {
// echo 'Failed to copy '.implode(' + ', $FilenamesIn).' to '.$FilenameOut;
// }
2015-09-04 03:59:46 +02:00
//
2015-12-20 12:20:04 +01:00
// Could also be called like this to extract portion from single file:
// CombineMultipleMP3sTo('sample.mp3', array(array('input.mp3', 0, 30))); // extract first 30 seconds of audio
2015-09-04 03:59:46 +02:00
function CombineMultipleMP3sTo ( $FilenameOut , $FilenamesIn ) {
foreach ( $FilenamesIn as $nextinputfilename ) {
2015-12-20 12:20:04 +01:00
if ( is_array ( $nextinputfilename )) {
$nextinputfilename = $nextinputfilename [ 0 ];
}
2015-09-04 03:59:46 +02:00
if ( ! is_readable ( $nextinputfilename )) {
echo 'Cannot read "' . $nextinputfilename . '"<BR>' ;
return false ;
}
}
2015-12-20 12:20:04 +01:00
if (( file_exists ( $FilenameOut ) && ! is_writeable ( $FilenameOut )) || ( ! file_exists ( $FilenameOut ) && ! is_writeable ( dirname ( $FilenameOut )))) {
2015-09-04 03:59:46 +02:00
echo 'Cannot write "' . $FilenameOut . '"<BR>' ;
return false ;
}
2015-12-20 12:20:04 +01:00
require_once ( dirname ( __FILE__ ) . '/../getid3/getid3.php' );
2015-09-04 03:59:46 +02:00
ob_start ();
if ( $fp_output = fopen ( $FilenameOut , 'wb' )) {
ob_end_clean ();
// Initialize getID3 engine
$getID3 = new getID3 ;
foreach ( $FilenamesIn as $nextinputfilename ) {
2015-12-20 12:20:04 +01:00
$startoffset = 0 ;
$length_seconds = 0 ;
if ( is_array ( $nextinputfilename )) {
@ list ( $nextinputfilename , $startoffset , $length_seconds ) = $nextinputfilename ;
}
2015-09-04 03:59:46 +02:00
$CurrentFileInfo = $getID3 -> analyze ( $nextinputfilename );
if ( $CurrentFileInfo [ 'fileformat' ] == 'mp3' ) {
ob_start ();
if ( $fp_source = fopen ( $nextinputfilename , 'rb' )) {
ob_end_clean ();
$CurrentOutputPosition = ftell ( $fp_output );
// copy audio data from first file
2015-12-20 12:20:04 +01:00
$start_offset_bytes = $CurrentFileInfo [ 'avdataoffset' ];
if ( $startoffset > 0 ) { // start X seconds from start of audio
$start_offset_bytes = $CurrentFileInfo [ 'avdataoffset' ] + round ( $CurrentFileInfo [ 'bitrate' ] / 8 * $startoffset );
} elseif ( $startoffset < 0 ) { // start X seconds from end of audio
$start_offset_bytes = $CurrentFileInfo [ 'avdataend' ] + round ( $CurrentFileInfo [ 'bitrate' ] / 8 * $startoffset );
2015-09-04 03:59:46 +02:00
}
2015-12-20 12:20:04 +01:00
$start_offset_bytes = max ( $CurrentFileInfo [ 'avdataoffset' ], min ( $CurrentFileInfo [ 'avdataend' ], $start_offset_bytes ));
2015-09-04 03:59:46 +02:00
2015-12-20 12:20:04 +01:00
$end_offset_bytes = $CurrentFileInfo [ 'avdataend' ];
if ( $length_seconds > 0 ) { // seconds from start of audio
$end_offset_bytes = $start_offset_bytes + round ( $CurrentFileInfo [ 'bitrate' ] / 8 * $length_seconds );
} elseif ( $length_seconds < 0 ) { // seconds from start of audio
$end_offset_bytes = $CurrentFileInfo [ 'avdataend' ] + round ( $CurrentFileInfo [ 'bitrate' ] / 8 * $startoffset );
}
$end_offset_bytes = max ( $CurrentFileInfo [ 'avdataoffset' ], min ( $CurrentFileInfo [ 'avdataend' ], $end_offset_bytes ));
if ( $end_offset_bytes <= $start_offset_bytes ) {
echo 'failed to copy ' . $nextinputfilename . ' from ' . $startoffset . '-seconds start for ' . $length_seconds . '-seconds length (not enough data)' ;
fclose ( $fp_source );
fclose ( $fp_output );
return false ;
}
fseek ( $fp_source , $start_offset_bytes , SEEK_SET );
while ( ! feof ( $fp_source ) && ( ftell ( $fp_source ) < $end_offset_bytes )) {
fwrite ( $fp_output , fread ( $fp_source , min ( 32768 , $end_offset_bytes - ftell ( $fp_source ))));
}
fclose ( $fp_source );
2015-09-04 03:59:46 +02:00
} else {
$errormessage = ob_get_contents ();
ob_end_clean ();
echo 'failed to open ' . $nextinputfilename . ' for reading' ;
fclose ( $fp_output );
return false ;
}
} else {
echo $nextinputfilename . ' is not MP3 format' ;
fclose ( $fp_output );
return false ;
}
}
} else {
$errormessage = ob_get_contents ();
ob_end_clean ();
echo 'failed to open ' . $FilenameOut . ' for writing' ;
return false ;
}
fclose ( $fp_output );
return true ;
}