How to mix/merge 2 mp3 files in PHP? - php

I need a tool to join 2 mp3 files in 1.
The first file ( background ) will be some sound ( music, submitted by user ),
second file will be a machine (google) speaking text, which was submitted ( by user ).
In output I need a single mp3 file, with background music and speaking robot text playing together.
I can't really find any PHP standalone solution like some library or something like, only shell commands atc.
So are there some libraries?
or there's some unique shell command which works on all OS to combine files?
Or how do I complete the task?

Based off of this question, you should be able to install FFMPEG onto your server (hopefully not a shared host?) and use
//Reduce background volume, assuming it's input2.mp3
shell_exec('ffmpeg -i input2.mp3 -af "volume=0.3" backround.wav');
//Merge the two
shell_exec('ffmpeg -y -i input1.mp3 -i background.wav -filter_complex amerge -c:a libmp3lame -q:a 4 output.mp3');
Then you can simply serve up the output.mp3 file. If this is being performed by PHP running under apache (or other web host, instead of CLI) you'll need to make sure your www-data user has read access to the input files, and write access to the output directory.
All your temporary output, like the background, should be saved as .wav, and only converted back to .mp3 for the final output. Recompressing the audio at each step may result in a very poor final output.
I am making assumptions about how FFMPEG works here, so you may need to consult the documentation for it in order to build a functioning or more efficient set of commands.

You can simply do this
file_put_contents('combined.mp3',
file_get_contents('file1.mp3') .
file_get_contents('file2.mp3'));

Related

diff images between 2 servers

I have 2 servers serv1 and serv2 and need to compare the images in those 2 servers to detect which files are missing or has been modified.
So far I have 3 options:
- Create an API using PHP
I created an API file that will return all the images in serv1/www/app/images/
get the modification time of each images
return the result as json
output is something like this: { 'path/to/file' : 123232433422 }
I fetch that in serv2, decode then merge the array to the images in serv2/www/app/images
get the array_diff, works fine
cons:
- takes a lot of time (fetching, decoding, merging, looping, comparison... )
- Use rsync
Dry run to get the list of images that is existing in serv1 but is missing or modified in serv2 (very fast :))
cons:
apache can't run ssh because it's not authorized to access ~/.ssh/
would need to give apache permission but my client doesn't want it
so in short, i cannot use anything that would require permission
- maybe I could use some library or vendor but I doubt my client would allow me. If it can be shell script or a php built in function, I'll do it as long as it's possible.
So my question is if there is another way to fetch the images and modification date of those images without requiring authentication? My first solution is okay if it can be optimized cause if the array is too large, it takes a lot of time.
I hope the solution can be done in PHP, or Shell script.
Please help give me more options. Thanks
Install utility md5deep (or sha1deep) on both servers.
Execute md5deep on first server and save result to text file:
user#server1> md5deep -l -r mydir > server1.txt
Result file would look like this:
e7c3fcf5ad7583012379ec49e9a47b28 .\a\file1.php
2ef76c2ecaefba21b395c6b0c6af7314 .\b\file2.txt
45e19bb4b38d529d6310946966f4df12 .\c\file3.bin
...
Then, copy file server1.txt to second server and run md5deep in negative matching mode:
md5deep -l -r -X server1.txt mydir
This will print checksums and names of all files on second server which are different from first server.
Alternatively, you can compare text files created by md5deep -l -r dir yourself using diff or similar utility.
Last note - it may be easier to simply run md5deep -l -r mydir | gzip > md5deep.txt.gz in cron on each server, such that you have ready to compare filelist with checksums on each server (gzipped so it is fast to fetch).

PHP Script for FFMPEG conversion

Not been programming for long, so go easy.
Basically I'm attempting to write a PHP script that'll be able to automatically convert a folder full of .mp4's for me, and make them .flv's. This will be done for my entire TV collection (which is quite large) to allow for streaming over my local network within browsers.
I've currently got the following code:
// Save video files into an array
$vid = glob("../../*.mp4");
// Open text file in write mode
$fp=fopen("test.txt","w+");
// Write contents of array to file
foreach($vid as $key => $value){
fwrite($fp,$value."\n");
}
This is taking all of the mp4 files within the folder, and saving their filenames into a text file. The next step I need to take is to read each line, one by one, and perform an FFMPEG command on them until each line has been completed.
Any idea how I can achieve this? I know I'll have to use shell_exec somehow, but I've never used this before, and I'm a little bit stuck as to what to do next.
Thanks for any help
Here is the ffmpeg command line to convert all the mp4 files in a directory to flv files
for i in *.mp4; do ffmpeg -i $i -ar 44100 $i.flv; done
Here it is in php
// Change directory to the directory of the videos
chdir('../..');
// Run the command
exec('for i in *.mp4; do ffmpeg -i $i -ar 44100 $i.flv; done');

