Yfli Yfli
dev · Updated on · 0 views
Written by
Yfli
Yfli

Stop Switching to HandBrake — We Built FFmpeg Into Our App

Why should you need a separate app just to convert your recording to MP4? We integrated a 10-year FFmpeg pipeline directly into Yfli Screen Recorder — here's the architecture, the trade-offs, and why we couldn't do it all in real time.

Yfli Screen Recorder is a macOS app for screen recording, audio recording, and subtitle generation. Recently we integrated an FFmpeg-based format conversion pipeline directly into the app — so you can export to whatever format you need without ever launching a second tool. This is the story of why we built it, how it works, and what broke along the way.

The Step Everyone Hates But Nobody Fixes

The standard Mac recording workflow is three steps too long:

  1. Record your screen → get a massive .mov file
  2. Open HandBrake (or Permute, or some online converter), pick a format, tweak the settings, wait
  3. Now you have two files — the original .mov and the converted output

If you record once a month, this is a minor annoyance. If you record tutorials, demos, or meetings every day, it adds up to a lot of wasted time — and a lot of disk space eaten by duplicate files.

So the question is simple: why can’t the recording app just export the format you wanted in the first place?

It’s not that it’s technically impossible. It’s that recording and format conversion run on two fundamentally different pipelines.

Real-Time Recording vs. Offline Conversion — Same Engine, Opposite Constraints

The Recording Pipeline

ScreenCaptureKit / AVCaptureScreen
  → raw video frames (CVPixelBuffer)
  → VideoToolbox hardware encoder (H.264 / H.265)
  → .mov or .mp4 container
  → real-time disk write

This is the core of any screen recorder. The non-negotiable constraints:

  • Must run in real time — dropped frames are unacceptable. Encoding speed must match or exceed the capture frame rate.
  • Format is limited — VideoToolbox hardware encoders only support H.264 and H.265
  • Quality and speed are hardware-determined — you get very few knobs to turn
  • Audio — only AAC or PCM

This pipeline optimizes for speed. Get the frames onto disk as fast as they come in.

The Conversion Pipeline

Source file (.mov / .mp4 / .mkv / .wav / .mp3)
  → MediaCodecs demuxer (FFmpeg)
  → decode to raw frames
  → optional filter chain (scale, crop, subtitle burn-in, watermark, fade)
  → target encoder (H.264, H.265, VP9, MP3, AAC, FLAC, WAV...)
  → mux to target container → output file

This pipeline lives in a completely different world:

  • No real-time constraint — two-pass encoding is possible. Quality over speed.
  • Any format in → any format out
  • Full parameter control — bitrate, preset, profile, level, sample rate, channel count
  • Filters are available — scale, crop, subtitle overlay, volume normalization, fade in/out

This pipeline optimizes for completeness and quality. Convert anything to anything, and make the output look good.

The Key Insight

Both pipelines share the same underlying engine (MediaCodecs), but the data flow is organized completely differently:

  • Recording: camera/screen frames → push → hardware encoder → file
  • Conversion: file → pull → software decode → filter → software encode → file

One pushes, one pulls. One is real-time, one is not. They need different API surfaces, different threading models, different error handling.

So what if we put both pipelines in the same app?

The FFmpeg Wrapper — A Decade of Private Frameworks

We’ve been building on FFmpeg for 10 years. Over that decade, we built up a set of Objective-C private frameworks:

FrameworkPurposeScope
MediaCodecsFFmpeg wrapper: demux, decode, filter chain, encode, mux. 200+ format/codec combinationsCore engine
MediaFormatFormat preset management: codec presets, resolution presets, sample rate presets, profile/level presetsPreset system
MediaFormatPopupFormat selection dropdown UI componentUI
MediaPlayerPlayback engine + recording engine (VideoRecorder)Playback/Recording
MediaEditorEditing: crop, rotate, volume, subtitle overlay, watermarkEditing

All frameworks are written in Objective-C with ARC memory management. Under the hood, they call FFmpeg’s libavcodec, libavformat, and libavfilter.

What we reused:

  • MediaCodecs — the entire codec engine (this was the hardest part to write; FFmpeg’s C API is notoriously hostile, and mixing C memory management with ObjC ARC requires extreme care)
  • MediaFormat — the preset database (200+ format/device presets, each defining codec + container + parameter combinations)
  • MediaPlayer — the recording engine (VideoRecorder drives screen/audio capture)
  • MediaEditor — file management layer

What we built new:

  • Complete AppKit UI (macOS 10.15 compatible, pure code layout, no XIB)
  • Screen recording control layer (region selection, annotation tools, webcam PiP)
  • Audio recording UI (live waveform, countdown timer, custom record button animation)
  • Offline subtitle pipeline (whisper.cpp integration → SRT/VTT/TXT/LRC)
  • In-app purchase and licensing
  • The record → convert bridge: a one-click export UI that goes from recording to target format in a single step

