A Flutter app built for filming interval-based rowing and cycling workouts on YouTube. Designed to sit in frame while you train — big, readable text on a black background, showing your current interval countdown alongside the next two intervals so you always know what's coming.
Built by John as part of the RowAlong channel.
The screen is split into three panels:
- Left half (full height) — a large countdown timer for the current interval, with its stroke/pedal rate and intensity label below
- Top right — the next interval's duration and details, in orange
- Bottom right — the interval after that, in blue
Intervals advance automatically as each one completes — no tapping required mid-workout. When the last interval finishes, the screen shows WORKOUT COMPLETE.
Everything is saved on the device. Your workout is still there next time you open the app.
Built with Flutter. Tested on Android (Pixel Tablet, Moto e30).
Dependencies — run these from your project root:
flutter pub add shared_preferences
flutter pub add file_picker
flutter pub add wakelock_plus
flutter pub add http
Android internet permission — add this to android/app/src/main/AndroidManifest.xml as a direct child of <manifest>, before <application>:
<uses-permission android:name="android.permission.INTERNET" />Then flutter pub get and run.
Tap the settings cog on the main screen. Each interval has three fields:
| Field | What to enter |
|---|---|
| Duration | HH : MM : SS — e.g. 00:02:30 for 2 minutes 30 seconds |
| SPM | Stroke or pedal rate — numbers only, e.g. 22 |
| Intensity | Free text label, e.g. Easy Spin or Max Effort |
Use the drag handle to reorder intervals, the checkbox + copy icon to duplicate one or more, and the bin icon to delete. Tap the tick to save.
Rather than entering intervals one by one, you can import from a CSV file.
CSV format — one row per interval, three columns:
duration,spm,intensity
0:30,,Lead in
5:00,,Easy Spin Warmup
2:00,,Hard Grind
1:00,,Easy Spin
0:30,,Max Power
1:30,,Easy Spin
duration:M:SSorH:MM:SSspmandintensity: free text, can be left blank (note the two commas for a blank SPM)- A header row is optional — it's skipped automatically if present
- Repeats like
3x (...)need to be expanded into individual rows first
Tap the upload icon in Settings to pick a .csv file from your device. The imported intervals replace whatever's currently in the list — tap Save to keep them.
A sample CSV is included in sample_workouts/lead_in_grind_sprint.csv.
| Button | Action |
|---|---|
| ▶ / ⏸ | Start / pause the timer |
| ↺ | Reset to the first interval |
| ⏭ | Skip to the next interval |
| ⚙ | Open workout settings |
Keyboard doesn't appear when tapping a field (Pixel Tablet etc.) Some Android tablets suppress the on-screen keyboard when they detect a dock or Bluetooth accessory. Check Settings → System → Languages & input → On-screen keyboard and make sure it isn't set to hide when a physical keyboard is detected.
App stays in portrait on some phones The app is landscape-only by design — it forces landscape on launch. If it's staying portrait, try locking your device rotation off and back on, then restarting the app.
This project is licensed under Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0).
You are free to use, share, and adapt this code for personal, non-commercial purposes, as long as you give appropriate credit to the original author.
Commercial use of this code or any derivative is not permitted without explicit written permission.
Full licence text: https://creativecommons.org/licenses/by-nc/4.0/
© John / RowAlong