light_compressor icon indicating copy to clipboard operation
light_compressor copied to clipboard

Compression quality: can we add more detailed settings?

Open delfme opened this issue 1 year ago • 1 comments

Hello, We are testing the plugin and like it very much.

However, to get better results for our use case, we would need to set compression options.

For example, let's us consider an input File with size: 13.66MB

  • On iOS, FFMPEG is fast: result is 3.96MB in 2.5 sec, which is our reference With veryfast preset and below settings for -g and -r String command = "-i $_filePath -c:v libx264 -crf 23 -preset veryfast -g 12 -r 25 $outputPath";

  • On Android (mid-end phone) , it performs poorly, mostly due to Dart: 5.81MB in 6.39 sec

  • On Android with LightCompressor, we get better results than FFMPEG:

medium quality: 4.76MB 
compression time: 4.3 sec

high quality:: 6.10MB
compression time: 4.5 sec

For this specific case, we would like to get about 3,5-4MB in 2.5-3sec and we think this would be possible if we had a way to set compression options. Can you please add this feature?

delfme avatar Nov 08 '23 13:11 delfme

I just compared FFmpeg and Swift native on macOS and FFmpeg is on average 10X slower for video compression. I was using media_tool_flutter which is a little faster than light_compressor in my tests.

@delfme, do you have better results or why you avoid the native iOS version?

starkdmi avatar Dec 15 '23 21:12 starkdmi

@starkdmi sorry this got lost. Isn't https://github.com/starkdmi/media_tool_flutter slow on android due to lack of native implementation?

delfme avatar Sep 29 '24 07:09 delfme

@starkdmi for us ffmpeg is slow only on android, it depends on the command you are using to compress video.

delfme avatar Sep 29 '24 07:09 delfme

@delfme yes, media_tool supports ios/mac only as for now, ffmpeg was a temporary fix for other platforms but no real demand here. As for compression options of light_compressor package, isn't videoBitrateInMbps sufficient for your case? If you are using ffmpeg I suggest you to try hevc_mediacodec and hevc_videotoolbox codecs for hardware accelerated encoding.

starkdmi avatar Sep 29 '24 08:09 starkdmi

Yes indeed this was our workaround. But we noticed that the compressed video are not loaded quicly from player (kind of something corrupting the idea). We tested with the same file uncompressed and compressed and the compressed one needs 3-4sec to initialize.

What performance are you achieving on android with ffmpeg and hevc_mediacodec and hevc_videotoolbox codecs? Can you please write here how to use the codecs? This is our command: String command = "-i $_filePath -c:v libx264 -crf 23 -preset veryfast -g 12 -r 25 $outputPath";

delfme avatar Sep 29 '24 12:09 delfme

@delfme, to try those codecs:

  • Android: h264_mediacodec, hevc_mediacodec
  • Apple: h264_videotoolbox, hevc_videotoolbox

Use:

ffmpeg -hide_banner -loglevel error -i $_filePath -c:v h264_videotoolbox -crf 23 -preset veryfast -g 12 -r 25 -movflags +faststart $outputPath
ffmpeg -hide_banner -loglevel error -i $_filePath -c:v hevc_videotoolbox -tag:v hvc1 -crf 28 -preset veryfast -g 12 -r 25 -movflags +faststart $outputPath

For HEVC add -tag:v hvc1, and use crf about 28 for same quality as H.264 with 23.

For faster playback start time you can try adding -movflags +faststart. Try running ffmpeg -i input.mp4 -c copy -movflags +faststart output.mp4 on compressed files to see if -movflags +faststart helps with yours 3-4 sec delay.

Note that hardware accelerated codecs could provide worse results, and aren't always faster but more efficient, adjust your quality if needed.

starkdmi avatar Sep 29 '24 13:09 starkdmi

Thx will try those ones. Did you try unltrafast without r and g, and crt 28? It is fast on our side.

String command = "-i $_filePath -c:v libx264 -crf 28 -preset ultrafast $outputPath";

delfme avatar Sep 29 '24 17:09 delfme

@delfme ultrafast produce larger files, I prefer default presets, you could just lower quality for playback on mobiles (via crf). There is also libx265 for you to try. I do not use g (keyframe interval), r (frame rate) under 30 is a good choice (excluding slo-mo).

starkdmi avatar Sep 29 '24 18:09 starkdmi