Download your FlyAOA Media training videos — and the PDF handouts, checklists, study guides and other downloadable files attached to each lesson — so you can watch and use them offline.
Requires an active FlyAOA Media training membership with access to the courses.
training.flyaoamedia.com runs on Kajabi, which serves course lessons with embedded Wistia videos. This tool uses plain HTTP requests (no browser automation) to:
- Log in to the training site
- Crawl your Library to discover every product (course) and its lessons
- Read each lesson page and find the embedded Wistia video
- Download the video with
yt-dlp - Mirror any downloadable files (PDFs, handouts, checklists, ZIPs) attached to the lesson
Videos and their lesson files are organised per course:
downloads/
Course Name/
001 - First Lesson.mp4
001 - First Lesson - Study_Guide.pdf
002 - Second Lesson.mp4
Lesson metadata is saved to metadata.json.
- Python 3.11+
- A FlyAOA Media account with access to the training
ffmpegon yourPATH(used byyt-dlpto merge video + audio)
-
Clone the repository and install dependencies:
git clone https://github.com/GraafG/flyaoamedia-dl.git cd flyaoamedia-dl pip install -r requirements.txt
-
Copy the example configuration:
Copy-Item .env.example .env -
Fill in
.envwith your account email and password.
Download everything:
python -u download_videos.pyList the courses and lessons it finds (no downloads):
python -u download_videos.py --listDownload only a limited number of videos:
python -u download_videos.py --limit 5Only download a specific course (matches against the product URL):
python -u download_videos.py --product zero-to-finishRefresh metadata only:
python -u download_videos.py --metadata-onlyBy default the downloader reuses the cached metadata.json when it exists, so
resuming an interrupted run does not re-crawl every lesson page (which can trip the
site's rate limiting). Force a fresh crawl with --refresh:
python -u download_videos.py --refreshThe tool will:
- Log in to the training site
- Save lesson metadata in
metadata.json - Save lesson URLs in
video_links.txt - Download videos into
downloads\<Course Name>\ - Mirror all console output to
download.log - Skip previously downloaded
.mp4files - Resume safely when you run it again
All settings can be configured in .env:
| Variable | Description | Default |
|---|---|---|
FLYAOA_EMAIL |
Your FlyAOA Media login email | empty |
FLYAOA_PASSWORD |
Your FlyAOA Media password | empty |
FLYAOA_BASE_URL |
Base URL of the training site | https://training.flyaoamedia.com |
OUTPUT_DIR |
Folder for downloaded videos | ./downloads |
YTDLP_CONCURRENT_FRAGMENTS |
Parallel HLS/DASH fragment downloads | 16 |
FLYAOA_REQUEST_DELAY |
Seconds to wait between crawl requests (avoids HTTP 429) | 1.0 |
LOG_FILE |
Path for the mirrored run log | ./download.log |
The main speed setting is YTDLP_CONCURRENT_FRAGMENTS.
$env:YTDLP_CONCURRENT_FRAGMENTS='32'
python -u download_videos.pyUse 16 or 32 as a practical range. Higher values may be faster, but can also trigger throttling or more retries.
downloads/
Course Name/
001 - First Lesson.mp4
001 - First Lesson.nfo
001 - First Lesson.jpg
001 - First Lesson - Study_Guide.pdf
002 - Second Lesson.mp4
002 - Second Lesson.nfo
002 - Second Lesson.jpg
Each video gets:
.mp4— the video.nfo— Kodi/Jellyfin metadata (title, course, ordering, duration).jpg— Wistia thumbnail / poster art
Lessons that have files in their Kajabi downloads dropdown (PDFs, handouts,
checklists, ZIPs, etc.) also get those mirrored next to the video, named
NNN - Lesson Title - Original Filename.ext. Lessons with downloadable files
but no video (for example a course "Study Guide") are mirrored too.
To skip NFO generation:
python -u download_videos.py --no-nfoTo control attachment mirroring:
# Skip downloadable attachments entirely
python -u download_videos.py --no-attachments
# Only mirror attachments (skip videos) — handy when videos are already downloaded
python -u download_videos.py --attachments-onlyAdd downloads/ as a Movies library in Jellyfin and group by folder. The .nfo files are read automatically, and the <set> tag keeps lessons grouped by course.
- Login failed — Check
FLYAOA_EMAIL/FLYAOA_PASSWORDin.env. The site requires your account email, not a username. - No products found — Kajabi occasionally changes its library layout. Run with
--listto see what is discovered. - A lesson has no video — Some lessons are text/PDF only; these are listed in
metadata.jsonwith nohashed_idand are skipped. - Download stops halfway — Run the script again. Completed files are skipped.
Contributions are welcome! See CONTRIBUTING.md for guidelines.
Report bugs or suggest features via GitHub Issues.
Security issues? See SECURITY.md.
Other personal-use download tools for paid subscriptions:
- tylerraw-dl — Tyler Raw subscription videos
- elektormagazine-dl — Elektor Magazine issues as PDF
- consumentenbond-dl — Consumentenbond publications as PDF
This tool is intended for personal use by paying FlyAOA Media members to watch their own accessible training videos offline. Do not share downloaded files — respect FlyAOA Media's copyright and terms.
MIT