Guide
Google ended AutoFlip support in 2023, and pip ships none of it. Rebuild its shot-by-shot 9:16 crop in Python with MediaPipe and PySceneDetect, or let clipsdk follow the speaker for $0.03 per source minute.
AutoFlip alternative: rebuild the 9:16 crop in Python
AutoFlip still needs a Bazel build and OpenCV 3, and the mediapipe package on pip ships none of it, so this guide rebuilds its core idea with the MediaPipe Tasks face detector.
GuidesUpdated
Or one API call
$0.03per source minute
- Every clip included, up to 1080p60 and 20 Mb/s
- $1 free to start, 33 minutes of video
- Prepaid credit, no subscription
AutoFlip, the rebuild and clipsdk side by side
| Option | Status | Shot cuts | Faces | Camera | Cost |
|---|---|---|---|---|---|
| AutoFlip (MediaPipe legacy) | Support ended March 1, 2023 | Its own shot boundary calculator | Faces plus other salient objects | Steady or following, decided per shot | Free, you build it with Bazel |
| The rebuild in this guide | Runs on current Python | PySceneDetect | BlazeFace full-range in MediaPipe Tasks | One steady crop per shot | Free, runs on your CPU |
| clipsdk | Live API | ffmpeg scdet at threshold 8, plus fades | YuNet 5 times a second, speaker picked by mouth motion | Cuts on speaker switches, eases in between | $0.03 per source minute |
Rebuild AutoFlip in Python
We ran every file below against NASA's Rocket Ranch podcast, one of our public domain demo videos. The output each file printed sits under its code.
Install the pieces and cut a test moment
AutoFlip is not in the pip package: not one file that mediapipe installs has autoflip in its name. Install the MediaPipe Tasks API and PySceneDetect instead, fetch both BlazeFace models and cut the 59-second moment clipsdk ranked as its second clip.
setup.sh python3 -m venv venv && . venv/bin/activate pip install -q mediapipe==1.2.2 scenedetect==0.7.2 curl -sO https://api.clipsdk.com/f/lib/demo/rocket-ranch-podcast.mp4 for model in full_range short_range; do curl -sO https://storage.googleapis.com/mediapipe-models/face_detector/blaze_face_$model/float16/1/blaze_face_$model.tflite done ffmpeg -v error -ss 186.31 -i rocket-ranch-podcast.mp4 -t 59.13 -c:v libx264 -crf 18 -c:a aac moment.mp4 # $ pip show -f mediapipe | grep -i -c autoflip # 0 # $ python3 --version && ffmpeg -version | head -1 # Python 3.13.14 # ffmpeg version 7.1.5-0+deb13u1 Copyright (c) 2000-2026 the FFmpeg developersSplit the shots, then pick one crop per shot
AutoFlip decides per shot whether the camera holds still or follows the action. People at a podcast table barely move, so a steady crop per shot does the job. PySceneDetect finds the cuts, BlazeFace finds the biggest face 5 times in each shot, the median face centre sets a 608x1080 crop, and one ffmpeg pass switches crops at every cut.
reframe.py import subprocess import cv2 import mediapipe as mp from mediapipe.tasks.python import BaseOptions, vision from scenedetect import ContentDetector, detect SRC, OUT = "moment.mp4", "vertical.mp4" # AutoFlip step 1: split the video into shots at every camera cut shots = detect(SRC, ContentDetector()) video = cv2.VideoCapture(SRC) W = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)) H = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)) crop_w = round(H * 9 / 16 / 2) * 2 faces = vision.FaceDetector.create_from_options(vision.FaceDetectorOptions( base_options=BaseOptions(model_asset_path="blaze_face_full_range.tflite"))) def biggest_face_x(t): video.set(cv2.CAP_PROP_POS_MSEC, t * 1000) ok, frame = video.read() image = mp.Image(image_format=mp.ImageFormat.SRGB, data=cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) found = faces.detect(image).detections if not found: return None box = max(found, key=lambda d: d.bounding_box.width).bounding_box return box.origin_x + box.width / 2 # AutoFlip step 2: one steady crop per shot, its "stable camera" choice plan = [] for start, end in shots: a, b = start.seconds, end.seconds xs = [x for i in range(5) if (x := biggest_face_x(a + (b - a) * (i + 0.5) / 5)) is not None] centre = sorted(xs)[len(xs) // 2] if xs else W / 2 left = int(min(max(centre - crop_w / 2, 0), W - crop_w)) plan.append((b, left)) print(f"shot {a:5.2f}-{b:5.2f}s face in {len(xs)}/5 samples crop x={left}") # AutoFlip step 3: render, switching the crop at each cut x_expr = str(plan[-1][1]) for end, left in reversed(plan[:-1]): x_expr = f"if(lt(t,{end:.3f}),{left},{x_expr})" subprocess.run(["ffmpeg", "-v", "error", "-y", "-i", SRC, "-vf", f"crop={crop_w}:{H}:'{x_expr}':0,scale=1080:1920", "-c:a", "copy", OUT], check=True) print(f"{len(plan)} shots, {crop_w}x{H} crop scaled to 1080x1920: {OUT}") # $ time python3 reframe.py 2>/dev/null # shot 0.00- 5.47s face in 5/5 samples crop x=1256 # shot 5.47-17.73s face in 5/5 samples crop x=476 # shot 17.73-23.13s face in 5/5 samples crop x=818 # shot 23.13-30.73s face in 5/5 samples crop x=41 # shot 30.73-35.73s face in 5/5 samples crop x=474 # shot 35.73-39.23s face in 5/5 samples crop x=1257 # shot 39.23-50.73s face in 5/5 samples crop x=426 # shot 50.73-59.10s face in 4/5 samples crop x=38 # 8 shots, 608x1080 crop scaled to 1080x1920: vertical.mp4 # # real 2m32.576s # user 3m57.115s # sys 0m12.353sUse the full-range face model
Google tunes the short-range model for selfie distance and the full-range model for back camera shots. On this wide two-person studio shot that matters: short-range missed the face in 4 of every 10 sampled frames, while full-range found it in all of them.
compare_detectors.py import cv2 import mediapipe as mp from mediapipe.tasks.python import BaseOptions, vision video = cv2.VideoCapture("moment.mp4") detectors = { name: vision.FaceDetector.create_from_options(vision.FaceDetectorOptions( base_options=BaseOptions(model_asset_path=f"blaze_face_{name}.tflite"))) for name in ("short_range", "full_range") } hits = dict.fromkeys(detectors, 0) for second in range(59): video.set(cv2.CAP_PROP_POS_MSEC, second * 1000 + 500) ok, frame = video.read() image = mp.Image(image_format=mp.ImageFormat.SRGB, data=cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) for name, detector in detectors.items(): hits[name] += len(detector.detect(image).detections) > 0 print({name: f"face found in {count}/59 frames" for name, count in hits.items()}) # $ python3 compare_detectors.py 2>/dev/null # {'short_range': 'face found in 35/59 frames', 'full_range': 'face found in 59/59 frames'}
Or send one request
The same podcast through clipsdk with reframe: "auto" came back as 3 ranked 9:16 clips in under 2 minutes. Clip 2 is the moment from the steps, and it scored 85.
clipsdk finds faces with YuNet 5 times a second and picks the speaker by mouth motion, so a two-person shot crops to whoever is talking. A shot with no face keeps the whole frame over a blurred copy instead of a blind centre crop.
curl https://api.clipsdk.com/v1/clips \
-H "Authorization: Bearer $CLIPSDK_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://api.clipsdk.com/f/lib/demo/rocket-ranch-podcast.mp4",
"clips": 3,
"aspect": "9:16",
"reframe": "auto",
"captions": "bold"
}'What AutoFlip did, and what is left of it
AutoFlip was a MediaPipe graph that turned landscape video into any aspect ratio. It found shot boundaries, detected faces and other salient objects, and decided per shot between a camera that holds still and one that follows the action.
Google's AutoFlip page now opens with one line: "We have ended support for this MediaPipe Legacy Solution as of March 1, 2023." The C++ graph still builds with bazel build, and by the same page it only works with OpenCV 3. The current mediapipe package on pip has the Tasks API and no AutoFlip.
Where the simple rebuild falls short
A steady crop per shot can't follow someone who walks across the frame, and when two people share a shot the biggest face wins, not the one talking. With no face found the script centres the crop, where AutoFlip would pad the frame to keep its salient content.
Each fix is more code: track faces between frames, score mouth movement to find the speaker, ease the crop between targets, and catch fades as well as hard cuts. That is the part clipsdk runs for you, as a reframe API or inside every clip job.
What it costs
The rebuild is free software, so the cost is your CPU: reframe.py took about two and a half minutes for the 59-second moment.
clipsdk bills per source minute, so the episode, just under 10 minutes, cost about $0.29 at $0.03 for the 3 clips above, with no subscription. See pricing for the clip minute floor and volume rate.
Questions, answered
Is MediaPipe AutoFlip still supported?
No. Google's AutoFlip page says support for this MediaPipe Legacy Solution ended on March 1, 2023, and points to MediaPipe Solutions instead. The code is still in the repository, but it gets no fixes.
Is AutoFlip free?
Yes. The source is free in Google's MediaPipe repository, but you compile it yourself with Bazel and it needs OpenCV 3. The Python rebuild on this page is free too and installs with pip. clipsdk costs $0.03 per source minute, and your first $1 is free.
Why is AutoFlip not working?
The usual blockers are the build and the package. AutoFlip is a C++ graph you compile with Bazel, Google's page says it only works with OpenCV 3, and the mediapipe package on pip doesn't include it, so pip install mediapipe gives you nothing named AutoFlip to run.
Which MediaPipe face model works for wide shots?
Full-range. On a two-person studio shot it found a face in every frame we sampled, while short-range, which Google tunes for selfie distance, missed 4 in 10.
Keep reading
- Speaker reframe: 16:9 to 9:16 that follows whoever is talkingReframe wide video to 9:16 (1080x1920), 1:1, 4:5 or 16:9. Auto mode tracks faces and cuts to whoever is talking; center and none are one field away. $0.03 per source minute.
- Turn every podcast episode into a week of shortsUpload a podcast episode and get up to 20 vertical clips, each scored 0 to 100 with a reason, reframed to the speaker and captioned. A 60 minute episode costs ~$1.80.
- Build an OpusClip cloneThe whole clipping pipeline in 5 Python files: transcribe, pick moments with an LLM, reframe to 9:16, caption and render, with real costs.
- Face tracking crop from 16:9 to 9:16Track a face with OpenCV YuNet and move an ffmpeg crop with sendcmd to turn a 1920x1080 lesson into a 1080x1920 vertical clip.
- Find viral moments with an LLMA tested prompt that makes an LLM pick clip-worthy moments from a transcript by hook, complete thought and payoff, plus the checks its answers need.
- Scene cut detection for clipsFind hard cuts with PySceneDetect and ffmpeg scdet, split a clip into shots, and see why a vertical reframe must restart at each one.
Sources
- Google: AutoFlip, a MediaPipe legacy solution, checked 7 November 2026
- Google: MediaPipe face detector models, checked 7 November 2026
- mediapipe 1.2.2 on PyPI, checked 7 November 2026
- scenedetect 0.7.2 on PyPI, checked 7 November 2026
- NASA: Rocket Ranch podcast with Moogega Cooper, checked 7 November 2026
Start free
Your back catalog is full of shorts
Your first $1 is free: 33 minutes of video, every clip included up to 1080p60 and 20 Mb/s.
