ffmpeg - convert mkv to mp4 with default subtitle - php

What is best way to convert mkv to mp4, with default subtitle (that mkv have), and keep same quality of video / audio ?
Currently I'm using this command
ffmpeg -y -i filename.mkv -vf subtitles='filename.mkv' -disposition:s default+forced -c:v libx264 -c:a libmp3lame -crf 27 -preset ultrafast filename.mp4
But the command still not perfect, the mkv have better quality than mp4 generated. Any advise?
Thanks

your preset is lowest possible quality, and crf could be lower, 18 is more or less lossless, this will make the transcoding slower. of course
So suggest -crf 18 and -preset slow
If you aren't bothered about which codecs you use you could just copy everything into the mp4 container, which would be megaquick

Related

ffmpeg reducing the qualitu of photos

I am using ffmpeg to convert photos to video and i am pretty successfull so far.
However I am facing quality issue.
$command1="ffmpeg -r 1/1 -pattern_type glob -i 'pics/*.jpg' -vf \"pad=ceil(iw/2)*2:ceil(ih/2)*2\" finalPics/video.mp4";
exec($command1);
What is wrong with the command as video quality is really reducing the quality of images
Try using
ffmpeg -r 1/1 -framerate 25 -pattern_type glob -i 'pics/*.jpg' -c:v libx264 -profile:v high -crf 20 -pix_fmt yuv420p pics/video.mp4

Reduce file size of ffmpeg converted video

I have a .mp4 video with a file size of 540kb and a duration of 30 seconds before it was converted, but when I use ffmpeg to convert it to the file size became 21mb. What options do I need to add inorder to reduce the file size to less than 1mb?
ffmpeg command I am using right now:
video_filename = __DIR__. '/uploads/VID.mp4';
exec('ffmpeg -i '.$video_filename.' -c:v libx264 '.$video_filename.'');
Create tmp_dir in the desired location
exec('ffmpeg -i '.$video_filename.' -c:v libx264 -crf 25 tmp_dir'.$video_filename.'');
exec('rm -rf '. $video_filename);
exec('mv tmp_dir/'.$video_filename.' ..');
I hope it will work properly, I haven't test it!.

PHP/FFMPEG - why does my video conversion result in empty file?

I'm trying to convert a video that lives on my server from a .webm to a .mp4.
shell_exec('ffmpeg -i file.webm output.mp4');
However, this results in an empty mp4 (0 bytes - or, sometimes, and very weirdly, 28 bytes.) The input file exists, and is 45MB.
This answer recommended explicitly copying the input codec, but same result.
shell_exec('ffmpeg -i file.webm -vcodec copy -acodec-copy output.mp4');
What am I doing wrong?
[ ===== EDIT ===== ]
After trying a few more things, inspired by the comments, I'm still having no joy converting to MP4.
It seems I'm running FFMPEG v.2.8.15. This seems quite a lot lower than the current release of 4~, however I only installed this a week or so ago so I'm not sure why this is the case and I don't know how to update it (I'm on WHM Cpanel.)
Anyway, my problem is NOT to do with pathing, because the same command works fine if I change .mp4 to .webm - I get a successfully converted .webm file.
But when I run:
$foo = shell_exec('ffmpeg -i file.webm -vcodec copy -acodec copy output3.mp4 -report');
...I get this FFMPEG log output.
I've also tried:
shell_exec('ffmpeg -fflags +genpts -i file.webm -r 24 KKK.mp4 -report');
...from this answer, and
shell_exec('ffmpeg -i file.webm -c:v copy III.mp4');
...from this article.
Both result in the same problem, i.e. an 0-bytes .mp4 file.
Problem
You're trying to mux VP9 video and Opus audio into the MP4 container. Currently, muxing Opus into the MP4 container is considered experimental and requires -strict experimental (or -strict -2), but your ffmpeg is too old to support that. Download a new version.
Solutions
Do not mux typical WebM formats (VP9 or VP8 + Opus or Vorbis) into MP4. You can re-encode it to H.264 (or H.265) with AAC audio if you want a more common set of formats for MP4:
ffmpeg -i input -c:v libx264 -c:a aac -movflags +faststart output.mp4
Or upgrade your ffmpeg and add the -strict experimental (or -strict -2) output option to your command if you know you want VP9 + Opus in MP4:
ffmpeg -i input -c copy -strict experimental -movflags +faststart output.mp4
Or don't re-mux into MP4 in the first place. HTML5 video supports VP9 + Opus in WebM so just use the original file if it is supported by your target browser(s).

