FFMPEG Creates blurry video

2.5k views Asked by At

With this library https://github.com/tanersener/mobile-ffmpeg, I am using FFMPEG on iOS. I am trying to create a video from audio, with its relevant waveform, background and a logo image added.

let command = "-i \(audioPath) -i \(imagePath) -filter_complex \"[0:a]showwaves=s=hd720:mode=line: colors=0x666666|0x555555[v];[1:v]scale=hd720[bg];[bg][v]overlay=shortest=0:main_h-overlay_h-35[outv]\" -shortest -map '[outv]' -map 'a' -c:a aac -f mp4 \(videoPath)"

With the above command, I am creating a video that has the audio, waveform and a background image.

let artworkCommand = "-y -i \(videoPath) -i \(artworkPath) -filter_complex \"[1:v][0:v]scale2ref=200:200[logo1][base];[base][logo1]overlay=20:20[v]\" -map \"[v]\" -map 0:a -y -codec:a copy \(artVideoPath)"

With the second command, I am adding a logo image on top-left corner.

When I execute these commands directly on terminal, the output video is of high quality and has no issues. But when I try the same commands on iOS device, after the first second of the video, it becomes blurry.

It looks like it is becoming blurry this way when I execute the first command itself. Can anyone point some light on why this is happening? TIA.

Update 1 Log - https://www.dropbox.com/s/ev8gw8bvfe1m7ur/Logs_FFMPEG.rtf?dl=0

Update 2 I modified both the commands to include the bitrate, as suggested. It has improved the video, but still now and then it blurs out.

let command = "-i \(audioPath) -i \(imagePath) -filter_complex \"[0:a]showwaves=s=hd720:mode=line: colors=0x666666|0x555555[v];[1:v]scale=hd720[bg];[bg][v]overlay=shortest=0:main_h-overlay_h-35[outv]\" -shortest -map '[outv]' -map 'a' -c:a aac -b:v 2M \(videoPath)"
let artworkCommand = "-y -i \(videoPath) -i \(artworkPath) -filter_complex \"[1:v][0:v]scale2ref=200:200[logo1][base];[base][logo1]overlay=20:20[v]\" -map \"[v]\" -map 'a' -c:a aac -b:v 2M \(artVideoPath)"

Demo for both commands executed on iOS device - https://www.dropbox.com/s/6ux4obufb0eiax6/video1x1_art.MP4?dl=0

Logs - https://www.dropbox.com/s/cjm259oehd048xb/Logs2.rtf?dl=0

1

There are 1 answers

0
llogan On BEST ANSWER

Old encoder is being used

Your ffmpeg on iOS does not have a H.264 or H.265/HEVC video encoder enabled. For example, --enable-libx264 is missing from your configure line. So by default for MP4 output ffmpeg uses the encoder named mpeg4. This encoder outputs an older legacy video format: MPEG-4 Part 2.

  • mpeg4 can made a good quality output, but it needs much more bitrate than a more modern encoder such as libx264.

  • MPEG-4 Part 2 video is not supported by HTML5 video and has less support on modern devices.

On iOS use ffmpeg that supports a modern encoder for the format you need.

Generation loss

You are encoding twice when you only need to encode once. This is causing generation loss. Do everything in one command:

let command = "-i \(audioPath) -i \(imagePath) -i \(artworkPath) -filter_complex \"[0:a]showwaves=s=hd720:mode=line: colors=0x666666|0x555555[v];[1:v]scale=hd720[bg];[bg][v]overlay=shortest=0:main_h-overlay_h-35:format=auto[bg];[2]scale=200:200[fg];[bg][fg]overlay=20:20:format=auto,format=yuv420p[outv]\" -shortest -map '[outv]' -map 0:a -c:a aac -movflags +faststart -f mp4 \(videoPath)"

Other changes:

  • I saw no reason for you to be using the scale2ref filter so I changed it to the scale filter for simplicity.
  • I added the format option to the overlay filters which can improve quality.
  • The format filter was then added to ensure yuv420p pixel format for max player compatibility.
  • -movflags +faststart was added to enable fast start playback.