Parsing Thumbcache in PHP

I always wondered if it was possible to parse the thumbs db files located in Windows 7 in:
C:\Users\%userdata%\AppData\Local\Microsoft\Windows\Explorer
In Windows XP they used to be located in each folder, but I assume I would have to traverse these to find the directory I want, etc. I'm aware there are ways to generate thumbnails using ffmpeg and such, but want to find a way in PHP to parse that db file since Windows has already generated thumbs for me. It's not in plain text (which I was hoping for).
you could use a parser like vinetto via php's exec
I gave up trying to do parse these out and instead used ffmpeg to generate thumbs like this. The system call takes the 10th frame of the all the mp4 videos in my recordings folder and saves it as a 320x240 image and as the filename.jpg. I had a bunch of videos so I had to increase the max execution time of PHP to handle it.
foreach (glob("F:\\Recordings\\*.mp4") as $filename) {
$path = pathinfo($filename);
system("c:\\ffmpeg\\bin\\ffmpeg.exe -itsoffset -10 -i \"$filename\" -vcodec mjpeg -vframes 1 -an -f rawvideo -s 320x240 \"".$path['filename'].".jpg\"");
}

getting progress for multiple exec() processes realtime

I have a php script that executes ffmpeg and then it starts working. I can execute this script 4 times and spawn 4 processes. I would like to get progress in real time. How do I get and identify which process is which for each output?
$h = fopen('php://stdin', 'r'); $str = fgets($h);
I know that line will get whatever output is in stdin but how do you separate it? How do I continuously poll for output? Once a process is started, how do you access that output on a continuous basis? I know you need ajax but what php method will allow you to access that info and separate it from other processes.
Some have suggested directing output to a text file and getting the contents, but is this the only way? Why keep making more text files for each process? Another suggested redirecting output using 2>&1 | php script.php after the command. This only gets output at the start of the process since the file executes once.
I have been struggling with this for a while and am getting closer, so any expert help would be so appreciated.
See Edit
$process = exec("/usr/local/bin/ffmpeg -i /home/g/Desktop/cave.wmv -deinterlace -acodec libfaac -ab 96k -ar 44100 -vcodec libx264 -s 480x320 -f flv /home/g/Desktop/file.flv")
This is a bit complex. As far as I know exec blocks the PHP thread until it completes. I think ffmpeg can write it's progress to a file. You'd need to parse that file to get the progress. You'll want to call that with Ajax.
You need to figure out how you can get ffmpeg to report it's progress, the rest is easy :P
If only 4 processes should be running at a time, I really see no reason not to create 4 text files and directing the output of ffmpeg into those. After that it's just a question of reading those text files with PHP.
If you intend to make this HTTP operateable, you could create two scripts: start_process.php and process_status.php. The first file would take an ID as input, starting an ffmpeg process, continuously reading its progress and reporting to a MySQL database. process_status.php would take the same ID as input and report the status from MySQL to the user. You could hook that file up to Ajax and get live updates.
You would have to polish the solution with checking for double entry of the same ID, perhaps automatically creating an ID and returning it from start_process.php etc.
You should probably create an array for the four processes. Start your processes with proc_open and slap the returned resource in your array. You could then poll your the array looking at the output for each process resource.
http://us2.php.net/manual/en/function.proc-open.php

mp3 to flv on the server side how to?

I googled it for a long time, all I found was the ffmpeg php api, and a site called mp32tube .. now I was to have the exact same functionality of mp32tube I want to give my users the ability to upload an mp3 add a picture, then compile an FLV on the server that contains the picture and the mp3...
the rest I can do, like uploading the video to youtube, it's simple with their own API ..
can anyone please guide me to something that automatically does this on my server? (a centos powered VPS)
thank you very much.
Rami
You should read FAQ first.
http://www.ffmpeg.org/faq.html#SEC14
then to add sound you may try;
ffmpeg -ar 22050 -ab 128k -i song.mp3 -i videoHaveNoSound.flv VideoWithSound.flv
Let me know the result.
in addition:
you findout a shorter way;
ffmpeg -r 12 -b 1800 -i img.jpg -i yourSound.mp3 -acodec copy outVideo.flv
There is no "automatic" way to do this. You'll have to have the user upload the 2 pieces of data, then run them through ffmpeg. There is tons of documentation for ffmpeg out there, just research the command you'll need to run, test it outside of php first, then once you get it working, implement it in your script. After its gone through ffmpeg, delete the files used for creation, and let them download the resulting flv.

Categories