ffmpeg convert any user video file to run on mobiles h264 mp4 - php

So, i have kind of accepted this task on work but im really not sure if its possible.
We are going to build a website where users can upload videos from their computers and mobile phone browsers. The video files can be a large range of aspect ratios, width, height, codex and file formats.
I will have access to ffmpeg from php exec command on a web server.
Is it possible to use this to convert the user files to one file format that works on computers, android and iphone.
The requirements is that we can set a max width, to witch the video will be scaled, dynamically to match height.
Does anyone know is this can be done, and be done in a reasonable amount of time. Will do project on 2 days. And if so some pointers in the right direction would be nice.

Had the same problem but solved by using HandBrake the open source video transcoder
https://handbrake.fr/

If your target can only be one file format, then I would choose mp4 baseline. (However some browsers won't play it, which is why the html tag offers multiple source flags, which usually include webm and ogg video...)
Using ffprobe -show_streams $uploadedFile you can get the dimensions (and aspect ratio) of the file. Using math you can get the new dimensions based on your needs.
$newDim=$new_width.":".$new_height;
$output = shell_exec("/usr/bin/ffmpeg -i $uploadedFile -f mp4 \
-c:a libfdk_aac -b:a 128k -c:v libx264 -vprofile baseline \
-movflags faststart -vf scale=$newDim $output");```
Here is the breakdown:
f mp4 > format mp4
c:a libfdk_aac > audio codec
c:v libx264 > video codec
vprofile baseline > minimal codec usage for mobile
movflags faststart > put the moov atom at the beginning of file
$output > should have '.mp4' as a file ending
Of course the devil is in the details (and the number of processing cores you can throw at an online converter), but this will get you up and running at least.
Edit: Actually answered the question. :)
By the way, ffmpeg does offer the vf flag: -vf scale=320,-1, but sometimes it gives you a dimension not divisible by 2 which throws an error in x264 encoding. Its better to do the math yourself.

Related

Convert video from FFMPEG than video is rotated [duplicate]

When I try to upload videos captured from my iPhone in my app, the server performs a conversion from .mov to .mp4 so that it can be played in other platforms. However the problem is that when I shoot the video (in portrait orientation) and it is converted (using ffmpeg) and then played back from the server, it appears to be rotated. Any idea?
FFMPEG changed the default behavior to auto rotate video sources with rotation metadata in 2015. This was released as v2.7.
If your ffmpeg version is v2.7 or newer, but your rotation metadata isn't respected, the problem is likely that you are using custom rotation based on metadata. This will cause the same logic to be applied twice, changing or cancelling out the rotation.
In addition to removing your custom rotation (recommended), there's an option to turn off auto rotation with -noautorotate.
ffmpeg -noautorotate -i input.mp4...
This will also work in some older releases.
For sake of completeness, the reason this is happening is that iPhones only actually capture video in one fixed orientation. The measured orientation is then recorded in Apple-specific metadata.
The effect is that Quicktime Player reads the metadata and rotates the video to the correct orientation during playback, but other software (e.g., VLC) does not and shows it as oriented in the actual codec data.
This is why rotate=90 (or vflip, or transpose, or etc.) will work for some people, but not others. Depending on how the camera is held during recording, the rotation necessary could be 90, 180, or even 270 degrees. Without reading the metadata, you're just guessing at how much rotation is necessary and the change that fixes one video will fail for another.
What you can also do is remove the QuickTime specific metadata when rotate the .mov.
This will make sure that the video is rotated the same way in VLC and QuickTime
ffmpeg -i in.mov -vf "transpose=1" -metadata:s:v:0 rotate=0 out.mov
Here's the documentation on the -metadata option (from http://ffmpeg.org/ffmpeg.html):
-metadata[:metadata_specifier] key=value (output,per-metadata)
Set a metadata key/value pair.
An optional metadata_specifier may be given to set metadata on streams or chapters. See -map_metadata documentation for details.
This option overrides metadata set with -map_metadata. It is also possible to delete metadata by using an empty value.
For example, for setting the title in the output file:
ffmpeg -i in.avi -metadata title="my title" out.flv
To set the language of the first audio stream:
ffmpeg -i INPUT -metadata:s:a:1 language=eng OUTPUT
Depending on which version of ffmpeg you have and how it's compiled, one of the following should work...
ffmpeg -vf "transpose=1" -i input.mov output.mp4
...or...
ffmpeg -vfilters "rotate=90" -i input.mov output.mp4
Use the vflip filter
ffmpeg -i input.mov -vf "vflip" output.mp4
Rotate did not work for me and transpose=1 was rotating 90 degrees
So - I too ran into this issue, and here my $0.02 on it:
1.) some videos DO have Orientation/Rotation metadata, some don't:
MTS (sony AVHCD) or the AVIs I have - DO NOT have an orientation tag.
MOVs and MP4s (ipad/iphone or samsung galaxy note2) DO HAVE it.
you can check the setting via 'exiftool -Rotation file'.
My videos often have 90 or 180 as the rotation.
2.) ffmpeg - regardless of the man-page with the metadata-tag, just doesn't EVER seem to set it in the output file. - the rotation-tag is ALWAYS '0'.
it correctly reports it in the output - but it's never set right to be reported by exiftool. - But hey - at least it's there and always 0.
3.) rotation angles:
if you want rotate +/- 90: transpose=1 for clockwise 90, 2 ccw
now if you need 180 degree - just add this filter TWICE.
remember - it's a filter-chain you specify. :-) - see further down.
4.) rotate then scale:
this is tricky - because you quickly get into MP4 output format violations.
Let's say you have a 1920x1080 MOV.
rotate by 90 gives 1080x1920
then we rescale to -1:720 -> 1080*(720/1920) = 405 horiz
And 405 horizontal is NOT divisable by 2 - ERROR. fix this manually.
FIXING THIS automatically - requires a bit of shell-script work.
5.) scale then rotate:
you could do it this way - but then you end up with 720x1280. yuck.
But the filter-example here would be:
"-vf yadif=1,scale=-1:720,transpose=1"
It's just not what I want - but could work quite OK.
Putting it all together: - NOTE - 'intentionally WRONG Rotation-tag', just to demonstrate - it won't show up AT ALL in the output !
This will take the input - and rotate it by 180 degree, THEN RESCALE IT - resetting the rotation-tag. - typically iphone/ipad2 can create 180deg rotated material.
you just can leave '-metadata Rotation=x' out the line...
/usr/bin/ffmpeg -i input-movie.mov -timestamp 2012-06-23 08:58:10 -map_metadata 0:0 -metadata Rotation=270 -sws_flags lanczos -vcodec libx264 -x264opts me=umh -b 2600k -vf yadif=1,transpose=1,transpose=1,scale=1280:720 -f mp4 -y output-movie.MP4
I have multiple devices - like a settop box, ipad2, note2, and I convert ALL my input-material (regardless whether it's mp4,mov,MTS,AVI) to 720p mp4, and till now ALL the resulting videos play correct (orientation,sound) on every dev.
Hope it helps.
For including into web pages my portrait-format videos from iPhone, I just discovered the following recipe for getting .mp4 files in portrait display.
Step 1: In QuickTime Player, Export your file to 480p (I assume that 720p or 1080p would work as well). You get a .mov file again.
Step 2: Take the new file in QT Player, and export to “iPad, iPhone…”. You get a .m4v file.
Step 3: I’m using Miro Video Converter, but probably any readily-available converter at all will work, to get your .mp4 file.
Works like a (long-winded) charm.
I've filmed the video with Ipad3 and it was oriented upside down, which I suppose is the common situation of all Apple devices at some versions. Besides of it, the 3-minutes long MOV file (1920x1090) took about 500 Mb in size, which made it not available to share easily. I had to convert it to MP4, and analyzing all threads I've found on stackoverflow, here's the final code string for ffmpeg I've used (ffmpeg ver. 2.8.4):
ffmpeg -i IN.MOV -s 960x540 -metadata:s:v rotate="0" -acodec libmp3lame OUT.mp4
I suppose you may just leave '-metadata:s:v rotate="0"' if you don't need the resize and audio codec change. Note that if you resize the video, width and height should fully divide to 4.
Although the topic is old.
Hope this will help some one:
Get ffmpeg latest version : https://www.ffmpeg.org/download.html
The command that worked for me (to flip 180 degrees):
ffmpeg -noautorotate -i input.mp4 -filter:v "rotate=PI" output.mp4
When the degrees are determined by -filter:v "PI/180*degrees"
for example
-filter:v "45*PI/180" for 45 degrees
A nice explanation is here
https://superuser.com/questions/578321/how-to-rotate-a-video-180-with-ffmpeg
Or... to simply change the tag in an existing file:
Read the current rotation
exiftool -Rotation <file>
then, for example:
exiftool -Rotation=180 <file>
to set it to 180

different video format supported by html and major browsers

hello all i am building a video hosting site and wanted to know what are the video formats which my php code should convert the user's video so that all the major browsers support the file.
by searching on internet i got to know that mp4,swf,avi,ogg are the formats but if i convert one video to all these formats then there will be 4 times the space of a single video and also there will be server load and time consuming process for the conversion.
so i was wondering if there is one or two formats which i should take with me so to reduce the server load and conversion time.
i am converting the video by this code (ffmpeg)
if (move_uploaded_file(#$_FILES['profileimage99']['tmp_name'], $uploadfile)) {
$base = basename($uploadfile, $safe_file['ext']);
$new_file = $base.'flv';
$new_image = $base.'jpg';
$new_image_path = $live_img.$new_image;
$new_flv = $live_dir.$new_file;
require 'vendor/autoload.php';
//ececute ffmpeg generate flv
exec('ffmpeg -i '.$uploadfile.' -f flv -s 768x432 '.$new_flv.'');
//execute ffmpeg and create thumb
exec('ffmpeg -i '.$uploadfile.' -f mjpeg -vframes 71 -s 768x432 -an '.$new_image_path.'');
also please tell me will it be good to use exec in php code ??
The most common web video formats are WebM, OGG, and MP4 with MP4 being supported in IE, Chrome, Safari, Opera, and FireFox.
Therefore, it would be prudent to stick with MP4.

FFMPEG compressed MP4 video not playing on Mozilla Firefox with a "file is corrupt" error

I have compressed MP4 video using FFmpeg in a PHP environment. Videos are being compressed, but they are not playing in Firefox, showing an error:
Video can't be played because the file is corrupt
while this video is playing fine in VLC media player and also in the Chrome browser. My code of compression is as-
exec("ffmpeg -i input.mp4 -acodec mp2 output.mp4");
I struggled with this problem until I discovered this gist entitled 'ffmpeg convert gif to mp4, for best cross browser compatibility'. It uses this command:
ffmpeg -f gif -i FOO.gif -pix_fmt yuv420p -c:v libx264 -movflags +faststart -filter:v crop='floor(in_w/2)*2:floor(in_h/2)*2' BAR.mp4
It has these notes on how it works:
output mp4 is encoded with h264, support Firefox/Chrome/Safari in Windows, Mac OSX, Android, and iOS.
one mp4 file for all platforms, there is no need to encode an extra webm movie, which encoding speed is pretty slow.
format as yuv420p for Firefox compatibility, the downside is color becomes less-saturate than original gif.
yuv420p only support even width/height, so crop filter is required
-movflags +faststart flags are optimized for online view in browser
compression ratio typically 10:1, pretty awesome. note that if original gif is < 512KB, convert as mp4 is less efficient.
Incorporating that into my ffmpeg command, I find that the videos now run in Firefox, Safari, Opera and QuickTime (where previously only Chrome and VLC worked for me).
Credit to ingramchen, who wrote the gist.
I know this is a few months old, but in case anyone is still intereste: I had this same thing happen and I found it was because my MP4s were encoded in "MPEG-4 Simple profile" a.k.a. H.263/MPEG4 part 2/xvid. These formats are not supported for playback in most browsers any more.
Transcoding the files to H.264 fixed the problem.

How to reduce the file size during conversion of video from any video to mp4 using ffmpeg &mp4box in PHPmotion?

I am using ffmpeg & mp4box in my PHPmotion site to convert videos to mp4 format. When I convert a 50MB video to mp4, the file size remain same. So Its affecting the video streaming in my site. So I want to reduce the file size of the video in conversion. This is my code example, that I've used the site for converting m4v videos in PHPmotion.
$ffmpeg_cmd2_2 = "$config[path_to_ffmpeg] -i $raw_video_path -vcodec libx264 -vpre veryfast -crf 15 -b 5120000 -threads 0 -acodec libfaac -ac 2 -ab 128k -ar 44100 -f mp4 $new_flv_1";
$mp4box_cmd = "$mp4box_path -add $new_flv_1 $new_flv_2"
When I use this command,it converts the m4v file to mp4 format, but the filesize doesn't change. What command I should use in this to reduce the filesize during video conversion in PHPmotion? Can anyone write a ffmpeg command to reduce the filesize during conversion ?
There are two main factors involve in reducing the size of mp4 video
i: width and height of video, greater their widths, greater will be size and slower will be streaming e,g 360p, 480p, 720p, 1080p
ii: video bitrate, greater will be their bitrate, higher will be quality, size and slower will be their streaming.
For faster streaming i recommend using
i: 480x360 or lower width and height of video
ii: -b value 360k or lower.
iii: -ab value 64k (optional)
Hope this will help you.
Apart from using smaller video frame size, you need to use higher crf value to achieve bitrate reduction while maintaining good video quality.
Replace this
-crf 15 -b 5120000
with
-crf 22

using FFMPEG to convert to MP4 with maximum browsers compatibilty

I'm converting from WMV to FLV using FFMPEG, and my problem is that the FLV videos are so big! the 15 minutes video's size ranges between 150MB and 1GB!
I'm using the following FFMPEG command to convert and split WMV videos :
nohup nice -1 ffmpeg -y -ss 00:00:00 -t 00:15:00 -async 1 -i INPUT.WMV -acodec libmp3lame OUTPUT.FLV
And I've tried converting to MP4 before and the video size was much smaller than the FLV video.
So my questions are:
Would the MP4 videos have any
compatibility issues browsers?
Would it work on iPhone, iPad? (I
know FLV videos doesn't work on
iPhones or iPads)
What is the best FFMPEG command to
convert to MP4 without losing the
quality of the video?
A few points...
Video size has to do with the bit rate, dimension, and codec. It does not have anything to do with the container.
You can certainly expect 15 minutes of video to be large, assuming you want more than a postage stamp for viewing area. This is normal.
Any time you re-compress something, you are going to lose quality. There is no way around this. You might be able to keep most quality by recompressing at a higher bitrate, but this defeats what you are trying to accomplish.
Bottom line, unless you need to, don't do it. Simply encode your videos at the appropriate bitrate to begin with.
For converting any video to mp4, use:
ffmpeg.exe -i INPUT.wmv -vcodec libx264 -sameq OUTPUT.mp4
If the quality is too low on that then set the bitrate to be around what you want:
ffmpeg.exe -i INPUT.wmv -vcodec libx264 -b 500k OUTPUT.mp4
The output mp4 file plays in Flash, browsers that support H.264 MPEG4, iOS, and Android.

Categories