I need to merge two flv files, using PHP. I can't use exec method. I am wondering if is possible to cut some part of one flv file (audio tag) and paste to another and overwrite duration for output file.
I have found interesting solution here: calculate flv video file length ? using pure php but I do not know how can I get an audio tag from a flv file? How many audio tags a flv file has? Which tags should I overwrite in output file to be able to play audio from two merged files?
I will be very gratefull for advices.
Many thanks,
Piotr
I strongly recommend you to go to http://www.adobe.com/devnet/f4v.html and download the FLV/F4V specification made freely available by Adobe.
Using the techniques I described in my answer you linked at, you should be able to achieve your goal.
Be careful however when trying to join files with different codecs, since the resulting file has good chances to confuse the flash player, or even not playing at all past the junction point.
Otherwise, I don't really understand your goal.
If you plan to put a file's audio track into another file, I would really discourage you from doing it in PHP, but instead using video tools such as ffmpeg.
If you're stuck with PHP, you should probably read both files concurrently, synchronizing via each tag's timestamp, reading the first file's video, and the second file's audio, combining tags by temporal order into a third new file.
Related
What we want to do is to add a kind of MP3 preroll to an other MP3 file in real time. That means we have two physical MP3 files on the server which are not merged into one yet, because ffmpeg & Co. take too much time. It has to be in real time to not loose time when someone starts the (web)player. The practical case is to add prerolls to podcast files. What we already did (described below) works, except displaying the correct file duration in audio players.
One of my co-workers did this, so I try to describe as good as possible.
What my coworker already did is telling the header that two files are coming in a row by reading both files and echoing them via PHP. HTTP/1.1 206 Partial Content is used for delivering the "merged" content.
The problem is, that there are still two ID3 Tags from both files and most audio players only read the first one, which occurs wrong duration displays. The only case it works 100% is in VLC after downloading the whole thing. No webplayer, no iTunes etc. can manage the "merged" file duration.
Any idea how to create a "virtual ID3 Tag" in real time and how to remove the existing ones without touching the original files?
There are a lot of inaccurate conclusions you've come to, so let me start by correcting those, which may help you solve the problem.
because ffmpeg & Co. take too much time
FFmpeg can merge these audio streams faster than you can stream to clients for sure. If you're using -codec copy (which you should be in this case), it will handle all the demuxing/muxing for you. And, keep in mind that you can stream directly out of FFmpeg. No need for an intermediary file.
The practical case is to add prerolls to podcast files.
The FFmpeg route is what you want.
What my coworker already did is telling the header that two files are coming in a row by reading both files and echoing them via PHP. HTTP/1.1 206 Partial Content is used for delivering the "merged" content.
That's a bit of a wonky way to do this. You could instead just merge the data and send it directly in a single response.
The problem is, that there are still two ID3 Tags from both files and most audio players only read the first one, which occurs wrong duration displays.
No, the usual ID3 tags don't indicate duration. (There is an extension which does, but this is rarely used.) There is nothing in the bare MP3 stream that indicates duration either. Clients estimate this based on file size and bitrate. The bitrate can change mid-stream, so they usually estimate based on the bitrate of the first couple frames.
Undoubtedly, the problem in your case is incorrect length headers due to the way you're handling this merging, and/or a mismatch of bitrate which causes the length estimate from the player to be wrong.
Any idea how to create a "virtual ID3 Tag" in real time and how to remove the existing ones without touching the original files?
I would absolutely use FFmpeg for this work. If anything, because not all podcasts use MP3. There are plenty of AAC in MP4 podcasts, and a handful of Opus in WebM as well.
I'm using the Google Text-to-Speech to make a game, but the TTS have a limit of 100 characteres per request. So, I split the text, and I do more than one request to synthesize the complete text.
Now, I have the binary of sound of my text split in two files.
Just doing a simple
$audio1 .= $audio2
doesn't work.
The file type is MPEG, so it's not the same as MP3.
I think I need to clear the headers of the second file, but I dont know how to.
I made a test using your URL, it generates MP3 files, after a lookup on Google it could be done:
https://www.dropbox.com/sh/iwbzqdvsxymytgu/c2SaOVjcHY (Hosted on Dropbox for Audio files)
There is a FFmpeg tool to process media files, example concat two files
I'm trying to build a site using HTML5's video tag so that I can share some movies I have made. Their sizes are pretty big (>500 MB), and when I watch them from outside my network, it seems like it's trying to download the whole thing before showing it. I'm wondering how I can make it so that they can be downloaded and watched at the same time.
I'm using php and javascript to build the site, although if there are libraries or techniques available in other languages, I'm more than happy to hear about them.
Video files on the web sometimes need to be encoded in a special way in order for them to be played while downloading. In order for flash based videos to work, data called "moov" must be moved from the end of the stream to the start. A program called mp4 FastStart can do this for you.
Programs like HandBrake have a "web" option that also does this when encoding. The data basically contains the length of the video, etc. Typically this was at the end of the file. However when the web came along that meant downloading the entire thing before being able to play.
Can you tell us what format the video is?
Do you know a class to merge two MP3 files using PHP?
I've found nothing on Google.
If by merging, you mean placing one audio over the other, then please disregard this answer.
If you dont want to re-encode the MP3s, you can probably just append them. I know this worked for MPEG movies, so I guess it could work for MP3s too. Another option would be to add the audo files to a Zip Archive with no compression and then rename the extension to .mp3.
I did a quick test and this
file_put_contents('combined.mp3',
file_get_contents('file1.mp3') .
file_get_contents('file2.mp3'));
worked fine. The ID3 tags will be wrong, but the resulting file contains both audio files. For some other possible gotchas, see the link in Pekka's answer.
Also, some quick googling resulted in
http://www.sourcerally.net/Scripts/20-PHP-MP3-Class
http://codingforums.com/showthread.php?t=169069
and some discussion
http://ask.metafilter.com/21381/Merge-mp3s-with-PHP
For anyone interested in doing the same thing now, you can use the following library that I wrote (refactored?):
https://github.com/falahati/PHP-MP3
composer require falahati/php-mp3
Merge two MP3 file:
$audio1 = \falahati\PHPMP3\MpegAudio::fromFile("1.mp3")->stripTags();
$audio2 = \falahati\PHPMP3\MpegAudio::fromFile("2.mp3")->stripTags();
$audio1->append($audio2)->saveFile("3.mp3");
Please note that this is an MP3 parser library and it does not encode, decode or re-encode MP3 files. This solution is essentially the same as others here but always results in a structurally correct and standard MP3 file.
-- In answer to the comment about the invalid duration of the file:
MP3 files have no header and only consists of MPEG frames. This library keeps the MPEG frame headers (since it won't be playable without those) and therefore the problem described here is not entirely true.
However, from the point of view of a player or a tool that needs to extract the duration of an MP3 file, in the absence of an ID3 tag, the whole file should be read and calculate the duration frame by frame. This is both calculation-intensive and memory-intensive, especially for big files.
Therefore many tools might try to read the first frame and guess the number of total frames based on the total size of the file and simply calculate the possible duration of the file from this information and based on the properties of the first frame. This is alright by it-self and should work with no to little difference to the real file's duration.
The real problem arises when you try to merge two hugely different MP3 files together. Since this library does no re-encode the files it won't change the frames and just simply adds them next to each other trusting the player to read the MP3 frame header for each frame independently of other frames. This is not the case with some players and tools since they tend to ignore each frame property in favor of performance by only reading the properties of the first frame and expecting all other frames to be similar.
This is where your problem with duration arises from and not from a bug or lack of feature in this library. You simply need to provide the library with similar files in terms of properties (bitrate, etc); otherwise, you are leaving the fate of your file in the hand of player's MP3 decoder implementation.
Other issues with hugely different files sewed together via this library and bad player implementations contain, fast or slow-paced playback, error while playing, distorted playback, etc. So make sure your files are as close to each other as possible if the file's portability is something you care about (sharing the file for download maybe) or use a compatible player if it is not (in my tests, Chrome, Firefox and Telegram ware compatible; don't know and don't remember about the others).
This is not possible. There is no implementation of the MP3 codec in PHP. You will need to use an external command-line tool to do this. (Which, depending on your server configuration, you can execute from within PHP as #ceejayoz says.)
See these questions for solutions:
Merging MP3 files in Linux Debian using PHP
What is the best way to merge mp3 files?
If the .mp3 files are just MPEG-1 or MPEG-2 Layer III audio, then the files can just be concatenated. There is no real concept of a header for the whole file. Each frame has a header followed by data, and the file is just comprised of a sequence of frames, which is called the bitstream. The bitrate, stereo mode, etc, do not necessarily have to be the same within a bitstream, so you can concatenate dissimilar files. The Wikipedia article explains this, but I think the spec actually is easier to understand.
ID3 tags, or an other data, within the file (which technically renders it a non-compliant bitstream) may muck things up on the decoder end.
The spec for MPEG-1 and MPEG-2 audio is actually pretty simple. Writing a parser to chunk a file into frames, and then interpreting the headers is not that much work. The last time I did this, it only took an hour or two.
The ID3 spec isn't that complicated either, so I suspect writing some code to strip out the tags before concatenation should be easy, but I have never done this.
The getID3() library (http://getid3.sourceforge.net/) may provide some guidance, too. It has been a while since I have used it, but it may also support opening MP3s and stripping out the ID3 tags already.
HTH
Important things to remember:
The bit rates must match. It's also a good idea to ensure the rate (Hz) and stereo/mono are matched (I used Audacity).
The Content-length header be the length of both files.
Here's a sample from my text-to-speech project. I needed to add a 1 second silence at the end of MP3 audio that was generated dynamically:
$output_audio = textToMP3("Hello World"); // Original audio
$silent_audio = file_get_contents("silence.mp3"); // 1 second silence
$content_length = strlen($output_audio) + strlen($silent_audio);
// Output the audio stream
header('Content-type: audio/mpeg');
header('Content-length: ' . $content_length);
header('Cache-Control: no-cache');
header("Pragma: no-cache");
header("Expires: 0");
echo $audio . $silent_audio;
I have an MP3 file uploader. I want to add an additional audio track to the file upon upload via PHP. Is that possible?
I say "Yes, it's possible".
The following seems to make it seem almost trivial: "How to Merge / Concatenate MP3s with PHP"
(based on comments)
It's not possible, well not directly possible. Not with just PHP.
With PHP you could break up a Mp3 and insert your own little snippet into pauses, but it probably won't sound very good, and if I am thinking correctly will result in lowered audio quality.
To really achieve what you want you would need something inbetween to process the Mp3 files. More than likely it would be a Unix shell script attached to some program or library that can do this, executed by PHP.