How can I limit ffmpeg memory usage

I am using ffmpeg to convert a 1080p video to MP4 using this command in PHP.
$command = FFMPEG.' -i ' . $src . ' -sameq -strict -2 -vcodec libx264 -ar 22050 -y ' . $dest.'.mp4 2>&1';
exec($command,$output,$status);
The problem is that the process uses a lot of memory ~1600MB, which is not allowed by my server so ffmpeg gets terminated. Can I limit the memory usage of ffmpeg to about 600-700MB?
Any help is greatly appreciated...
It's not about PHP. It's about how to limit FFMPEG memory usage.
Short answer no!
Look here: http://hwdmediashare.co.uk/forum/27-development-customisation/54700-limit-ffmpeg-memory-usage
It would be the video codec which is mainly responsible for the high memory use.
So it's the encoder whose memory use needs to be addressed, not FFmpeg directly. I'm not sure how to fix x264's memory use, but I tried the newer x265 and in my case it's only using 1.6 GB, while libx264 was failing by asking more than the 2 GB memory limit (per process, on 32-bit systems).
So, what worked for me was to use:
ffmpeg -i input -pix_fmt yuv420p -c:v hevc -x265-params crf=23 out.mp4
(Omitting parameters to take care of the audio.)
But the general approach is to try other encoders. I was going to try mpeg4 and vp9 if x265 didn't work, maybe others. If none of that works, then further options include looking at the encoders' settings (though nothing obvious and directly relevant to memory use shows up):
ffmpeg -h encoder=mpeg4
Update: actually, it turned out that YouTube doesn't accept HEVC (aka H.265) yet (and it only let me know after the upload finished). So, like I suggested above, I went for VP9, doing a pilot run with the first 50 frames this time. I used settings similar to a guide I found (the Constant quality settings, though I should have used more of their suggested parameters):
ffmpeg.exe -i <input> -pix_fmt yuv420p -c:v libvpx-vp9 -pass 1 -b:v 0 -crf 20 -f webm pass1.webm
ffmpeg.exe -i <input> -pix_fmt yuv420p -c:v libvpx-vp9 -pass 2 -b:v 0 -crf 20 -f webm pass2.webm
(Note that pass1.webm will be almost empty.)
Also note that two passes are preferred whenever possible. It's better on all fronts, including faster encoding overall.
With these settings, a 73-second clip at 4K resolution took about 16 hours to encode — that's using one core, as I forgot to specify -threads. While slow, FFmpeg's memory use only went up to about 0.6 GB. The resulting file was 300 MB, and I can't see any loss of quality compared to uncompressed frames (so -crf 20 might have been a bit too low).
The truth is video encoding a CPU and memory intensive job. If you want to do it you need to give the requisite memory for it.
Since you want to convert a 1080p .mov to a .mp4 of same quality I am assuming you jsut want to change the format of the file and not reencode.
ffmpeg -i input.mov -acodec copy -vcodec copy out.mp4
will do it in a jiffy and without any of the memory overheads
If you want your audio codec only changed don't give the acodec part.
If the input video codec does not work for you [so copy is not an option] try doing mpeg4 encoding for vcodec. Cheaper to encode there but I cannot assure you it will fit in your memory requirements always.

ffmpeg compresses upto 32 kbps only

I have created a PHP code which compresses mp3 while uploaded to 32kbps bit rate I have referred this thread
How to compress or convert to low quality Mp3 file from PHP
used this code
exec("ffmpeg -i inputfile.mp3 -ab 24000 outputfile.mp3")
but the problem is I can't compress more than 32kbps .my code instruct to compress up to 24kbps but after execution, I can see the output file is 32kbps. can anyone tell what should I do so that I can compress more than 32kbps .or is there any limitation of ffmpeg ??
The reason you cant achieve lower then 32kbps is because of the sample rate most likely is still 44100-Hz meaning larger stream size, you have a few options 44100-Hz, 22050-Hz, and 11025-Hz as valid frequency's.
Try (very low quality):
ffmpeg -i inputfile.mp3 -acodec libmp3lame -b:a 8k -ac 1 -ar 11025 outputfile.mp3
-b:a = audio bitrate
-ar = sample rate

Categories