Skip to content

RESOURCES / BLOG

What’s the best way to convert video formats?

Every week, developers swap tips about wrangling video files for the web, mobile apps, and OTT. One thread might celebrate a tiny WebM file, another might complain that a MOV won’t play in a certain browser, and a third debates quality vs speed when transcoding. If you are trying to ship video reliably, the choices of container, codec, and tooling matter a lot.

Hi folks,


I’m preparing videos for web and mobile and keep running into compatibility and size issues. I have source files in MOV, MP4, and sometimes MKV. I want a practical approach that balances quality, file size, and speed and works across browsers and devices.


What’s the best way to convert video formats? What formats and settings should I target, and how do I automate the process for a batch of files?

Converting video efficiently boils down to picking the right container and codec for your audience, then automating with a robust toolchain. For most web delivery, MP4 with H.264 video and AAC audio is the safe default. Add a WebM VP9 variant for better compression in Chrome and Firefox when you can.

  • MP4 H.264 + AAC: max compatibility for browsers, iOS, older devices. 
  • WebM VP9 + Opus: smaller files at similar quality; great for Chrome and Firefox.
  • MOV: excellent as a source or editing format, but not ideal for web delivery.
  • When in doubt, generate at least MP4 H.264 and optionally WebM VP9.

FFmpeg is the go-to CLI for batch workflows and CI. It is flexible and lets you control quality, bitrate, and codecs precisely. If you want a guide on its strengths and tradeoffs, check out FFmpeg features and pros/cons.

ffmpeg -i input.mov -c:v libx264 -preset medium -crf 23 \
  -c:a aac -b:a 128k -movflags +faststart output.mp4Code language: CSS (css)
  • Use CRF 18 to 23 for quality targeting. Lower CRF is higher quality and larger files.
  • Preset trades encoding time for compression efficiency. Try fast, medium, or slow.
  • +faststart moves metadata to the front for quicker playback start on the web.
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 0 -crf 33 -row-mt 1 \
  -c:a libopus -b:a 96k output.webmCode language: CSS (css)
  • Set -b:v 0 with CRF to quality-target VP9. CRF 28 to 34 is a good starting range.
  • -row-mt enables multi-threaded VP9 encoding for speed on modern CPUs.

ffmpeg -i input.mov -c copy output.mp4

This simply changes the container. It only works if the streams are already compatible with the target container.

# Bash example: convert all MOV files to MP4
for f in *.mov; do
  ffmpeg -i "$f" -c:v libx264 -preset medium -crf 22 -c:a aac -b:a 128k \
    -movflags +faststart "${f%.*}.mp4"
doneCode language: PHP (php)
  • Resolution: Match your target display. Consider creating 1080p and 720p variants.
  • Keyframes: Set around 2 seconds for streaming friendliness, for example -g 48 at 24 fps.
  • Audio: AAC 96 to 160 kbps is fine for most content, Opus at 64 to 96 kbps is efficient.
  • Testing: Validate playback on Chrome, Firefox, Safari, iOS, and Android.

After you have a reliable encoding recipe, you can offload conversion and delivery to Cloudinary so you do not manage infrastructure or CDNs yourself.

const cloudinary = require('cloudinary').v2;

cloudinary.config({
  cloud_name: 'demo', api_key: 'key', api_secret: 'secret'
});

cloudinary.uploader.upload('input.mov', {
  resource_type: 'video',
  eager: [
    { format: 'mp4', transformation: [{ video_codec: 'h264', audio_codec: 'aac' }] },
    { format: 'webm', transformation: [{ video_codec: 'vp9', audio_codec: 'opus' }] }
  ],
  eager_async: true
}).then(console.log).catch(console.error);Code language: JavaScript (javascript)

You can also request formats via URL when delivering:

https://res.cloudinary.com/demo/video/upload/f_mp4,vc_h264,q_auto/sample
https://res.cloudinary.com/demo/video/upload/f_webm,vc_vp9,q_auto/sample

This approach simplifies A/B testing different settings, reduces origin load, and leverages global caching.

  • Local FFmpeg: Maximum control, offline pipelines, CI jobs, or custom presets.
  • Cloud-based: Scale, auto-derivatives, easy delivery, and simpler client integration.
  • Play your outputs in target browsers and devices.
  • Check file size vs visual quality at your typical bitrates or CRF values.
  • Ensure fast start for web playback and reasonable keyframe spacing.
  • Create MP4 H.264 + AAC for universal compatibility and add a WebM VP9 variant for better compression.
  • Use FFmpeg with CRF targeting and appropriate presets for quality and speed.
  • Automate batch jobs and validate on common browsers and devices.
  • Offload conversion and delivery to Cloudinary if you want simple, scalable pipelines with on-the-fly formats.

Ready to streamline video conversion and delivery at scale? Sign up for Cloudinary free and start transforming and delivering optimized video in minutes.

Start Using Cloudinary

Sign up for our free plan and start creating stunning visual experiences in minutes.

Sign Up for Free