ytdl-org/youtube-dl · error · ExtractorError

Unable to find video URL

Error message

Unable to find video URL

What it means

Raised by TeachableIE._real_extract when the lecture page contains no Wistia embed URLs (WistiaIE._extract_urls returns empty) AND none of the 'locked' markers (lecture-contents-locked, Lecture contents locked, lecture-locked, lesson-locked, LESSON LOCKED) are present. Not marked expected=True. It means the page loaded but the extractor found neither a player it recognizes nor a known lock screen.

Source

Thrown at youtube_dl/extractor/teachable.py:176

        self._login(site)

        prefixed = url.startswith(self._URL_PREFIX)
        if prefixed:
            url = url[len(self._URL_PREFIX):]

        webpage = self._download_webpage(url, video_id)

        wistia_urls = WistiaIE._extract_urls(webpage)
        if not wistia_urls:
            if any(re.search(p, webpage) for p in (
                    r'class=["\']lecture-contents-locked',
                    r'>\s*Lecture contents locked',
                    r'id=["\']lecture-locked',
                    # https://academy.tailoredtutors.co.uk/courses/108779/lectures/1955313
                    r'class=["\'](?:inner-)?lesson-locked',
                    r'>LESSON LOCKED<')):
                self.raise_login_required('Lecture contents locked')
            raise ExtractorError('Unable to find video URL')

        title = self._og_search_title(webpage, default=None)

        chapter = None
        chapter_number = None
        section_item = self._search_regex(
            r'(?s)(?P<li><li[^>]+\bdata-lecture-id=["\']%s[^>]+>.+?</li>)' % video_id,
            webpage, 'section item', default=None, group='li')
        if section_item:
            chapter_number = int_or_none(self._search_regex(
                r'data-ss-position=["\'](\d+)', section_item, 'section id',
                default=None))
            if chapter_number is not None:
                sections = []
                for s in re.findall(
                        r'(?s)<div[^>]+\bclass=["\']section-title[^>]+>(.+?)</div>', webpage):
                    section = strip_or_none(clean_html(s))
                    if not section:

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Open the lecture in a browser (logged in) and check what hosts the video; if it is not Wistia, use the matching extractor for the embed URL found in the page/network tab.
  2. Ensure you are authenticated: pass --username/--password or --cookies — some lectures only render the player for enrolled users, without the locked markers this extractor checks.
  3. Upgrade to yt-dlp, whose Teachable/Wistia handling is actively maintained for new embed formats.
  4. If the lecture genuinely has no video (text/attachment only), there is nothing to download; pick an actual video lecture URL.

Example fix

# before: lecture uses a non-Wistia embed
# youtube-dlc https://school.teachable.com/courses/x/lectures/123
# after: extract embed URL from page source, then use its extractor
# view-source -> find iframe src, e.g. https://www.youtube.com/embed/XYZ
# youtube-dl https://www.youtube.com/watch?v=XYZ
Defensive patterns

Strategy: fallback

Validate before calling

# Check for a playable embed before invoking the extractor
html = ydl.urlopen(url).read().decode('utf-8', 'replace')
if 'wistia' not in html.lower():
    print('no Wistia embed found; lecture may use another provider or require login')

Try / catch

try:
    info = ydl.extract_info(url)
except ExtractorError as e:
    if 'Unable to find video URL' in str(e):
        info = try_with_cookies(url) or extract_embed_manually(html)
    if hasattr(e, 'exc_info') and 'Lecture contents locked' in str(e):
        raise  # needs login, not a markup issue
    raise

Prevention

When it happens

Trigger: Extracting /courses/<course>/lectures/<id> on a Teachable site where the video is embedded via a provider other than Wistia, the lecture has only attachments/text, or the page markup changed so the Wistia URL pattern no longer matches.

Common situations: Teachable schools embedding with YouTube/Vimeo/Wistia-new-embed after platform updates; lectures that are quizzes or PDF-only; enrolling changes that render lecture HTML differently for enrolled vs preview users.

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/5e3f76612b806496. Report an issue: GitHub.