A GUI tool for downloading all Panopto lecture videos from a Canvas course as MP3 files, with optional local transcription via Whisper.
Built for CBS (Copenhagen Business School) but should work for any institution using Canvas + Panopto with LTI 1.3 authentication.
- Automatic video discovery — scans all Canvas modules, pages, assignments, and announcements for Panopto links
- Full LTI 1.3 authentication — handles the Canvas → Panopto OIDC handshake automatically, no manual cookie export needed
- MP3 download via ffmpeg (audio-only, 128 kbps)
- Local transcription via OpenAI Whisper — produces
.txtand.srt(timestamped) files - GPU support — automatically detects CUDA for fast Whisper transcription
- Simple GUI — all settings in one window, live log output, progress bar
- Persistent config — token and preferences saved to
config.json, pre-filled on next launch - Debug tools — two diagnostic scripts for troubleshooting auth issues
# 1. Clone the repo
git clone https://github.com/your-username/panopto-downloader.git
cd panopto-downloader
# 2. Install Python dependencies
pip install requests openai-whisper
# 3. Install ffmpeg
# Windows: download from https://ffmpeg.org/download.html and add to PATH
# macOS: brew install ffmpegIf you have an NVIDIA GPU, install a CUDA-enabled version of PyTorch for much faster transcription. Replace cu118 with your CUDA version (cu117, cu121, etc.):
pip install torch --index-url https://download.pytorch.org/whl/cu118After this, the GUI will detect your GPU automatically and select it by default.
- Log in to your Canvas instance (e.g.
cbscanvas.instructure.com) - Go to Account → Settings → New Access Token
- Give it a name, set an expiry if you want, and copy the token
The course ID is the number in the Canvas URL when you're on your course page:
https://cbscanvas.instructure.com/courses/43660
^^^^^
this is the course ID
python panopto_downloader.pyThe GUI will open. Fill in:
| Field | Description |
|---|---|
| Canvas API token | Your token from the step above (saved to config.json after first run) |
| Course ID | The number from your Canvas course URL |
| Output folder | Where MP3s (and transcripts) will be saved |
| Transcribe with Whisper | Check to auto-transcribe each download |
| Model | Whisper model size — turbo is the best balance of speed and accuracy |
| Language | auto works well; set da for Danish to improve accuracy |
| Device | GPU if available (much faster), CPU otherwise |
| Debug mode | Verbose log output — useful for troubleshooting |
Click ▶ Start Download. The app will:
- Discover all Panopto videos in the course (via Canvas API + LTI auth)
- Show you the full list in the log
- Download each one as an MP3
- Transcribe each one (if enabled)
Already-downloaded files are skipped automatically on re-runs.
For each video you get up to three files in your output folder:
01_Module Name - Video Title.mp3 ← audio
01_Module Name - Video Title.txt ← plain text transcript
01_Module Name - Video Title.srt ← timestamped subtitles
| Model | Size | Speed (CPU) | Speed (GPU) | Notes |
|---|---|---|---|---|
tiny |
75 MB | Fast | Very fast | Low accuracy |
base |
145 MB | Moderate | Fast | Decent for clear audio |
small |
465 MB | Slow | Fast | Good accuracy |
medium |
1.5 GB | Very slow | Moderate | High accuracy |
large |
3 GB | Very slow | Slow | Best accuracy |
turbo |
1.5 GB | Very slow | Fast | Best for GPU use |
For CPU-only use, small is a good compromise. For GPU, turbo or medium are recommended.
Settings are stored in config.json next to the script and loaded automatically on startup. You can edit this file directly if needed:
{
"canvas_api_token": "your_token_here",
"course_id": "43660",
"output_dir": "C:/path/to/downloads",
"transcribe": true,
"whisper_model": "turbo",
"whisper_language": "da",
"whisper_device": "cuda",
"debug": false
}- Verify your GPU supports CUDA (any NVIDIA card from the last ~10 years does)
- Install the CUDA-enabled torch:
pip install torch --index-url https://download.pytorch.org/whl/cu118 - Restart Python and try again
- Check:
python -c "import torch; print(torch.cuda.is_available())"
- Enable Debug mode in the GUI, run again, and click 📋 Copy log to see what's happening
- Some Canvas items are ExternalTool links that require an LTI handshake to resolve — the script handles this automatically, but a slow network can cause timeouts
- Windows: Download ffmpeg, extract it, and add the
bin/folder to your system PATH - macOS:
brew install ffmpeg - Verify:
ffmpeg -version
Your Canvas API token may have expired. Generate a new one in Canvas → Account → Settings.
Two diagnostic scripts are included for troubleshooting. Both read credentials from config.json automatically.
debug_canvas.py — dumps all Canvas module items and their fields. Useful for checking what the API returns for your course.
python debug_canvas.pydebug_lti.py — traces the full Canvas → Panopto LTI authentication chain step by step. Useful for diagnosing auth failures.
python debug_lti.pyCBS Panopto uses LTI 1.3 (Learning Tools Interoperability) for authentication — a multi-step OpenID Connect handshake between Canvas and Panopto. The script replicates what a browser does when you click a Panopto link in Canvas:
- Call the Canvas
sessionless_launchAPI to get a one-time launch URL - GET the launch URL → Canvas returns an auto-submit HTML form
- POST the form to Panopto's OIDC login endpoint
- Panopto redirects to Canvas's OIDC
/authorizeendpoint - Canvas returns a signed
id_tokenform - POST the
id_tokenback to Panopto'sredirect_uri - Panopto verifies the token, sets session cookies, and redirects to
Embed.aspx?id=REAL_VIDEO_ID
The real video ID (from Embed.aspx) is then used to call Panopto's DeliveryInfo.aspx API, which returns the actual stream URL. ffmpeg downloads the stream as an MP3.
MIT