File: demo.joinmp3.php

package info (click to toggle)
php-getid3 2.0.0~beta6%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 3,108 kB
  • sloc: php: 34,627; makefile: 12
file content (141 lines) | stat: -rw-r--r-- 5,681 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<?php

use JamesHeinrich\GetID3;

require __DIR__ . "/../vendor/autoload.php";

/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org>               //
//  available at https://github.com/JamesHeinrich/getID3       //
//            or https://www.getid3.org                        //
//            or http://getid3.sourceforge.net                 //
//                                                             //
// /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.        //
// Can also be used to extract portion from single file.       //
// Note: all joined MP3s need to be the same sample rate.      //
//  see readme.txt for more details                            //
//                                                            ///
/////////////////////////////////////////////////////////////////

die('For security reasons, this demo has been disabled. It can be enabled by removing line '.__LINE__.' in demos/'.basename(__FILE__));


// sample usage:
//   $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;
//   }
//
// 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


function CombineMultipleMP3sTo($FilenameOut, $FilenamesIn) {

	foreach ($FilenamesIn as $nextinputfilename) {
		if (is_array($nextinputfilename)) {
			$nextinputfilename = $nextinputfilename[0];
		}
		if (!is_readable($nextinputfilename)) {
			echo 'Cannot read "'.$nextinputfilename.'"<BR>';
			return false;
		}
	}
	if ((file_exists($FilenameOut) && !is_writeable($FilenameOut)) || (!file_exists($FilenameOut) && !is_writeable(dirname($FilenameOut)))) {
		echo 'Cannot write "'.$FilenameOut.'"<BR>';
		return false;
	}

	ob_start();
	if ($fp_output = fopen($FilenameOut, 'wb')) {

		ob_end_clean();
		// Initialize getID3 engine
		$getID3 = new GetID3\GetID3;
		foreach ($FilenamesIn as $nextinputfilename) {
			$startoffset = 0;
			$length_seconds      = 0;
			if (is_array($nextinputfilename)) {
				@list($nextinputfilename, $startoffset, $length_seconds)  = $nextinputfilename;
			}
			$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
					$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);
					}
					$start_offset_bytes = max($CurrentFileInfo['avdataoffset'], min($CurrentFileInfo['avdataend'], $start_offset_bytes));

					$end_offset_bytes = $CurrentFileInfo['avdataend'];
					if ($length_seconds > 0) {       // set end offset to X seconds from start of audio
						$end_offset_bytes = $start_offset_bytes           + round(($CurrentFileInfo['bitrate'] / 8) * $length_seconds);
					} elseif ($length_seconds < 0) { // set end offset to X seconds from end of audio
						$end_offset_bytes = $CurrentFileInfo['avdataend'] + round(($CurrentFileInfo['bitrate'] / 8) * $length_seconds);
					}
					$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);

				} 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;
}