Arrow

How to merge / concatenate mp3s with PHP

First published on August 12, 2007

One of the new features of my anti-spam plugin is the ability to create auto-generated mp3 files. The plugin concatenates individual mp3 files representing the sound of each letter in the alphabet, in order to build a word.

Of course, I have no idea how to code something that merges mp3 files, so I had to do some searching and eventually found this site with some working code: http://www.sourcerally.net/Scripts/20-PHP-MP3-Class.

Here is my modified version, with some simplified functionality (I removed the code that added ID3 tags) and an added feature that I modified from FPDF (a script that creates PDFs in PHP) in order to output (to the browser) the merged mp3 file, prompting users to open or save it. This code is compatible with both PHP 4 and PHP 5.

<?php
// This is the class to generate mp3 files based on the anti-spam words
// Based on the PHP mp3 class at http://www.sourcerally.net/Scripts/20-PHP-MP3-Class
// Output code based on the FPDF class at http://www.fpdf.org
class mp3
  {
  	var $str;
  	var $time;
  	var $frames;
  
  	// Create a new mp3
  	function mp3($path="")
  	{
  	if($path!="")
  		{
  		$this->str = file_get_contents($path);
  		}
  	}
  
  // Put an mp3 behind the first mp3
  function mergeBehind($mp3)
  {
  $this->str .= $mp3->str;
  }
  
  // Calculate where's the end of the sound file
  function getIdvEnd()
  {
  $strlen = strlen($this->str);
  $str = substr($this->str,($strlen-128));
  $str1 = substr($str,0,3);
  if(strtolower($str1) == strtolower('TAG'))
  {
  return $str;
  }
  else
  {
  return false;
  }
  }
  
  // Calculate where's the beginning of the sound file
  function getStart()
  {
  $strlen = strlen($this->str);
  for($i=0;$i<$strlen;$i++)
  {
  $v = substr($this->str,$i,1);
  $value = ord($v);
  if($value == 255)
  {
  return $i;
  }
  }
  }
  
  // Remove the ID3 tags
  function striptags()
  {
  //Remove start stuff...
  $newStr = '';
  $s = $start = $this->getStart();
  if($s===false)
  {
  return false;
  }
  else
  {
  $this->str = substr($this->str,$start);
  }
  //Remove end tag stuff
  $end = $this->getIdvEnd();
  if($end!==false)
  {
  $this->str = substr($this->str,0,(strlen($this->str)-129));
  }
  }
  
  // Display an error
  function error($msg)
  {
  //Fatal error
  die('<strong>audio file error: </strong>'.$msg);
  }

// Send the new mp3 to the browser function output($path) { //Output mp3 //Send to standard output if(ob_get_contents()) $this->error('Some data has already been output, can\'t send mp3 file'); if(php_sapi_name()!='cli') { //We send to a browser header('Content-Type: audio/mpeg3'); if(headers_sent()) $this->error('Some data has already been output to browser, can\'t send mp3 file'); header('Content-Length: '.strlen($this->str)); header('Content-Disposition: attachment; filename="'.$path.'"'); } echo $this->str; return ''; } } ?>

Here’s how I used the class to generate an mp3 file from individual files (in a “sounds” folder) representing each letter. You can, of course, use the above code to concatenate mp3 files for any purpose.

// Specify the word 
$petersword = "testword";

$word_count = strlen($petersword);

 // Set up the first file
  if ($word_count > 0) {
  $mp3 = new mp3($cas_fontpath . 'sounds/' . substr($petersword, 0, 1) . '.mp3');
  $mp3->striptags();
  }

// Generate the mp3 file from each letter in the word 
  for ($i = 1; $i < $word_count; ++$i) {
  $cas_character = $cas_fontpath . 'sounds/' . substr($petersword, $i, 1);
  $cas_mp3equivalent = new mp3($cas_character . '.mp3');
  $mp3->mergeBehind($cas_mp3equivalent);
  $mp3->striptags();
  }
  
  // Spit out the audio file!  
$mp3->output('word.mp3');

Note: if you need some support using any of the code, I suggest that you visit the original source of the mp3 concatenation code.

Arrow

19 Responses to “How to merge / concatenate mp3s with PHP”


  1. Priyankoo Sarmah says:

    Thanks a lot!! So useful!!


  2. Alx says:

    do it is possible to insert a pause into file merged?


  3. Peter says:

    Yes, you can insert a pause — to do so you simply have to record a blank sound file as the pause.


  4. Alx says:

    This is my implementation:

    http://interno.netsons.org/modules.php?name=Dtmf

    http://interno.netsons.org/modules.php?name=Banche

    http://interno.netsons.org/modules.php?name=CodFis

    Ty :)


  5. Dada says:

    I was looking for that sort of script since severals months, you’re my hero, thanks alot.


  6. Thierry says:

    Thanks for sharing. It worked on the first try … what I though would take hours, take me 30mn …


  7. Vaz says:

    Excellent…I thought we need some extra things to work mp3 with php…great tutorial


  8. Mukoo says:

    Thanks! it works perfectly. But how about layering/mixdown 2 mp3’s, not simply appending one after the other. What if I want them to blend together? Do you think it can be done?

    Reply from Peter: It can certainly be done with desktop programs, but I’ve never looked into a command-line solution. If you find something, please post your findings.


  9. Natali says:

    Very helpfull!!! Many thanks!!!


  10. Sarunas says:

    When merging mp3s with different bitrates the higher bitrate mp3 plays in slow motion. Any solutions to this?

    Reply from Peter: Not sure, but I welcome other people’s solutions.


  11. Michel says:

    This script is exactly what I was looking for but… is there a way to have the sound played by a flash script like hbs_mp3_player.swf directly in the web page?
    When I use your script I’m asked to download the merged mp3 file or play it with VLC or WMP.

    Reply from Peter: I’m pretty sure you could feed the generated file to a player, since it shouldn’t be any different than any other mp3 player. If it’s a file being generated on the fly, you probably have to save it to the server and stream it from there.


  12. John C says:

    Dear all,

    I am a beginner with php. I would like to adapt this script to merge 2 mp3 files (file1.mp3 and file2.mp3 into file-merged.mp3).
    It should be very simple compared to this script.
    Thank you very much for your kind replies.

    JC


  13. nischal dhakal says:

    Dear all,
    When i am trying to merge two mp3 files which have more than 2:00 minutes lengths of file, It create a merge file but can’t be opened on window media player. Anyone have any answer with this.
    thank you….


  14. Teryaki says:

    Hey
    Thank you very much for your script. it works fine.
    What changes do i need to make, if i want to merge ogg files?

    Reply from Peter: I haven’t looked into ogg files, but please share any findings!


  15. Matt says:

    Hey Peter,

    You said you removed the section which added ID3 Tags, but can you help me with putting in new ID3 tags into the downloaded file?

    Reply from Peter: Unfortunately, I don’t have the original code and it looks like the original link is broken. Looks like you’ll have to search elsewhere. Good luck!


  16. Nour says:

    Is there any documentation about this mp3 class, the given link is broken.


  17. Kalpesh says:

    Hello Sir,
    I want joint two or more mp4 audio file in one audio file using code igniter framework .
    How to implement this code in my project.

    Please Help…….


  18. Stanislas says:

    Hello Sir,
    I am a beginer in php and I just want to merge two files:
    $file_total = $file_1 + $file_2
    I tried to understand your code during a long time, but I can’t understand where is the code for just adding 2 files.
    Each time they put me a warning which says : "Catchable fatal error: Object of class mp3 could not be converted to string"
    what should I do ?
    Thanks for your answer

    Reply from Peter: Are you merging mp3 content, text, or non-mp3 binary files? Most of the code is for handling mp3s, so you should look for some other code specific to your purpose.


  19. Peter says:

    This is amazing! Thanks a lot for sharing this code and also the audio files! I’ll use this for my own custom CAPTCHA implementation.

    One change which is required to make it work with "new" PHP versions: The constructor must now be called "__construct" instead of "mp3". Otherwise it won’t be invoked.

    Another little improvement I made is adding playback via JavaScript. This is much more convenient than having to download the file.

    As a fallback / non-JS solution you can also just remove the "Content-Disposition"-header. Modern browsers won’t make you save the file then but instead it will be opened directly in the browser and you can play it easily (you should open it in a new tab so users don’t lose their input). It’s probably smart to still offer a download link for best compatibility.

    btw: In case anyone still needs the tag stuff: I also found this newer PHP mp3 merge code which seems to do these things (didn’t try it): https://github.com/thegallagher/PHP-MP3/tree/master

Speak your mind

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word