An online trainer signs 400 new learners on Monday. Tuesday morning, lesson 3 — 45 minutes of video — takes 90 seconds to start. Support tickets flood in: "it loads, then drops." The team added a "protect my videos" plugin that checks the PHP session before every HLS segment. Result: stronger security, destroyed experience.
E-learning platforms live in permanent tension: protect paid content without making every learner pay in latency. It is not a binary "secure or fast" choice — it is about where you place authentication, encryption, and especially who serves the video bytes.
Separate LMS, API, and video delivery
| Layer | Role | Common mistake |
|---|---|---|
| LMS (Moodle, WordPress + LMS) | Auth, progress, quizzes | Serving MP4 from /wp-content/ |
| API / backend | Issues tokens, course rights | 24 h token on direct URL |
| Object storage | Source files, HLS segments | No CDN in front |
| CDN | Cache segments near learner | Public cache without edge validation |
Healthy flow: learner authenticates on LMS → backend issues a short signed URL (5–15 min) to the HLS manifest → CDN validates signature or uses origin shield → segments never hit PHP-FPM.
If video goes through a PHP worker, you do not have a security problem — you have an architectural bottleneck.
Protection: what works, what is theater
Effective:
- Signed URLs (AWS CloudFront, Scaleway, Cloudflare Stream tokens).
- HLS with short segments + mid-session token renewal.
- Dynamic watermark (email or learner ID) on premium content — higher encode cost.
- Per-account rate limit on manifest download.
Theater:
- "Right-click disabled" on the player.
- JavaScript obfuscation of MP4 link (extracted in 30 seconds).
- Static token in a URL shared on Discord.
Bandwidth sizing and cost
Baseline formula for live or concurrent peak:
Required Mbps ≈ (video bitrate × simultaneous viewers) / 1000
Example: 720p at 3 Mbps, 150 parallel learners → ~450 Mbps + CDN headroom = 600 Mbps at peak. A 1 Gbps VPS looks wide — until origin also serves PDFs, course images, and LMS requests.
| Scenario | Origin only | Object + CDN |
|---|---|---|
| 50 async learners | OK | Comfortable |
| 200 learners same hour | Limit | Recommended |
| 500+ live webinar | Insufficient | Mandatory + live provider |
Watch egress: some clouds charge heavily for exit to CDN or end users. Compare offers with documented outbound traffic in our directory.
LMS and European hosting
Learner data (GDPR) and videos may have different requirements:
- Personal data: LMS in EU, signed DPA, limited access logs.
- Videos: object region + European CDN PoPs; check if provider transcodes in the US.
Do not confuse "European host" on the LMS sheet with "all video stack in EU." Ask for the full map: encode, storage, CDN, player analytics.
Mistakes that slow everyone down
- PHP auth on every HLS chunk — validate at manifest + CDN cookies or signed URLs.
- Single non-adaptive MP4 — mobiles on 4G buffer, support explodes.
- Uncontrolled prefetch — player loads 10 lessons; bill and latency rise.
- Quiz and video on same PHP-FPM pool — isolate workers or move API to async stack.
The peak: securing in the wrong place costs more than casual piracy
Marketing sells "secure content." Ops must deliver time-to-first-frame < 3 s on median French 4G — otherwise completion drops before any DRM debate.
Decide and move forward without blind spots
- Map the video path from upload to learner (encode, storage, CDN).
- Measure time-to-first-frame on simulated 4G, not office fiber only.
- Externalize streaming from 50 GB video or 100 credible concurrent learners.
- Short tokens + renewal; audit shared URLs in logs.
- 12-month egress budget with catalog growth.
See also Scaleway Object Storage for media and the compare tool to filter by object storage.
Frequently asked questions
Should videos live on the same server as the LMS?
No. Object + CDN or dedicated video service; LMS server does not stream heavy MP4s.
Are signed URLs enough to stop sharing?
They limit hotlinking and direct access, not capture or determined re-streaming. Combine short tokens and watermark if needed.
Which format should you prefer for streaming?
Adaptive HLS or DASH matched to learner bandwidth.
How do you size bandwidth?
Duration × bitrate × concurrent learners × headroom; origin does not carry peak alone.
Protect courses where bytes flow — not in a PHP plugin that makes every learner wait before every second of video.