Audio: Pick Format First. Screen: Record First, Convert Later.

The UX differs between audio and screen recording, and the reason comes down to hardware.

Audio recording: pick your target format from the Format dropdown before recording. Hit stop, and the file is already in that format. Done.

15 supported audio formats:

Audio format selection dropdown — 15+ formats including MP3, WAV, FLAC, AAC, M4A

CategoryFormats
LossyMP3, AAC, WMA, OGG, AMR
LosslessFLAC, ALAC (M4A), APE
UncompressedWAV, AU
Apple-specificM4B (audiobook), M4R (ringtone)
ContainerMKA (Matroska audio), MP2
SurroundAC3 (Dolby Digital)

Screen recording: record first to MOV, then pick your target format (MP4, MKV, etc., with H.264 or H.265 encoder), hit export, and it converts in the background. Screen recording is constrained by real-time hardware encoding — VideoToolbox only outputs MOV with H.264/H.265. You can’t specify format or encoder parameters at capture time.

Dynamic format settings:

The parameter options change automatically based on the selected format — not every format supports every configuration:

  • Select WAV → sample rate goes up to 96,000 Hz, stereo/mono selectable
  • Select AMR → locked to 8,000 Hz, mono only (AMR is a speech codec)
  • Select MP3 → CBR/VBR adjustable, 320 kbps ceiling
  • Select FLAC → lossless, compression level 0–8
  • Select MP4 (H.265) → half the file size of H.264, but older devices may not play it back

This logic all comes from the MediaFormat framework — 10 years of format compatibility data baked into the preset database.

What happens when you click Export:

1. Read format preset → FormatPreset
2. Build encoder config → CodecParameter (codec, bitrate, sample rate, channels)
3. Build filter chain (if needed) → fade, volume normalization
4. Open source file → MediaDecoder
5. Open destination file → MediaEncoder
6. Transcode loop: decode frame → filter → encode frame → write packet
7. Progress callback → UI update
8. Complete → cleanup → reveal in Finder

Why Not Convert During Recording?

The ideal experience would be: pick your output format, hit record, and the file is already in the right format when you stop. No export step needed.

We designed for this initially — transcode video frames to the target format in real time during capture. It didn’t work.

The problem is performance overhead.

Real-time recording is already resource-intensive — screen capture, hardware encoding, disk I/O. Stack a software transcode on top of that (e.g., real-time H.264 to H.265 conversion), and CPU immediately pegs at 100%. On our test machine (2018 Intel MacBook Pro), recording + transcoding simultaneously started dropping frames within a minute. The footage was visibly choppy.

Our product targets everyday users, not just M3 Max owners. An older MacBook Air can handle screen recording just fine — but only because VideoToolbox offloads encoding to dedicated hardware. Add a software transcode and that headroom evaporates.

So we split them:

  • Recording phase: VideoToolbox hardware encoding. Output is MOV only. Fast, zero dropped frames, works on any Mac.
  • Conversion phase: post-recording FFmpeg software encode to target format. Slower, but full quality control, and it doesn’t compete with recording for resources.

It’s not the most elegant solution. But for a tool aimed at a broad user base, not dropping frames matters more than one-click perfection.

Real-World Workflows

Tutorial creators: Record screen + voiceover (MOV, H.264, several GB). Need to upload to YouTube → export compressed MP4. Previously: HandBrake as a separate step. Now: export directly after recording.

Podcasters: Record an interview (MP3, 128 kbps). Need WAV for Audacity editing. Previously: import MP3 into Audacity, export WAV. Now: export WAV 48 kHz/24-bit directly.

Developers recording demos: Record app walkthrough (MOV, H.265, large file). Need to share on Slack (10 MB limit). Previously: compression tool, manually tweak parameters. Now: export compressed MP4 H.264, 720p.

Meeting recordings: Record a 2-hour meeting (giant MOV). Need MP3 for transcription. Previously: extract audio track, convert to MP3. Now: export as “Audio Only → MP3” directly.

Language learners: Record pronunciation practice (WAV). Need M4R ringtone format. Previously: hunt for a dedicated ringtone converter. Now: export M4R, drag to iPhone.


Yfli Screen Recorder is a free Mac app for screen recording, audio recording, subtitle generation, and format conversion. The format conversion features described here are part of the Pro upgrade. 7-day free trial, then 10 free exports after.


Related Reading

Whisper Was Slow and Garbage on Intel Mac — Here's How We Fixed It

The debugging session that nearly changed our entire technical direction.

Ready to Try Yfli Screen Recorder?

Free download on the Mac App Store. No account required, no ads, no watermark.

Yfli

Yfli

Creator of Yfli Screen Recorder. Passionate about building great macOS tools that are simple, powerful, and beautiful. Writing about screen recording, macOS tips, and software development.