
BeatBuddy Replay is a video analysis application designed for athletes, with a special focus on swimmers training with the Total Immersion method. It was originally named SwimLab Coach's Eye. We are currently integrating it into the BeatBuddy ecosystem - family of products for athletes - which is why we decided to rename it.
The app was built with Flutter. It is currently available on iOS (iPhone and iPad), with an Android version in development.
BeatBuddy Replay was created for:
Total Immersion Coaches - who need precise tools for technique analysis. The TI method is based on conscious work on every movement element, and the app allows coaches to show athletes exactly what and how to improve.
Swimming Coaches - who want to show athletes their technical errors directly on the recording.
Athletes - who independently analyze their training sessions and competitions.
Swimming Clubs - looking for a simple video analysis tool without complicated software.
The app fills the gap between a simple video player and professional (and expensive) sports analysis software. It's intuitive, works offline, and requires no subscription.
During two weeks of test development, we encountered many problems. Here are the 10 most important challenges and the lessons we learned from them.
All the application code is in a single file with over 3,300 lines. Without an advanced state management framework, everything relies on Flutter's basic mechanisms.
We wanted to deliver a working product to coaches who were waiting for this tool as quickly as possible. Perfect architecture can wait - user feedback cannot.
Takeaway: For MVP projects, speed is more important than architecture, but refactoring will be essential for further development.
One of the first serious problems was app crashes on iOS. The debugging process was tedious and required many attempts before we could locate the issue.
It turned out that plugins like video_player or file_picker require appropriate entries in the iOS configuration:
<key>NSPhotoLibraryUsageDescription</key>
<string>Needed to access videos for analysis</string>
Every crash is a potentially lost user. A coach whose app crashes during a demonstration to an athlete won't give it a second chance.
Takeaway: Cross-platform plugins often require platform-specific configuration that isn't obvious from the documentation.
From the first version of the app, we had to implement a complex drawing system supporting 6 shape types: lines, arrows, rectangles, circles, triangles, and freehand curves.
Flutter offers the CustomPainter class, which provides full control over drawing:
class DrawingPainter extends CustomPainter {
final List<Shape> shapes;
@override
void paint(Canvas canvas, Size size) {
for (var shape in shapes) {
final paint = Paint()
..color = shape.color
..strokeWidth = shape.strokeWidth
..style = PaintingStyle.stroke;
canvas.drawLine(shape.start, shape.end, paint);
}
}
}
Coaches need different tools for different situations. An arrow shows the direction of movement, a circle highlights an error, a line compares body positions.
Takeaway: Flutter offers a powerful drawing API, but it requires knowledge of geometry. It's an investment that pays off - a custom engine provides full control over functionality.
A key feature for swimming coaches - technique angle measurement - required implementing vector mathematics. We use the dot product of vectors and the law of cosines:
double calculateAngle(Offset p1, Offset vertex, Offset p2) {
final v1 = p1 - vertex;
final v2 = p2 - vertex;
final dotProduct = v1.dx * v2.dx + v1.dy * v2.dy;
final magnitude1 = sqrt(v1.dx * v1.dx + v1.dy * v1.dy);
final magnitude2 = sqrt(v2.dx * v2.dx + v2.dy * v2.dy);
final cosine = dotProduct / (magnitude1 * magnitude2);
return acos(cosine) * (180 / pi); // result in degrees
}
Elbow bend angle, hand entry angle into the water, head position relative to torso - these are concrete numbers that a coach can show to an athlete. "Bend your elbow 15 degrees more" is more effective than "bend more."
Takeaway: Applications for a specific industry often require domain knowledge beyond typical programming.
Implementing dragging and resizing of drawn shapes proved to be one of the more difficult challenges. It requires detecting whether a finger touches a shape, tracking the "selected" element, and smoothly updating its position.
bool isPointInsideShape(Shape shape, Offset point) {
final rect = Rect.fromPoints(shape.start, shape.end);
return rect.contains(point);
}
A coach draws an arrow, but the athlete asks about a different moment - they need to quickly move the annotation without redrawing. Workflow fluidity is fundamental.
Takeaway: Interactive graphic elements are much harder than static drawing, but essential for good UX.
Implementing the "spotlight" effect - dimming the background with a cut-out circle - required a multi-layered approach with two independent graphic components.
When a coach shows hand position, the rest of the frame is distracting. Spotlight allows focusing the athlete's attention exactly where needed. It's the difference between "look here" and actually looking.
Takeaway: Visual effects require thoughtful layer architecture, but dramatically improve application usability.
Attempting to add screen recording revealed the painful truth about cross-platform development. The library used simply doesn't work the same on all systems.
if (!Platform.isMacOS) {
await FlutterScreenRecording.startRecordScreen(fileName);
} else {
showMessage("Screen recording is not available on this platform");
}
A coach wants to record their analysis with voice commentary and send it to an athlete. This is a key feature for remote work with athletes.
Takeaway: "Cross-platform" doesn't mean "works identically everywhere." You need to test on all target devices and sometimes accept limitations.
Finding the optimal control layout required many iterations. We started with controls in the right sidebar, then moved them to the bottom, added a play icon over the video, removed the sidebar, centered the toolbar...
A coach often holds the tablet with one hand while pointing something out to an athlete with the other. Controls must be accessible with a thumb, cannot obscure the video, and must be readable at the pool in full sunlight.
Takeaway: UX requires experimentation and feedback collection. You cannot design the perfect interface on the first try.
The app must work equally well on iPhone (compact screen, on-the-go analysis) and iPad (larger screen, detailed work). Drawing controls require different proportions on each device.
final isTablet = MediaQuery.of(context).size.shortestSide >= 600;
final iconSize = isTablet ? 32.0 : 24.0;
A coach uses the iPad during training at the pool, but the athlete watches the analysis on their iPhone at home. The experience must be consistent.
Takeaway: Responsive design requires conscious design for each form factor, not just interface scaling.
Every "simple" system integration - opening links, sharing, saving to gallery - turned out to require more work than we expected.
await Share.shareFiles([screenshotPath], text: 'Technique analysis');
A coach takes a screenshot with annotations and wants to send it via WhatsApp. If that requires 5 steps instead of 2, they simply won't do it.
Takeaway: System integrations are the "last mile" - often underestimated, but crucial for real-world app usage.
The development history of BeatBuddy Replay shows a typical product-building path:
| Phase | Focus |
|---|---|
| Quick start | Working app in one day |
| Platform issues | Crashes, debugging, iOS adaptation |
| Feature expansion | Spotlight, object movement, protractor |
| UX refinement | Dozens of interface iterations |
| Stabilization | Screen recording, sharing |
We are working on:
Speed over perfection - it's better to release a working product and iterate than to wait for the ideal.
Test on real devices - a simulator cannot replace an iPad in a coach's hands by the pool.
Listen to users - every UI iteration resulted from real feedback.
Cross-platform has its limits - accept limitations and communicate them clearly.
The app delivers a fully functional video analysis tool in just over 3,000 lines of code - proof that Flutter allows you to quickly build useful products for a specific niche.
BeatBuddy Replay is part of the BeatBuddy Platform ecosystem, which also includes BeatBuddy Pro - a programmable metronome device for swimmers. More information at beatbuddypro.com
Have questions about BeatBuddy Replay or want to share your experience?
Reach out to us — we'd love to hear from you.
Ambistream – Building a Multi-Layer Streaming Platform from a Spark of an Idea
How a late-night experiment grew into a multi-platform streaming engine with overlays, remote control, Chromecast/AirPlay support, and a full creative workflow for music, sports, and training.
Building a Custom Chromecast & AirPlay Casting App: 14 Prototypes Later
How controlling a TV turned out to be harder than streaming to it – and why we built our own Chromecast receiver. A deep dive into the R&D process behind a complex casting architecture.