Course video in 2026: where to host it, and how to make sure every learner can watch

Christopher Ross

12 min read

AI and learning, kept human · Niagara, Ontario

Three video hosting paths laid out side by side: YouTube for organic discovery, Vimeo or self-hosted CDN for on-site conversion, and signed-URL delivery for private gated content

The first time a learner emailed to tell me a WP101 lesson had stopped playing overnight, I knew what had happened before I finished reading the message. The signed URL behind the video had expired while their browser tab sat open, so the lesson they had paid to watch came back the next morning as a permissions error. That particular gotcha is buried four levels deep in someone else’s documentation, and I only know it because I run that video myself, on this site, for real learners.

I get asked “should we just put the course on YouTube™?” more than almost any other video question, and my answer is always the same. It depends on what the video is doing. A marketing clip and a course lesson look identical in the upload dialog and could not be more different in what they actually need. Get the difference wrong and you either hand your learners’ attention to a competitor’s thumbnail, or, worse, you lock some of them out of the lesson entirely.

So here is the frame I wish more education teams started from. A teaching video carries two jobs a marketing video never does. It has to stay with the people who enrolled, and every one of those people has to be able to watch it. Cost comes third. Get those first two right and the host mostly picks itself.

The two jobs a teaching video has to do

A marketing video wants to be found. You want it in front of strangers, on as many screens as possible, and you measure it by reach. A course video wants the opposite. It should reach exactly the learners who signed up, and it should reach all of them.

That flips the whole decision. Discovery, the thing YouTube is unbeatable at, is a feature you mostly do not want for a lesson. What you want instead is gated delivery, so the video stays behind the enrolment, and access, so no learner is left staring at a player they cannot use. Those two demands quietly rule out the easy default and point you at a much shorter list of hosts.

Access is the job

Captions, a transcript on the page, and a player that works with a keyboard and reads cleanly to a screen reader. On a teaching video these decide whether the lesson works at all, long before anyone gets to the compliance checklist.

Picture the learners who actually open your course. One is watching at eleven at night, the evening before an assessment, in a room where other people are asleep, so the sound is off and the captions are the lesson. Another reads English faster than they hear it, so the transcript is how they keep up. A third is deaf or hard of hearing. Someone else is on a train with two bars of signal, scrolling the transcript because the video will not load. Captions and a transcript serve every one of them at once, and none of it makes the lesson any harder for the learner who does not need it. It just makes the lesson possible for the ones who do.

In Canada and most of the institutions I build for, this is also the line between a course you can sell to a school board and one you cannot. But I would put the captions on even if no rule asked me to, because a lesson a learner cannot follow is not a lesson. It is a video you were paid to make watchable and did not.

Why unlisted YouTube is not a private classroom

The most common shortcut is to upload the course to YouTube, mark the lessons unlisted, and call them private. Unlisted means anyone holding the link can watch, and the URL pattern can still be indexed, so treat an unlisted lesson as a public video with a quiet address.

Two more things bite you the moment you embed that player in a course. The end-screen pulls the learner away, so a lesson finishes and YouTube offers three unrelated videos, and the learner who was mid-course is now one click into someone else’s content. And under most privacy regimes the embed triggers a tracking-cookie disclosure, so every learner meets a consent banner before a lesson they have already paid to watch. I moved the WP101 course off an embedded player partly to kill that banner. It was the thing that surprised me least and annoyed me most, a cookie dialog standing between a paying learner and lesson one.

The five ways to host, read through a teaching lens

I have run, tested, or pulled apart all five of these for one client or another. Here is how each one reads once you judge it as a place to keep course video rather than as a place to get famous. I checked vendor pricing in July 2026, every figure is USD unless I say otherwise, and this stuff moves, so verify against the vendor’s own page before it goes in a budget.

YouTube is free and effectively uncapped, and it is the only real answer for the discovery side of your marketing, the trailer and the free sample lesson you want strangers to find. It is the wrong home for the classroom itself, for every reason above. Use it to sell the course, not to deliver it.

Vimeo™, roughly twenty to seventy-five dollars a month, gives you a clean player with no end-screen distraction, captions, and privacy controls that are solid enough for team training or a course behind a single password. It is the simplest paid option when the gating bar is “behind a password” rather than “one login per learner.”

VideoPress™, the Jetpack™ option, is WordPress-native, with no third-party domain and no heavy JavaScript. It fits a site already on Jetpack and lessons that live inside post content. It gives up ground on bandwidth allowances and on the finer privacy controls a real learning management system wants.

Cloudflare™ Stream is the managed option most comparison articles do not have a name for. Cloudflare runs the encoding, delivery, and gating, and there is no public gallery where anyone browses your videos. It hands you signed-URL gating at every paid tier, a very light embed, caption tracks, and per-minute billing. For an LMS where every lesson needs to be locked to a logged-in learner, it is the strongest fit on this list.

The fifth option is self-hosting on a content delivery network, your files on Cloudflare R2, Bunny.net™, or Amazon S3™ with CloudFront™, played through a clean HTML5 video element. You own the file and the player and the total cost stays low, but the chrome is your problem. No dashboard out of the box, transcoding to arrange, captions to wire, the player to build.

Side by side, judged on the two jobs a lesson has to do:

HostBest forGatingCaptionsCost (USD, checked July 2026)
YouTubeDiscovery: the trailer and the free sample lessonPublic or unlisted only; the link is the accessAuto-generated, then cleaned by youFree
VimeoTeam training, or a course behind a single passwordPassword and privacy controlsUploaded caption fileRoughly $20 to $75 a month
VideoPress (Jetpack)A site already on Jetpack, lessons inside post contentLimited fine-grained privacy controlsCheck the vendor pageSee your Jetpack plan
Cloudflare StreamAn LMS where every lesson is locked to a logged-in learnerSigned URLs on every paid tier, tokens up to 24 hoursUploaded WebVTT trackPer minute; about $1 per 1,000 delivered minutes, storage extra
Self-hosted on a CDN (R2, Bunny.net, S3 with CloudFront)Owning the whole stack, with the engineering time to wire itSigned URLs you build yourselfWebVTT track you supplyLow; the player, transcoding and dashboard are your job

Cloudflare Stream, from a working course

I use Stream for the WP101 course on this site, so what follows is from a running install rather than a marketing page.

The embed is genuinely light. Stream’s player loads one script and drags no ad-tracking beacons along behind it, which on a course page you care about because a slow lesson is a lesson learners abandon. The gating is the real reason to pick it over Vimeo. You get time-limited signed tokens, up to twenty-four hours, optionally restricted by address or country, on every paid tier rather than behind a top plan. Captions ride along as an uploaded WebVTT track, so the accessibility layer lives with the video instead of being reinvented per page.

The pricing rewards exactly the course pattern, one video delivered many times. Fifty minutes of lessons delivered to a thousand learners a month is fifty thousand delivered minutes, which at roughly one dollar per thousand delivered minutes lands near fifty dollars a month, with storage for those fifty minutes coming in around a quarter.

And here is where my learner’s overnight email came from. That twenty-four-hour token is a maximum. If a learner opens a lesson, walks away, and comes back the next day, the signed URL sitting in their tab has expired and the video returns a permissions error on resume. Either you accept the page reload and tell learners why it happens, or you wire a small handler that fetches a fresh token when the tab comes back into focus. Stream’s marketing does not mention this. The docs do, in a line that is very easy to skim past. I skimmed past it, and a learner found it for me.

The coffee analogy: same pot, different amount of brewing

When a client asks me which of these is simply “best,” I reach for coffee. Every cup starts from beans and water, but the grind, the roast, and what you pour in change the result completely. Self-hosting and Stream pour from the same pot here. Both give you a light player and signed-URL gating and captions. The only real difference is how much of the brewing you want to do yourself. Self-hosting hands you full control of the file and the player in exchange for wiring it all together. Stream hands you the same outcomes with the wiring already done, in exchange for living on someone else’s platform. They are the same cup made two ways.

Where captions and transcripts actually come from

This is the step teams forget, so decide it before you pick a host. YouTube auto-generates captions you then have to clean, because the raw machine pass mangles names and terms. Vimeo takes an uploaded caption file. Stream and self-hosted both take a WebVTT track you supply, and both leave the on-page transcript to you.

Put that transcript on the lesson page on purpose. It is the accessibility layer first, the thing that lets a learner read what they cannot hear. It happens to double as indexable text and as a study aid learners can search, but lead with the access reason, because that is the one that decides whether the lesson reaches everyone. For a content team this is a one-time template task rather than a per-video chore, but only if someone owns it. On the WP101 lessons, that someone was me, and I only learned it was mine to own after Stream handed me a clean player and quietly handed the captions and schema back.

A short decision before you commit

List the videos you will publish in the next year and label each one discovery, conversion, or private. Group them. For anything labelled discovery, the free sample and the trailer, default to YouTube and let strangers find it.

For the course itself, two things are not up for debate. It has to be gated to your learners, and it has to be captioned and transcribed. Default to Cloudflare Stream with signed URLs, because it gives you both without heroics. Reach for self-hosting instead if you want to own the whole stack and have the engineering time to wire the player and the token refresh. Reach for Vimeo Pro if the gating bar is genuinely just “behind a password.” Whichever you pick, write down where the captions, the transcript, and the poster image come from for every lesson. If the honest answer is “the instructor’s spare time,” the access work will not happen, and you will find out from a learner rather than a report.

If the honest answer is “the instructor’s spare time,” the access work will not happen, and you will find out from a learner rather than a report.

When to bring someone in

The moment worth outside help is usually a migration. A course already sitting on embedded YouTube, moving to a gated workflow while trying to keep the pages that rank, needs a redirect plan and a caption plan written before anything moves. Standing up Cloudflare Stream for an LMS build is the other one. The signed-URL token mint, the refresh handler that stops the overnight-tab error, and the per-learner access rules are worth doing correctly the first time, because the failure mode is a learner locked out of a paid lesson at seven in the morning.

If your team is arguing about video hosting and nobody can say plainly what each video is for, that conversation belongs to whoever owns the learning experience before it belongs to whoever owns the servers. Start by watching one of your own lessons the way a real learner does. On a phone, late at night, with the sound off, ideally on a train with two bars of signal. Whatever you cannot follow that way is the first thing to fix.

Getting course video right, so every learner can actually watch, is one piece of building a learning platform that holds up under real students. If you are standing up or fixing a course and want the delivery done properly, that is the work I do. Start with a call.

Working through something on your own site? Get in touch →

Leave a reply

Your email address will not be published. Required fields are marked *

Your rating (optional)

Your name and email are stored with your comment; only your display name is shown publicly. See our privacy policy.