A screen recording can look correct while sounding completely wrong. A tutorial needs narration above the application’s audio; a demonstration may need only system sound. Treating both inputs as one volume control makes those two jobs unnecessarily difficult.
In Reel Screen Recorder, the broadcast extension receives ReplayKit buffers and keeps their source identity until the writer dispatches them. The useful engineering detail is not the slider itself. It is what happens when transforming a buffer fails.
Keep source identity through the pipeline
The current SampleHandler.handleAudio distinguishes .audioMic from .audioApp and asks the shared settings for recordingGain(forMicrophone:). It then passes the processed buffer, with its original source type, to BroadcastWriter.
The writer routes video, app audio, and microphone audio to separate capture functions. Its asset writer uses the MP4 container. This division keeps capture policy out of the file-writing dispatch code and makes it possible to reason about each source independently.
| Boundary | Responsibility | What must remain intact |
|---|---|---|
| ReplayKit callback | Identify source | Video versus app versus mic |
| Gain adjustment | Apply that source’s setting | Timing and sample format |
| Writer dispatch | Choose capture function | Original buffer type |
| Finalization | Finish the local asset | A playable file, not merely a path |
Zero gain is different from a small gain
The handler tries a volume-adjusted copy when gain is not one. If that transformation fails and the requested volume is zero, it tries to create a silent buffer. If silence creation also fails, it returns without writing the buffer.
Here is the policy in condensed pseudocode, not a drop-in ReplayKit implementation:
if transformation succeeds:
write transformed buffer
else if requested gain is zero:
if silent copy succeeds: write silence
else: discard buffer
else:
write original buffer
That last nonzero case is a fidelity compromise: requested gain may not be honored. The zero case is a privacy boundary. Writing the original buffer after the user muted it would violate the user’s explicit choice. The implementation treats those failures differently.
A floating camera is a separate concern
Reel also offers a picture-in-picture camera workflow. A camera preview, a system PiP surface, and an encoded recording are different objects with different lifetimes. A visible camera window alone is not proof that the exported clip contains the intended image and audio.
For verification, use a short recording with identifiable synthetic app sound and a spoken microphone marker. Inspect the exported MP4, then repeat with each source muted individually. Include interruption and failed-transform cases in tests. These are suggested checks, not performance results claimed from this code review.
The broader lesson is to preserve source identity until the last component that needs it. Mixing early makes later controls harder to explain and harder to verify. For the product workflow and alternatives, see Reel’s recording comparisons.
Available on Reel Screen Recorder on the App Store.
Top comments (0)