Checking video facts against the source
ffmpeg -h muxer=whip on FFmpeg 7.1.1 returns Unknown format 'whip'. A lesson in the WebRTC course taught -f whip as a command that already ran on FFmpeg 7.1. It didn't. Checking a claim like that means running the command. Every course, quiz and lab on BeemMeUp went through the same check, and the corrections that came out of it are a good tour of the video facts that are easiest to get slightly wrong.
What counted as checked
An FFmpeg claim meant running it. -h encoder=, -h filter=, -h muxer=, or the full command against a real input, and reading what came back instead of what the lesson said would come back. A spec claim meant opening the primary spec and citing it by section number. Nothing got marked correct on the strength of sounding right.
A muxer that ships later than the course claimed
WHIP, the WebRTC-HTTP Ingestion Protocol, standardizes how a client publishes a WebRTC stream to a server: one HTTP POST carries an SDP offer, the response carries the answer, and the two sides negotiate media over the usual WebRTC transport from there. Before it, each platform had its own handshake. FFmpeg can act as a WHIP client and publish straight into a gateway like MediaMTX or Janus with a single -f whip command, which is useful for anyone scripting an ingest test. It arrived in FFmpeg 8.0. The whip output muxer landed upstream after the n7.1.1 tag and before n8.0. On the FFmpeg version the rest of the course runs against, it doesn't exist yet.
The companion protocol makes the opposite mistake possible. WHEP, the egress counterpart to WHIP, lets a client request playback over HTTP and get back an SDP answer for receiving media. A debugging lesson told learners to point ffprobe at a WHEP endpoint directly, captioned as needing "an FFMPEG build with the whep demuxer." FFmpeg has no WHEP demuxer. The workable approach is to probe what's actually on the other side of a WHEP gateway instead, MediaMTX's re-served RTSP stream, which ffprobe can read the way it reads any other RTSP source.
Three details in the SDP and the spec
A simulcast attribute in an SDP offer is written with a colon: a=simulcast:send, per RFC 8853. Written with a space instead, it isn't the attribute the spec defines, and a compliant parser won't read it as simulcast.
Opus isn't the only audio codec every WebRTC peer shares. RFC 7874 §3 makes G.711 mandatory to implement alongside Opus, precisely so two endpoints with nothing else in common can still negotiate audio. A peer is free to support only the mandatory codecs, and an app that assumes Opus everywhere will fail to negotiate audio against one that does.
And WebRTC's required H.264 profile is Constrained Baseline, per RFC 7742. It's a subset of Baseline that leaves out a few error-resilience tools, such as flexible macroblock ordering, that few decoders outside Baseline support. The two names mean different things, so a lesson has to use the right one.
The sign was flipped on setpts
The clearest error in the FFmpeg course was arithmetic. setpts rescales a video's presentation timestamps, and dividing every timestamp compresses the timeline, which speeds playback up; multiplying stretches it, which slows playback down. A course module taught the opposite rule in both directions:
| Lesson said | Command | Actual result |
|---|---|---|
| "4× slower" | setpts=PTS/4.0 | 4× faster (0.99s from a 4s clip) |
| "2× faster" | setpts=PTS/0.5 | 2× slower (7.92s from a 4s clip) |
| "2× slower" | setpts=PTS/2.0 | 2× faster (1.98s from a 4s clip) |
The lessons, a challenge and a quiz all used the inverted rule. The module now uses the multiplier form, setpts=0.5*PTS to speed up, setpts=2.0*PTS to slow down, which matches FFmpeg's own documented idiom for slow motion and reads correctly in either direction without needing to mentally flip a fraction.
One audio map per variant
A -var_stream_map command in the Cloud Video Lab built an adaptive HLS ladder by mapping three video renditions against a single shared audio map: v:0,a:0 v:1,a:0 v:2,a:0, reusing the same audio output stream for every variant. Running that command fails before it writes a segment, with FFmpeg's HLS muxer rejecting the header outright. The muxer expects a distinct audio output stream per variant group, even when every variant is meant to carry the identical audio track. The fix is to map the audio input once per variant: -map 0:a -map 0:a -map 0:a alongside the three video maps, so each group in -var_stream_map points at an audio stream that actually exists in the output.
Rules of thumb are the hard part
A wrong flag fails loudly the first time someone runs it. A rule of thumb with no source behind it can sit in a course for years, because it sounds reasonable and nothing ever runs it. Those went into a separate list of open questions, each one waiting for a primary source. A course about video should hold its claims to the same standard as its commands: if FFmpeg or the spec can answer it, ask them.