Skill: upupc/video-download (version 0.1.6)

--- name: video-download description: Download videos from 1800+ websites and generate subtitles using Faster Whisper AI. Use when user wants to download videos from YouTube, Bilibili, Twitter, TikTok, Facebook, Vimeo, or any other supported video site, extract audio, or transcribe video content to text/subtitles. metadata: { "openclaw": { "homepage": "https://github.com/upupc/video-download", "emoji": "🎬", "requires": { "bins": ["python", "ffmpeg"], "env": [] }, "primaryEnv": "", "install": [ { "id": "pip", "kind": "pip", "packages": ["yt-dlp", "yt-dlp-ejs", "ffmpeg-python", "faster-whisper", "tqdm"], "label": "Install dependencies (pip)", } ], }, } --- # Video Download & Subtitle Generation This skill downloads videos from 1800+ websites and generates subtitles using Faster Whisper AI. ## Supported Websites This skill supports downloading from virtually any video website thanks to yt-dlp. Some popular ones include: **Video Platforms:** - YouTube, YouTube Shorts - Bilibili (哔哩哔哩), Niconico (ニコニコ動画) - TikTok, Douyin (抖音) - Twitter/X, Facebook, Instagram - Vimeo, Dailymotion - Twitch (clips, VODs), Kick - Rutube, VK Video **Chinese Platforms:** - iQiyi (爱奇艺), Youku (优酷), MangoTV (芒果TV) - Weibo Video, Douyu (斗鱼), Huya (虎牙) **International:** - Netflix, Disney+, HBO Max, Amazon Prime Video - BBC iPlayer, ITV, Channel 4 - ARD, ZDF, Arte For the complete list of 1800+ supported sites, see: [yt-dlp supported extractors](https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md) Local document about supported sites: references/supportedsites.md **Important:** If you see an error like `Sign in to confirm you’re not a bot`, you should use the `cookiefile` parameter for authenticated downloads. See the `cookiefile` usage section at the end of this document. ## Prerequisites Ensure the following Python packages are installed: - `yt-dlp` - For downloading videos from any supported site - `yt-dlp-ejs` - External JavaScript for yt-dlp supporting many runtimes - `ffmpeg-python` - For audio extraction - `faster-whisper` - For speech-to-text transcription (faster and more memory-efficient than openai-whisper). **Note**: The first run will download models from HuggingFace (default: small, ~3GB). A VPN is required for mainland China users. - `tqdm` - For progress bar display during transcription Install via pip: ```bash pip install yt-dlp yt-dlp-ejs ffmpeg-python faster-whisper tqdm ``` ffmpeg must also be installed on your system ## Usage ### Command Line ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID"],"output":"./downloads"}' ``` ## Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `urls` | array | Yes | List of video URLs from any supported website | | `output` | string | No | Output directory (default: "./downloads") | | `model` | string | No | Faster Whisper model size: tiny, base, small, medium, large, large-v2, large-v3, turbo (default: "small") | | `transcribe` | boolean | No | Whether to transcribe video to subtitle (default: true) | | `subtitle_format` | string | No | Subtitle format: txt, srt, vtt, json (default: "txt") | | `download_subtitle` | boolean | No | Download video's built-in subtitles if available (default: false) | | `onlysubtitle` | boolean | No | Only download subtitles. When `true`, the script uses `skip_download + writesubtitles + writeautomaticsub` internally (default: false) | | `overwrite_subtitle` | boolean | No | Overwrite existing subtitle files (default: true, set to false to skip if exists) | | `cookie` | string | No | Cookie header string; injected into `http_headers.Cookie` (default: "") | | `cookiesfrombrowser` | string | No | Read cookies from browser (default: ""; injected only when non-empty) | | `cookiefile` | string | No | Netscape-format cookie file path (default: ""; injected only when non-empty) | ## Output The skill will: 1. Create a folder for each video (named after the video title) 2. Download the video file to that folder 3. Extract audio as WAV file 4. Generate transcript using Faster Whisper 5. Save subtitle as .txt file Output structure: ``` downloads/ └── Video Title/ ├── Video Title.mp4 ├── Video Title.wav └── Video Title.txt ``` ## Examples ### Download YouTube video: ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],"output":"./my_videos"}' ``` ### Download Bilibili video: ```bash python scripts/video_parser.py '{"urls":["https://www.bilibili.com/video/BV1xx411c7XD"],"output":"./downloads"}' ``` ### Download TikTok video: ```bash python scripts/video_parser.py '{"urls":["https://www.tiktok.com/@username/video/1234567890"],"output":"./tiktok"}' ``` ### Download multiple videos from different sites: ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO1","https://www.bilibili.com/video/BV1xx","https://twitter.com/user/status/123"],"output":"./videos"}' ``` ### Download Twitch clip: ```bash python scripts/video_parser.py '{"urls":["https://www.twitch.tv//channel/clip/ClipName"],"output":"./clips"}' ``` ### Download only (without transcription): ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID"],"output":"./downloads","transcribe":false}' ``` ### Generate SRT subtitle: ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID"],"output":"./downloads","subtitle_format":"srt"}' ``` ### Generate VTT subtitle: ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID"],"output":"./downloads","subtitle_format":"vtt"}' ``` ### Download video with built-in subtitles: ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID"],"output":"./downloads","download_subtitle":true}' ``` ### Download with custom Faster Whisper model: ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID"],"output":"./downloads","model":"large"}' ``` ### Skip transcription if subtitle already exists: ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID"],"output":"./downloads","overwrite_subtitle":false}' ``` ### Download video with Cookie: ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID"],"output":"./downloads","cookie":"sid=xxx; token=yyy"}' ``` ### Download video with cookies from browser: ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID"],"output":"./downloads","cookiesfrombrowser":"chrome"}' ``` ### Download video with cookie file: ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID"],"output":"./downloads","cookiefile":"/path/to/cookies.txt"}' ``` ### Only download subtitles: ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID"],"output":"./downloads","onlysubtitle":true,"cookiefile":"/path/to/cookies.txt"}' ``` `cookiefile` usage: - Install the **Get cookies.txt LOCALLY** Chrome extension first. URL: <https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc?pli=1> - Log in to the target website, then use the extension to export `cookies.txt` to your local machine. - Set `cookiefile` to that local file path, for example: ```bash python scripts/video_parser.py '{"urls":["https://www.youtube.com/watch?v=VIDEO_ID"],"output":"./downloads","cookiefile":"/Users/yourname/Downloads/cookies.txt"}' ``` ## Troubleshooting - **ffmpeg not found**: Install ffmpeg via `brew install ffmpeg` (macOS) or your system's package manager - **Faster Whisper model download fails**: Models are downloaded from HuggingFace. Mainland China users need a VPN/proxy to download models. The default small model is ~75MB. - **Download fails**: Some videos may be geo-restricted, age-gated, or unavailable. Check the video URL and try again. - **Cookie/auth required**: Some sites need authentication. You can pass cookies via yt-dlp options if needed.

path: _meta.json
content: ownerId: kn7f567jjqtcmrtj07nhsczp9h80zjzj
slug: video-download
version: 0.1.5
publishedAt: 1771306140332

path: scripts/video_parser.py
content: import sys
import os
import glob
import yt_dlp
from faster_whisper import WhisperModel
import json
import tqdm

COMMON_SUBTITLE_EXTENSIONS = (
    "srt",
    "vtt",
    "ass",
    "ssa",
    "lrc",
    "sub",
    "sbv",
    "ttml",
    "dfxp",
    "json",
    "txt",
)


def find_existing_subtitles(video_folder: str, audio_filename: str) -> list:
    """查找已存在的字幕文件，支持 video.ext 和 video.<lang>.ext 格式"""
    subtitle_candidates = glob.glob(os.path.join(video_folder, f"{audio_filename}.*"))
    existing_subtitles = []
    for candidate in subtitle_candidates:
        basename = os.path.basename(candidate)
        if not basename.startswith(f"{audio_filename}."):
            continue
        suffix_parts = basename[len(audio_filename) + 1:].split(".")
        if suffix_parts and suffix_parts[-1].lower() in COMMON_SUBTITLE_EXTENSIONS:
            existing_subtitles.append(candidate)
    return sorted(existing_subtitles)


def extract_audio(video_path: str) -> str:
    """从视频中提取音频"""
    import ffmpeg

    audio_path = os.path.splitext(video_path)[0] + '.wav'
    stream = ffmpeg.input(video_path)
    stream = ffmpeg.output(stream, audio_path, acodec='pcm_s16le', ar=16000)
    ffmpeg.run(stream, overwrite_output=True, quiet=True)
    return audio_path


def transcribe_audio(audio_path: str, model: WhisperModel) -> dict:
    """使用Faster Whisper转录音频

    Args:
        audio_path: 音频文件路径
        model: Faster Whisper模型
    """

    # 获取转录结果和信息
    result, info = model.transcribe(audio=audio_path)

    # 收集所有片段，带进度条
    segments = []
    with tqdm.tqdm(total=info.duration, unit="seconds", desc="Transcribing") as pbar:
        for segment in result:
            segments.append({
                "start": segment.start,
                "end": segment.end,
                "text": segment.text
            })
            pbar.update(segment.end - pbar.n)

    # 获取完整文本
    text = "".join([seg["text"] for seg in segments])

    return {
        "text": text,
        "segments": segments
    }


def save_subtitle(audio_path: str, result: dict, output_folder: str, subtitle_format: str = 'txt'):
    """保存字幕文件

    Args:
        audio_path: 音频文件路径
        result: Faster Whisper 转录结果
        output_folder: 输出目录
        subtitle_format: 字幕格式，支持: txt, srt, vtt, json
    """
    # 获取不带扩展名的音频文件名
    audio_filename = os.path.splitext(os.path.basename(audio_path))[0]
    output_path = os.path.join(output_folder, f"{audio_filename}.{subtitle_format.lower()}")

    if subtitle_format.lower() == 'txt':
        # 纯文本格式：直接保存所有文本
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(result['text'].strip())

    elif subtitle_format.lower() == 'json':
        # JSON格式
        import json
        with open(output_path, 'w', encoding='utf-8') as f:
            json.dump(result, f, ensure_ascii=False, indent=2)

    elif subtitle_format.lower() == 'srt':
        # SRT格式
        with open(output_path, 'w', encoding='utf-8') as f:
            for idx, seg in enumerate(result['segments'], 1):
                # SRT时间格式: HH:MM:SS,mmm
                start_time = format_srt_time(seg['start'])
                end_time = format_srt_time(seg['end'])
                # 清理文本，去除多余空格
                text = seg['text'].strip()
                f.write(f"{idx}\n{start_time} --> {end_time}\n{text}\n\n")

    elif subtitle_format.lower() == 'vtt':
        # VTT格式
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write("WEBVTT\n\n")
            for seg in result['segments']:
                # VTT时间格式: HH:MM:SS.mmm
                start_time = format_vtt_time(seg['start'])
                end_time = format_vtt_time(seg['end'])
                # 清理文本，去除多余空格
                text = seg['text'].strip()
                f.write(f"{start_time} --> {end_time}\n{text}\n\n")

    return output_path


def format_srt_time(seconds: float) -> str:
    """将秒数转换为SRT时间格式 HH:MM:SS,mmm"""
    hours = int(seconds // 3600)
    minutes = int((seconds % 3600) // 60)
    secs = int(seconds % 60)
    millis = int((seconds % 1) * 1000)
    return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"


def format_vtt_time(seconds: float) -> str:
    """将秒数转换为VTT时间格式 HH:MM:SS.mmm"""
    hours = int(seconds // 3600)
    minutes = int((seconds % 3600) // 60)
    secs = int(seconds % 60)
    millis = int((seconds % 1) * 1000)
    return f"{hours:02d}:{minutes:02d}:{secs:02d}.{millis:03d}"


def choose_subtitle_language_and_format(subtitle_map: dict) -> tuple:
    """从字幕信息中选择语言与格式：英文优先，其次中文；格式优先txt。"""
    if not subtitle_map:
        return None, None

    normalized = {}
    for lang, tracks in subtitle_map.items():
        if not tracks:
            continue
        exts = []
        for track in tracks:
            ext = (track.get("ext") or "").lower()
            if ext:
                exts.append(ext)
        if exts:
            normalized[lang] = exts

    if not normalized:
        return None, None

    def pick_format(exts: list) -> str:
        if "txt" in exts:
            return "txt"
        if "srt" in exts:
            return "srt"
        if "vtt" in exts:
            return "vtt"
        return exts[0]

    english_candidates = {"en", "en-us", "en-gb", "english"}
    chinese_candidates = {"zh", "zh-cn", "zh-hans", "zh-hant", "zh-tw", "chinese"}

    def normalize_lang(lang: str) -> str:
        return lang.lower().replace("_", "-")

    for lang in normalized:
        lang_norm = normalize_lang(lang)
        if lang_norm in english_candidates or lang_norm.startswith("en-"):
            return lang, pick_format(normalized[lang])

    for lang in normalized:
        lang_norm = normalize_lang(lang)
        if lang_norm in chinese_candidates or lang_norm.startswith("zh-"):
            return lang, pick_format(normalized[lang])

    fallback_lang = next(iter(normalized.keys()))
    return fallback_lang, pick_format(normalized[fallback_lang])


def download_subtitle(json_input: str) -> dict:
    """仅下载字幕：onlysubtitle=true 时使用。"""
    try:
        params = json.loads(json_input)
    except json.JSONDecodeError as e:
        return {"success": False, "message": f"JSON解析失败: {str(e)}", "results": []}

    urls = params.get("urls", [])
    output_path = params.get("output", "./downloads")
    onlysubtitle = params.get("onlysubtitle", False)
    cookie = params.get("cookie", "")
    cookiesfrombrowser = params.get("cookiesfrombrowser", "")
    cookiefile = params.get("cookiefile", "")

    if not urls:
        return {"success": False, "message": "URL列表为空", "results": []}
    if not onlysubtitle:
        return {"success": False, "message": "onlysubtitle=false，不执行仅字幕下载逻辑", "results": []}

    os.makedirs(output_path, exist_ok=True)

    results = []
    success_count = 0

    base_opts = {"format": "bestvideo+bestaudio/best"}
    if cookie:
        base_opts["http_headers"] = {"Cookie": cookie}
    if cookiesfrombrowser:
        base_opts["cookiesfrombrowser"] = (cookiesfrombrowser,)
    if cookiefile:
        base_opts["cookiefile"] = cookiefile

    for idx, url in enumerate(urls, 1):
        try:
            with yt_dlp.YoutubeDL(base_opts) as ydl_probe:
                info = ydl_probe.extract_info(url, download=False)

            video_title = info.get("title", f"video_{idx}")
            safe_title = "".join(c for c in video_title if c.isalnum() or c in (" ", "-", "_")).strip() or f"video_{idx}"
            video_folder = os.path.join(output_path, safe_title)
            os.makedirs(video_folder, exist_ok=True)

            subtitle_map = {}
            subtitle_map.update(info.get("subtitles") or {})
            subtitle_map.update(info.get("automatic_captions") or {})
            selected_lang, selected_format = choose_subtitle_language_and_format(subtitle_map)

            if not selected_lang or not selected_format:
                results.append({
                    "url": url,
                    "success": False,
                    "subtitle_path": None,
                    "error": "未找到可用字幕"
                })
                continue

            download_opts = dict(base_opts)
            download_opts.update({
                "outtmpl": f"{video_folder}/%(title)s.%(ext)s",
                "skip_download": True,
                "writesubtitles": True,
                "writeautomaticsub": True,
                "subtitleslangs": [selected_lang],
                "subtitlesformat": selected_format
            })

            with yt_dlp.YoutubeDL(download_opts) as ydl_download:
                ydl_download.download([url])
                video_path = ydl_download.prepare_filename(info)

            subtitle_base = os.path.splitext(os.path.basename(video_path))[0]
            subtitle_files = find_existing_subtitles(video_folder, subtitle_base)
            if subtitle_files:
                success_count += 1
                results.append({
                    "url": url,
                    "success": True,
                    "subtitle_path": subtitle_files[0],
                    "error": None
                })
            else:
                results.append({
                    "url": url,
                    "success": False,
                    "subtitle_path": None,
                    "error": "字幕下载执行完成，但未找到字幕文件"
                })
        except Exception as e:
            results.append({
                "url": url,
                "success": False,
                "subtitle_path": None,
                "error": str(e)
            })

    overall_success = success_count > 0
    return {
        "success": overall_success,
        "message": f"仅字幕下载完成：成功 {success_count}/{len(urls)}",
        "results": results
    }


def download_videos(json_input: str) -> dict:
    """
    下载视频并转录

    Args:
        json_input: JSON字符串，支持以下参数:
            - urls: 视频URL列表 (必须)
            - output: 下载保存路径 (默认: "./downloads")
            - model: Faster Whisper模型名称 (默认: "small")
            - transcribe: 是否进行转录 (默认: True)
            - subtitle_format: 字幕格式，支持: txt, srt, vtt, json (默认: "txt")
            - download_subtitle: 是否下载视频自带字幕 (默认: False)
            - overwrite_subtitle: 是否覆盖已存在的字幕文件 (默认: True)
            - cookie: 可选，下载请求使用的 Cookie 字符串 (默认: "")
            - cookiesfrombrowser: 可选，从浏览器读取 cookies (默认: "")
            - cookiefile: 可选，Netscape 格式 cookie 文件路径 (默认: "")

    Returns:
        结果字典
    """
    try:
        params = json.loads(json_input)
    except json.JSONDecodeError as e:
        return {"success": False, "message": f"JSON解析失败: {str(e)}", "downloaded": [], "transcripts": []}

    urls = params.get("urls", [])
    output_path = params.get("output", "./downloads")
    model_name = params.get("model", "small")
    transcribe = params.get("transcribe", True)  # 是否进行转录
    subtitle_format = params.get("subtitle_format", "txt")  # 字幕格式
    download_subtitle = params.get("download_subtitle", False)  # 是否下载视频自带字幕
    overwrite_subtitle = params.get("overwrite_subtitle", True)  # 是否覆盖已存在的字幕文件
    cookie = params.get("cookie", "")  # 下载请求 Cookie
    cookiesfrombrowser = params.get("cookiesfrombrowser", "")  # 从浏览器读取 cookies
    cookiefile = params.get("cookiefile", "")  # cookie 文件路径

    if not urls:
        return {"success": False, "message": "URL列表为空", "downloaded": [], "transcripts": []}

    os.makedirs(output_path, exist_ok=True)

    downloaded = []
    video_list = []  # 存储下载后的视频信息，用于后续转录

    # ========== 第一步：下载所有视频 ==========
    print("=" * 50)
    print("开始下载视频...")
    print("=" * 50)

    ydl_opts = {
        'format': 'bestvideo+bestaudio/best',
    }

    if cookie:
        ydl_opts['http_headers'] = {
            'Cookie': cookie
        }
    if cookiesfrombrowser:
        ydl_opts['cookiesfrombrowser'] = (cookiesfrombrowser,)
    if cookiefile:
        ydl_opts['cookiefile'] = cookiefile

    language = 'en'
    # 如果需要下载视频自带的字幕
    if download_subtitle:
        ydl_opts['writesubtitles'] = True
        ydl_opts['writeautomaticsub'] = True
        ydl_opts['subtitleslangs'] = [language]
        ydl_opts['subtitlesformat'] = subtitle_format

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        for idx, url in enumerate(urls):
            try:
                # 先获取视频信息，确定文件夹名称
                info = ydl.extract_info(url, download=False)
                video_title = info.get('title', f'video_{idx + 1}')
                # 清理文件名中的非法字符
                safe_title = "".join(c for c in video_title if c.isalnum() or c in (' ', '-', '_')).strip()
                video_folder = os.path.join(output_path, safe_title)
                os.makedirs(video_folder, exist_ok=True)

                # 检查视频是否已存在
                video_path = ydl.prepare_filename(info)
                if os.path.exists(video_path):
                    print(f"[{video_title}] 文件已存在，跳过下载")
                    downloaded.append(url)
                    video_list.append({
                        "title": video_title,
                        "url": url,
                        "video_path": video_path,
                        "video_folder": video_folder
                    })
                    print(f"[{video_title}] 已添加到转录队列")
                    continue

                # 下载视频到对应文件夹
                ydl_opts['outtmpl'] = f'{video_folder}/%(title)s.%(ext)s'
                ydl_opts['progress_hooks'] = [lambda d, t=video_title: print_progress(d, t)]

                def print_progress(d, title):
                    if d['status'] == 'downloading':
                        total = d.get('total_bytes') or d.get('total_bytes_estimate', 0)
                        downloaded_bytes = d.get('downloaded_bytes', 0)
                        speed = d.get('speed', 0)

                        # 格式化文件大小
                        def format_size(bytes_val):
                            if bytes_val >= 1024 * 1024 * 1024:
                                return f"{bytes_val / 1024 / 1024 / 1024:.2f} GB"
                            elif bytes_val >= 1024 * 1024:
                                return f"{bytes_val / 1024 / 1024:.2f} MB"
                            elif bytes_val >= 1024:
                                return f"{bytes_val / 1024:.2f} KB"
                            else:
                                return f"{bytes_val} B"

                        speed_str = f"{speed / 1024 / 1024:.2f} MB/s" if speed else "N/A"
                        if total > 0:
                            percent = downloaded_bytes / total * 100
                            print(f"\r[{title}] {format_size(downloaded_bytes)} / {format_size(total)} ({percent:.1f}%) | 速度: {speed_str}", end='', flush=True)
                        else:
                            # 没有总大小时，只显示已下载大小和速度
                            print(f"\r[{title}] 已下载: {format_size(downloaded_bytes)} | 速度: {speed_str}", end='', flush=True)
                    elif d['status'] == 'finished':
                        total = d.get('total_bytes') or d.get('total_bytes_estimate', 0)

                        def format_size(bytes_val):
                            if bytes_val >= 1024 * 1024 * 1024:
                                return f"{bytes_val / 1024 / 1024 / 1024:.2f} GB"
                            elif bytes_val >= 1024 * 1024:
                                return f"{bytes_val / 1024 / 1024:.2f} MB"
                            elif bytes_val >= 1024:
                                return f"{bytes_val / 1024:.2f} KB"
                            else:
                                return f"{bytes_val} B"

                        print(f"\n[{title}] 下载完成! 文件大小: {format_size(total)}")

                with yt_dlp.YoutubeDL(ydl_opts) as ydl_video:
                    ydl_video.download([url])
                    video_path = ydl_video.prepare_filename(info)

                if os.path.exists(video_path):
                    downloaded.append(url)
                    video_list.append({
                        "title": video_title,
                        "url": url,
                        "video_path": video_path,
                        "video_folder": video_folder
                    })
                    print(f"[{video_title}] 已添加到转录队列")
            except Exception as e:
                print(f"下载失败 {url}: {str(e)}")

    # ========== 第二步：转录所有视频 ==========
    if not transcribe:
        # 不需要转录，只下载视频
        print("\n" + "=" * 50)
        print("视频下载完成 (跳过转录)")
        print("=" * 50)
        return {
            "success": True,
            "message": f"成功下载 {len(downloaded)} 个视频 (跳过转录)",
            "downloaded": downloaded,
            "transcripts": []
        }

    if not video_list:
        return {
            "success": False,
            "message": "未下载到任何视频，程序退出",
            "downloaded": downloaded,
            "transcripts": []
        }

    transcripts = []
    pending_video_list = []
    if not overwrite_subtitle:
        for idx, video_info in enumerate(video_list):
            video_title = video_info["title"]
            url = video_info["url"]
            video_path = video_info["video_path"]
            video_folder = video_info["video_folder"]
            audio_filename = os.path.splitext(os.path.basename(video_path))[0]
            existing_subtitles = find_existing_subtitles(video_folder, audio_filename)
            if existing_subtitles:
                subtitle_preview = ", ".join(os.path.basename(path) for path in existing_subtitles)
                print(f"\n[{idx + 1}/{len(video_list)}] 检测到已存在字幕文件，跳过转录: {video_title}")
                print(f"[{idx + 1}/{len(video_list)}] 已存在字幕: {subtitle_preview}")
                transcripts.append({
                    "title": video_title,
                    "url": url,
                    "transcript": existing_subtitles[0],
                    "format": subtitle_format
                })
            else:
                pending_video_list.append(video_info)
    else:
        pending_video_list = video_list

    if not pending_video_list:
        print("\n无需转录：所有视频均已存在字幕文件")
        return {
            "success": True,
            "message": f"成功下载 {len(downloaded)} 个视频，跳过 {len(transcripts)} 个转录（字幕已存在）",
            "downloaded": downloaded,
            "transcripts": transcripts
        }

    print("\n" + "=" * 50)
    print(f"视频下载完成，开始转录 {len(pending_video_list)} 个视频...")
    print("=" * 50)

    # 使用 Faster Whisper 加载模型
    # device: "auto" 自动选择 CUDA 或 CPU
    # compute_type: "auto" 自动选择最佳精度 (float16 for CUDA, int8 for CPU)
    model = WhisperModel(model_name, device="auto", compute_type="auto")
    for idx, video_info in enumerate(pending_video_list):
        video_title = video_info["title"]
        url = video_info["url"]
        video_path = video_info["video_path"]
        video_folder = video_info["video_folder"]

        print(f"\n[{idx + 1}/{len(pending_video_list)}] 正在提取音频: {video_title}")
        try:
            audio_path = extract_audio(video_path)
            print(f"[{idx + 1}/{len(pending_video_list)}] 正在转录: {video_title}")

            transcript = transcribe_audio(audio_path, model)
            print()  # 换行

            # 保存字幕文件
            print(f"[{idx + 1}/{len(pending_video_list)}] 正在保存字幕文件...")
            transcript_filename = save_subtitle(audio_path, transcript, video_folder, subtitle_format)
            print(f"[{idx + 1}/{len(pending_video_list)}] 字幕文件已保存")

            transcripts.append({
                "title": video_title,
                "url": url,
                "transcript": transcript_filename,
                "format": subtitle_format
            })
            print(f"[{idx + 1}/{len(pending_video_list)}] 转录完成: {video_title}")
        except Exception as e:
            print(f"转录失败 {video_title}: {str(e)}")
            transcripts.append({
                "title": video_title,
                "url": url,
                "transcript": None,
                "error": str(e)
            })

    return {
        "success": True,
        "message": f"成功下载 {len(downloaded)} 个视频，完成 {len([t for t in transcripts if t.get('transcript')])} 个转录",
        "downloaded": downloaded,
        "transcripts": transcripts
    }


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("用法: python video_parser.py '<JSON字符串>'")
        print()
        print("参数说明:")
        print("  urls: 视频URL列表 (必须)")
        print("  output: 下载保存路径 (默认: './downloads')")
        print("  model: Faster Whisper模型 (默认: 'small', 可选: tiny/base/small/medium/large/large-v2/large-v3/turbo)")
        print("  transcribe: 是否转录 (默认: True)")
        print("  subtitle_format: 字幕格式 (默认: 'txt', 可选: txt/srt/vtt/json)")
        print("  download_subtitle: 是否下载视频自带字幕 (默认: False)")
        print("  onlysubtitle: 是否仅下载字幕 (默认: False)")
        print("  overwrite_subtitle: 是否覆盖已存在的字幕文件 (默认: True)")
        print("  cookie: 下载请求 Cookie 字符串 (默认: '')")
        print("  cookiesfrombrowser: 从浏览器读取 cookies (默认: '')")
        print("  cookiefile: Netscape 格式 cookie 文件路径 (默认: '')")
        print()
        print('示例1 - 下载并转录: python video_parser.py \'{"urls":["URL"],"output":"./downloads"}\'')
        print('示例2 - 只下载不转录: python video_parser.py \'{"urls":["URL"],"output":"./downloads","transcribe":false}\'')
        print('示例3 - 生成SRT字幕: python video_parser.py \'{"urls":["URL"],"output":"./downloads","subtitle_format":"srt"}\'')
        print('示例4 - 下载视频自带字幕: python video_parser.py \'{"urls":["URL"],"output":"./downloads","download_subtitle":true}\'')
        print('示例5 - 不覆盖已有字幕: python video_parser.py \'{"urls":["URL"],"overwrite_subtitle":false}\'')
        print('示例6 - 携带 Cookie 下载: python video_parser.py \'{"urls":["URL"],"cookie":"sid=xxx; token=yyy"}\'')
        print('示例7 - 从浏览器读取 cookies: python video_parser.py \'{"urls":["URL"],"cookiesfrombrowser":"chrome"}\'')
        print('示例8 - 使用 cookie 文件下载: python video_parser.py \'{"urls":["URL"],"cookiefile":"/path/to/cookies.txt"}\'')
        print('示例9 - 仅下载字幕: python video_parser.py \'{"urls":["URL"],"output":"./downloads","onlysubtitle":true}\'')
        sys.exit(1)

    json_input = ''.join(sys.argv[1:])
    try:
        cli_params = json.loads(json_input)
    except json.JSONDecodeError:
        cli_params = {}

    if cli_params.get("onlysubtitle", False):
        subtitle_result = download_subtitle(json_input)
        failed_urls = [
            item.get("url")
            for item in subtitle_result.get("results", [])
            if item.get("url") and (
                not item.get("subtitle_path") or not os.path.exists(item.get("subtitle_path"))
            )
        ]

        if failed_urls:
            fallback_params = dict(cli_params)
            fallback_params["urls"] = failed_urls
            fallback_params["onlysubtitle"] = False
            fallback_result = download_videos(json.dumps(fallback_params, ensure_ascii=False))
            result = {
                "success": subtitle_result.get("success", False) or fallback_result.get("success", False),
                "message": (
                    f"{subtitle_result.get('message', '')}；"
                    f"未下载到字幕的链接已回退到视频下载流程：{fallback_result.get('message', '')}"
                ),
                "results": subtitle_result.get("results", []),
                "fallback": fallback_result
            }
        else:
            result = subtitle_result
    else:
        result = download_videos(json_input)

    print(result['message'])
    if 'results' in result:
        print(result['results'])
        if 'fallback' in result:
            print(result['fallback'].get('transcripts', []))
    else:
        print(result['transcripts'])


path: references/supportedsites.md
content: # Supported sites

Below is a list of all extractors that are currently included with yt-dlp.
If a site is not listed here, it might still be supported by yt-dlp's embed extraction or generic extractor.
Not all sites listed here are guaranteed to work; websites are constantly changing and sometimes this breaks yt-dlp's support for them.
The only reliable way to check if a site is supported is to try it.

 - **10play**: [*10play*](## "netrc machine")
 - **10play:season**
 - **17live**
 - **17live:clip**
 - **17live:vod**
 - **1News**: 1news.co.nz article videos
 - **1tv**: Первый канал
 - **1tv:live**: Первый канал (прямой эфир)
 - **20min**: (**Currently broken**)
 - **23video**
 - **247sports**: (**Currently broken**)
 - **24tv.ua**
 - **3qsdn**: 3Q SDN
 - **3sat**
 - **4tube**
 - **56.com**
 - **7plus**
 - **8tracks**
 - **9c9media**
 - **9gag**: 9GAG
 - **9News**
 - **9now.com.au**
 - **abc.net.au**
 - **abc.net.au:iview**
 - **abc.net.au:​iview:showseries**
 - **abcnews**
 - **abcnews:video**
 - **abcotvs**: ABC Owned Television Stations
 - **abcotvs:clips**
 - **AbemaTV**: [*abematv*](## "netrc machine")
 - **AbemaTVTitle**: [*abematv*](## "netrc machine")
 - **AcademicEarth:Course**
 - **acast**
 - **acast:channel**
 - **AcFunBangumi**
 - **AcFunVideo**
 - **ADN**: [*animationdigitalnetwork*](## "netrc machine") Animation Digital Network
 - **ADNSeason**: [*animationdigitalnetwork*](## "netrc machine") Animation Digital Network
 - **AdobeConnect**
 - **adobetv**
 - **AdultSwim**
 - **aenetworks**: A+E Networks: A&E, Lifetime, History.com, FYI Network and History Vault
 - **aenetworks:collection**
 - **aenetworks:show**
 - **AeonCo**
 - **agalega:videos**
 - **AirTV**
 - **AitubeKZVideo**
 - **Alibaba**
 - **AliExpressLive**
 - **AlJazeera**
 - **Allocine**
 - **Allstar**
 - **AllstarProfile**
 - **AlphaPorno**
 - **Alsace20TV**
 - **Alsace20TVEmbed**
 - **altcensored**
 - **altcensored:channel**
 - **Alura**: [*alura*](## "netrc machine")
 - **AluraCourse**: [*aluracourse*](## "netrc machine")
 - **AmadeusTV**
 - **Amara**
 - **AmazonMiniTV**
 - **amazonminitv:season**: Amazon MiniTV Season, "minitv:season:" prefix
 - **amazonminitv:series**: Amazon MiniTV Series, "minitv:series:" prefix
 - **AmazonReviews**
 - **AmazonStore**
 - **AMCNetworks**
 - **AmericasTestKitchen**
 - **AmericasTestKitchenSeason**
 - **AmHistoryChannel**
 - **AnchorFMEpisode**
 - **anderetijden**: npo.nl, ntr.nl, omroepwnl.nl, zapp.nl and npo3.nl
 - **Angel**
 - **AnimalPlanet**
 - **ant1newsgr:article**: ant1news.gr articles
 - **ant1newsgr:embed**: ant1news.gr embedded videos
 - **antenna:watch**: antenna.gr and ant1news.gr videos
 - **Anvato**
 - **aol.com**: (**Currently broken**)
 - **APA**
 - **Aparat**
 - **apple:​music:connect**: Apple Music Connect
 - **ApplePodcasts**
 - **appletrailers**
 - **appletrailers:section**
 - **archive.org**: archive.org video and audio
 - **ArcPublishing**
 - **ARD**
 - **ARDAudiothek**
 - **ARDAudiothekPlaylist**
 - **ARDMediathek**
 - **ARDMediathekCollection**
 - **Art19**
 - **Art19Show**
 - **arte.sky.it**
 - **ArteTV**
 - **ArteTVCategory**
 - **ArteTVEmbed**
 - **ArteTVPlaylist**
 - **asobichannel**: ASOBI CHANNEL
 - **asobichannel:tag**: ASOBI CHANNEL
 - **AsobiStage**: ASOBISTAGE (アソビステージ)
 - **AtresPlayer**: [*atresplayer*](## "netrc machine")
 - **AtScaleConfEvent**
 - **ATVAt**
 - **AudiMedia**
 - **AudioBoom**
 - **Audiodraft:custom**
 - **Audiodraft:generic**
 - **audiomack**
 - **audiomack:album**
 - **Audius**: Audius.co
 - **audius:artist**: Audius.co profile/artist pages
 - **audius:playlist**: Audius.co playlists
 - **audius:track**: Audius track ID or API link. Prepend with "audius:"
 - **AWAAN**
 - **awaan:live**
 - **awaan:season**
 - **awaan:video**
 - **axs.tv**
 - **AZMedien**: AZ Medien videos
 - **BaiduVideo**: 百度视频
 - **BanBye**
 - **BanByeChannel**
 - **Bandcamp**
 - **Bandcamp:album**
 - **Bandcamp:user**
 - **Bandcamp:weekly**
 - **Bandlab**
 - **BandlabPlaylist**
 - **BannedVideo**
 - **bbc**: [*bbc*](## "netrc machine") BBC
 - **bbc.co.uk**: [*bbc*](## "netrc machine") BBC iPlayer
 - **bbc.co.uk:article**: BBC articles
 - **bbc.co.uk:​iplayer:episodes**
 - **bbc.co.uk:​iplayer:group**
 - **bbc.co.uk:playlist**
 - **BBVTV**: [*bbvtv*](## "netrc machine")
 - **BBVTVLive**: [*bbvtv*](## "netrc machine")
 - **BBVTVRecordings**: [*bbvtv*](## "netrc machine")
 - **BeaconTv**
 - **BeatBumpPlaylist**
 - **BeatBumpVideo**
 - **Beatport**
 - **Beeg**
 - **BehindKink**: (**Currently broken**)
 - **BerufeTV**
 - **Bet**
 - **bfi:player**: (**Currently broken**)
 - **bfmtv**
 - **bfmtv:article**
 - **bfmtv:live**
 - **bibeltv:live**: BibelTV live program
 - **bibeltv:series**: BibelTV series playlist
 - **bibeltv:video**: BibelTV single video
 - **Bigflix**
 - **Bigo**
 - **Bild**: Bild.de
 - **BiliBili**
 - **Bilibili category extractor**
 - **BilibiliAudio**
 - **BilibiliAudioAlbum**
 - **BiliBiliBangumi**
 - **BiliBiliBangumiMedia**
 - **BiliBiliBangumiSeason**
 - **BilibiliCheese**
 - **BilibiliCheeseSeason**
 - **BilibiliCollectionList**
 - **BiliBiliDynamic**
 - **BilibiliFavoritesList**
 - **BiliBiliPlayer**
 - **BilibiliPlaylist**
 - **BiliBiliSearch**: Bilibili video search; "bilisearch:" prefix
 - **BilibiliSeriesList**
 - **BilibiliSpaceAudio**
 - **BilibiliSpaceVideo**
 - **BilibiliWatchlater**
 - **BiliIntl**: [*biliintl*](## "netrc machine")
 - **biliIntl:series**: [*biliintl*](## "netrc machine")
 - **BiliLive**
 - **BioBioChileTV**
 - **Biography**
 - **BitChute**
 - **BitChuteChannel**
 - **Bitmovin**
 - **BlackboardCollaborate**
 - **BlackboardCollaborateLaunch**
 - **BleacherReport**: (**Currently broken**)
 - **BleacherReportCMS**: (**Currently broken**)
 - **blerp**
 - **blogger.com**
 - **Bloomberg**
 - **Bluesky**
 - **BokeCC**: CC视频
 - **BongaCams**
 - **Boosty**
 - **BostonGlobe**
 - **Box**
 - **BoxCastVideo**
 - **Bpb**: Bundeszentrale für politische Bildung
 - **BR**: Bayerischer Rundfunk (**Currently broken**)
 - **BrainPOP**: [*brainpop*](## "netrc machine")
 - **BrainPOPELL**: [*brainpop*](## "netrc machine")
 - **BrainPOPEsp**: [*brainpop*](## "netrc machine") BrainPOP Español
 - **BrainPOPFr**: [*brainpop*](## "netrc machine") BrainPOP Français
 - **BrainPOPIl**: [*brainpop*](## "netrc machine") BrainPOP Hebrew
 - **BrainPOPJr**: [*brainpop*](## "netrc machine")
 - **BravoTV**
 - **BreitBart**
 - **brightcove:legacy**
 - **brightcove:new**
 - **Brilliantpala:Classes**: [*brilliantpala*](## "netrc machine") VoD on classes.brilliantpala.org
 - **Brilliantpala:Elearn**: [*brilliantpala*](## "netrc machine") VoD on elearn.brilliantpala.org
 - **bt:article**: Bergens Tidende Articles
 - **bt:vestlendingen**: Bergens Tidende - Vestlendingen
 - **BTVPlus**
 - **Bundesliga**
 - **Bundestag**
 - **BunnyCdn**
 - **BusinessInsider**
 - **BuzzFeed**
 - **BYUtv**: (**Currently broken**)
 - **CaffeineTV**
 - **Callin**
 - **Caltrans**
 - **CAM4**
 - **Camdemy**
 - **CamdemyFolder**
 - **CamFMEpisode**
 - **CamFMShow**
 - **CamModels**
 - **Camsoda**
 - **CamtasiaEmbed**
 - **Canal1**
 - **CanalAlpha**
 - **canalc2.tv**
 - **Canalplus**: mycanal.fr and piwiplus.fr
 - **Canalsurmas**
 - **CaracolTvPlay**: [*caracoltv-play*](## "netrc machine")
 - **cbc.ca**
 - **cbc.ca:listen**
 - **cbc.ca:player**
 - **cbc.ca:​player:playlist**
 - **CBS**: (**Currently broken**)
 - **CBSLocal**
 - **CBSLocalArticle**
 - **CBSLocalLive**
 - **cbsnews**: CBS News
 - **cbsnews:embed**
 - **cbsnews:live**: CBS News Livestream
 - **cbsnews:livevideo**: CBS News Live Videos
 - **cbssports**: (**Currently broken**)
 - **cbssports:embed**: (**Currently broken**)
 - **CCMA**: 3Cat, TV3 and Catalunya Ràdio
 - **CCTV**: 央视网
 - **CDA**: [*cdapl*](## "netrc machine")
 - **CDAFolder**
 - **Cellebrite**
 - **CeskaTelevize**
 - **CGTN**
 - **CharlieRose**
 - **Chaturbate**
 - **Chilloutzone**
 - **chzzk:live**
 - **chzzk:video**
 - **cielotv.it**
 - **Cinemax**: (**Currently broken**)
 - **CinetecaMilano**
 - **Cineverse**
 - **CineverseDetails**
 - **CiscoLiveSearch**
 - **CiscoLiveSession**
 - **ciscowebex**: Cisco Webex
 - **CJSW**
 - **Clipchamp**
 - **Clippit**
 - **ClipRs**: (**Currently broken**)
 - **CloserToTruth**: (**Currently broken**)
 - **CloudflareStream**
 - **CloudyCDN**
 - **Clubic**: (**Currently broken**)
 - **Clyp**
 - **CNBCVideo**
 - **CNN**
 - **CNNIndonesia**
 - **ComedyCentral**
 - **ConanClassic**: (**Currently broken**)
 - **CondeNast**: Condé Nast media group: Allure, Architectural Digest, Ars Technica, Bon Appétit, Brides, Condé Nast, Condé Nast Traveler, Details, Epicurious, GQ, Glamour, Golf Digest, SELF, Teen Vogue, The New Yorker, Vanity Fair, Vogue, W Magazine, WIRED
 - **CONtv**
 - **CookingChannel**
 - **Corus**
 - **Coub**
 - **CozyTV**
 - **cp24**
 - **cpac**
 - **cpac:playlist**
 - **Cracked**
 - **Craftsy**
 - **croatian.film**
 - **CrooksAndLiars**
 - **CrowdBunker**
 - **CrowdBunkerChannel**
 - **Crtvg**
 - **CSpan**: C-SPAN
 - **CSpanCongress**
 - **CtsNews**: 華視新聞
 - **CTVNews**
 - **cu.ntv.co.jp**: 日テレ無料TADA!
 - **CultureUnplugged**
 - **curiositystream**: [*curiositystream*](## "netrc machine")
 - **curiositystream:collections**: [*curiositystream*](## "netrc machine")
 - **curiositystream:series**: [*curiositystream*](## "netrc machine")
 - **Cybrary**: [*cybrary*](## "netrc machine")
 - **CybraryCourse**: [*cybrary*](## "netrc machine")
 - **DacastPlaylist**
 - **DacastVOD**
 - **DagelijkseKost**: dagelijksekost.een.be
 - **DailyMail**
 - **dailymotion**: [*dailymotion*](## "netrc machine")
 - **dailymotion:playlist**: [*dailymotion*](## "netrc machine")
 - **dailymotion:search**: [*dailymotion*](## "netrc machine")
 - **dailymotion:user**: [*dailymotion*](## "netrc machine")
 - **DailyWire**
 - **DailyWirePodcast**
 - **damtomo:record**
 - **damtomo:video**
 - **dangalplay**: [*dangalplay*](## "netrc machine")
 - **dangalplay:season**: [*dangalplay*](## "netrc machine")
 - **daum.net**
 - **daum.net:clip**
 - **daum.net:playlist**
 - **daum.net:user**
 - **daystar:clip**
 - **DBTV**
 - **DctpTv**
 - **democracynow**
 - **DestinationAmerica**
 - **DetikEmbed**
 - **DeuxM**
 - **DeuxMNews**
 - **DHM**: Filmarchiv - Deutsches Historisches Museum (**Currently broken**)
 - **DigitalConcertHall**: [*digitalconcerthall*](## "netrc machine") DigitalConcertHall extractor
 - **DigitallySpeaking**
 - **Digiteka**
 - **Digiview**
 - **DiscogsReleasePlaylist**
 - **DiscoveryLife**
 - **DiscoveryNetworksDe**
 - **DiscoveryPlus**
 - **DiscoveryPlusIndia**
 - **DiscoveryPlusIndiaShow**
 - **DiscoveryPlusItaly**
 - **DiscoveryPlusItalyShow**
 - **Disney**
 - **dlf**
 - **dlf:corpus**: DLF Multi-feed Archives
 - **dlive:stream**
 - **dlive:vod**
 - **Douyin**
 - **DouyuShow**
 - **DouyuTV**: 斗鱼直播
 - **DPlay**
 - **DRBonanza**
 - **Drooble**
 - **Dropbox**
 - **Dropout**: [*dropout*](## "netrc machine")
 - **DropoutSeason**
 - **DrTalks**
 - **DrTuber**
 - **drtv**
 - **drtv:live**
 - **drtv:season**
 - **drtv:series**
 - **DTube**: (**Currently broken**)
 - **duboku**: www.duboku.io
 - **duboku:list**: www.duboku.io entire series
 - **Dumpert**
 - **Duoplay**
 - **dvtv**: http://video.aktualne.cz/
 - **dw**: (**Currently broken**)
 - **dw:article**: (**Currently broken**)
 - **dzen.ru**: Дзен (dzen) formerly Яндекс.Дзен (Yandex Zen)
 - **dzen.ru:channel**
 - **EbaumsWorld**
 - **Ebay**
 - **egghead:course**: egghead.io course
 - **egghead:lesson**: egghead.io lesson
 - **eggs:artist**
 - **eggs:single**
 - **EinsUndEinsTV**: [*1und1tv*](## "netrc machine")
 - **EinsUndEinsTVLive**: [*1und1tv*](## "netrc machine")
 - **EinsUndEinsTVRecordings**: [*1und1tv*](## "netrc machine")
 - **eitb.tv**
 - **ElementorEmbed**
 - **Elonet**
 - **ElPais**: El País
 - **ElTreceTV**: El Trece TV (Argentina)
 - **Embedly**
 - **EMPFlix**
 - **Epicon**
 - **EpiconSeries**
 - **EpidemicSound**
 - **eplus**: [*eplus*](## "netrc machine") e+ (イープラス)
 - **Epoch**
 - **Eporner**
 - **Erocast**
 - **EroProfile**: [*eroprofile*](## "netrc machine")
 - **EroProfile:album**
 - **ERRArhiiv**
 - **ERRJupiter**
 - **ertflix**: ERTFLIX videos
 - **ertflix:codename**: ERTFLIX videos by codename
 - **ertwebtv:embed**: ert.gr webtv embedded videos
 - **ESPN**
 - **ESPNArticle**
 - **ESPNCricInfo**
 - **EttuTv**
 - **Europa**: (**Currently broken**)
 - **EuroParlWebstream**
 - **EuropeanTour**
 - **Eurosport**
 - **EUScreen**
 - **EWETV**: [*ewetv*](## "netrc machine")
 - **EWETVLive**: [*ewetv*](## "netrc machine")
 - **EWETVRecordings**: [*ewetv*](## "netrc machine")
 - **Expressen**
 - **EyedoTV**
 - **facebook**
 - **facebook:ads**
 - **facebook:reel**
 - **FacebookPluginsVideo**
 - **fancode:live**: [*fancode*](## "netrc machine") (**Currently broken**)
 - **fancode:vod**: [*fancode*](## "netrc machine") (**Currently broken**)
 - **Fathom**
 - **Faulio**
 - **FaulioLive**
 - **faz.net**
 - **fc2**: [*fc2*](## "netrc machine")
 - **fc2:embed**
 - **fc2:live**
 - **Fczenit**
 - **Fifa**
 - **FilmArchiv**: FILMARCHIV ON
 - **filmon**
 - **filmon:channel**
 - **Filmweb**
 - **FiveThirtyEight**
 - **FiveTV**
 - **Flickr**
 - **Floatplane**
 - **FloatplaneChannel**
 - **Folketinget**: Folketinget (ft.dk; Danish parliament)
 - **FoodNetwork**
 - **FootyRoom**
 - **Formula1**
 - **FOX**
 - **FOX9**
 - **FOX9News**
 - **foxnews**: Fox News and Fox Business Video
 - **foxnews:article**
 - **FoxNewsVideo**
 - **FoxSports**
 - **fptplay**: fptplay.vn
 - **FrancaisFacile**
 - **FranceCulture**
 - **franceinfo**: franceinfo.fr (formerly francetvinfo.fr)
 - **FranceInter**
 - **francetv**
 - **francetv:site**
 - **Freesound**
 - **freespeech.org**
 - **freetv:series**
 - **FreeTvMovies**
 - **FrontendMasters**: [*frontendmasters*](## "netrc machine")
 - **FrontendMastersCourse**: [*frontendmasters*](## "netrc machine")
 - **FrontendMastersLesson**: [*frontendmasters*](## "netrc machine")
 - **FujiTVFODPlus7**
 - **Funk**
 - **Funker530**
 - **Fux**
 - **FuyinTV**
 - **Gab**
 - **GabTV**
 - **Gaia**: [*gaia*](## "netrc machine")
 - **GameDevTVDashboard**: [*gamedevtv*](## "netrc machine")
 - **GameJolt**
 - **GameJoltCommunity**
 - **GameJoltGame**
 - **GameJoltGameSoundtrack**
 - **GameJoltSearch**
 - **GameJoltUser**
 - **GameSpot**
 - **GameStar**
 - **Gaskrank**
 - **Gazeta**: (**Currently broken**)
 - **GBNews**: GB News clips, features and live streams
 - **GDCVault**: [*gdcvault*](## "netrc machine") (**Currently broken**)
 - **GediDigital**
 - **gem.cbc.ca**: [*cbcgem*](## "netrc machine")
 - **gem.cbc.ca:live**
 - **gem.cbc.ca:playlist**: [*cbcgem*](## "netrc machine")
 - **Genius**
 - **GeniusLyrics**
 - **Germanupa**: germanupa.de
 - **GetCourseRu**: [*getcourseru*](## "netrc machine")
 - **GetCourseRuPlayer**
 - **Gettr**
 - **GettrStreaming**
 - **GiantBomb**
 - **GlattvisionTV**: [*glattvisiontv*](## "netrc machine")
 - **GlattvisionTVLive**: [*glattvisiontv*](## "netrc machine")
 - **GlattvisionTVRecordings**: [*glattvisiontv*](## "netrc machine")
 - **Glide**: Glide mobile video messages (glide.me)
 - **GlobalPlayerAudio**
 - **GlobalPlayerAudioEpisode**
 - **GlobalPlayerLive**
 - **GlobalPlayerLivePlaylist**
 - **GlobalPlayerVideo**
 - **Globo**: [*globo*](## "netrc machine")
 - **GloboArticle**
 - **glomex**: Glomex videos
 - **glomex:embed**: Glomex embedded videos
 - **GMANetworkVideo**
 - **Go**
 - **GoDiscovery**
 - **GodResource**
 - **GodTube**: (**Currently broken**)
 - **Gofile**
 - **Golem**
 - **goodgame:stream**
 - **google:podcasts**
 - **google:​podcasts:feed**
 - **GoogleDrive**
 - **GoogleDrive:Folder**
 - **GoPro**
 - **Goshgay**
 - **GoToStage**
 - **GPUTechConf**
 - **Graspop**
 - **Gronkh**
 - **gronkh:feed**
 - **gronkh:vods**
 - **Groupon**
 - **Harpodeon**
 - **hbo**
 - **HearThisAt**
 - **Heise**
 - **HellPorno**
 - **hetklokhuis**
 - **hgtv.com:show**
 - **HGTVDe**
 - **HGTVUsa**
 - **HiDive**: [*hidive*](## "netrc machine")
 - **HistoricFilms**
 - **history:player**
 - **history:topic**: History.com Topic
 - **HitRecord**
 - **hketv**: 香港教育局教育電視 (HKETV) Educational Television, Hong Kong Educational Bureau
 - **HollywoodReporter**
 - **HollywoodReporterPlaylist**
 - **Holodex**
 - **HotNewHipHop**: (**Currently broken**)
 - **hotstar**: JioHotstar
 - **hotstar:series**
 - **hrfernsehen**
 - **HRTi**: [*hrti*](## "netrc machine")
 - **HRTiPlaylist**: [*hrti*](## "netrc machine")
 - **HSEProduct**
 - **HSEShow**
 - **html5**
 - **Huajiao**: 花椒直播
 - **HuffPost**: Huffington Post
 - **Hungama**
 - **HungamaAlbumPlaylist**
 - **HungamaSong**
 - **huya:live**: 虎牙直播
 - **huya:video**: 虎牙视频
 - **Hypem**
 - **Hytale**
 - **Icareus**
 - **IdagioAlbum**
 - **IdagioPersonalPlaylist**
 - **IdagioPlaylist**
 - **IdagioRecording**
 - **IdagioTrack**
 - **IdolPlus**
 - **iflix:episode**
 - **IflixSeries**
 - **ign.com**
 - **IGNArticle**
 - **IGNVideo**
 - **iheartradio**
 - **iheartradio:podcast**
 - **IlPost**
 - **Iltalehti**
 - **imdb**: Internet Movie Database trailers
 - **imdb:list**: Internet Movie Database lists
 - **Imgur**
 - **imgur:album**
 - **imgur:gallery**
 - **Ina**
 - **Inc**
 - **IndavideoEmbed**
 - **InfoQ**
 - **Instagram**
 - **instagram:story**
 - **instagram:tag**: Instagram hashtag search URLs
 - **instagram:user**: Instagram user profile (**Currently broken**)
 - **InstagramIOS**: IOS instagram:// URL
 - **Internazionale**
 - **InternetVideoArchive**
 - **InvestigationDiscovery**
 - **IPrima**: [*iprima*](## "netrc machine")
 - **IPrimaCNN**
 - **iq.com**: International version of iQiyi
 - **iq.com:album**
 - **iqiyi**: 爱奇艺
 - **IslamChannel**
 - **IslamChannelSeries**
 - **IsraelNationalNews**
 - **ITProTV**
 - **ITProTVCourse**
 - **ITV**
 - **ITVBTCC**
 - **ivi**: ivi.ru
 - **ivi:compilation**: ivi.ru compilations
 - **ivideon**: Ivideon TV
 - **Ivoox**
 - **IVXPlayer**
 - **iwara**: [*iwara*](## "netrc machine")
 - **iwara:playlist**: [*iwara*](## "netrc machine")
 - **iwara:user**: [*iwara*](## "netrc machine")
 - **Ixigua**
 - **Izlesene**
 - **Jamendo**
 - **JamendoAlbum**
 - **JeuxVideo**: (**Currently broken**)
 - **jiosaavn:album**
 - **jiosaavn:artist**
 - **jiosaavn:playlist**
 - **jiosaavn:show**
 - **jiosaavn:​show:playlist**
 - **jiosaavn:song**
 - **Joj**
 - **Jove**
 - **JStream**
 - **JTBC**: jtbc.co.kr
 - **JTBC:program**
 - **JWPlatform**
 - **Kakao**
 - **Kaltura**
 - **KankaNews**: (**Currently broken**)
 - **Karaoketv**
 - **Katsomo**: (**Currently broken**)
 - **KelbyOne**: (**Currently broken**)
 - **Kenh14Playlist**
 - **Kenh14Video**
 - **khanacademy**
 - **khanacademy:unit**
 - **kick:clips**
 - **kick:live**
 - **kick:vod**
 - **Kicker**
 - **KickStarter**
 - **Kika**: KiKA.de
 - **KikaPlaylist**
 - **kinja:embed**
 - **KinoPoisk**
 - **Kommunetv**
 - **KompasVideo**
 - **Koo**: (**Currently broken**)
 - **KrasView**: Красвью (**Currently broken**)
 - **KTH**
 - **Ku6**
 - **KukuluLive**
 - **kuwo:album**: 酷我音乐 - 专辑 (**Currently broken**)
 - **kuwo:category**: 酷我音乐 - 分类 (**Currently broken**)
 - **kuwo:chart**: 酷我音乐 - 排行榜 (**Currently broken**)
 - **kuwo:mv**: 酷我音乐 - MV (**Currently broken**)
 - **kuwo:singer**: 酷我音乐 - 歌手 (**Currently broken**)
 - **kuwo:song**: 酷我音乐 (**Currently broken**)
 - **la7.it**
 - **la7.it:​pod:episode**
 - **la7.it:podcast**
 - **laracasts**
 - **laracasts:series**
 - **LastFM**
 - **LastFMPlaylist**
 - **LastFMUser**
 - **LaXarxaMes**: [*laxarxames*](## "netrc machine")
 - **lbry**: odysee.com
 - **lbry:channel**: odysee.com channels
 - **lbry:playlist**: odysee.com playlists
 - **LCI**
 - **Lcp**: (**Currently broken**)
 - **LcpPlay**: (**Currently broken**)
 - **Le**: 乐视网
 - **LearningOnScreen**
 - **Lecture2Go**: (**Currently broken**)
 - **Lecturio**: [*lecturio*](## "netrc machine")
 - **LecturioCourse**: [*lecturio*](## "netrc machine")
 - **LecturioDeCourse**: [*lecturio*](## "netrc machine")
 - **LeFigaroVideoEmbed**
 - **LeFigaroVideoSection**
 - **LEGO**
 - **Lemonde**
 - **Lenta**: (**Currently broken**)
 - **LePlaylist**
 - **LetvCloud**: 乐视云
 - **Libsyn**
 - **life**: Life.ru
 - **life:embed**
 - **likee**
 - **likee:user**
 - **LinkedIn**: [*linkedin*](## "netrc machine")
 - **linkedin:events**: [*linkedin*](## "netrc machine")
 - **linkedin:learning**: [*linkedin*](## "netrc machine")
 - **linkedin:​learning:course**: [*linkedin*](## "netrc machine")
 - **Liputan6**
 - **ListenNotes**
 - **LiTV**
 - **LiveJournal**: (**Currently broken**)
 - **livestream**
 - **livestream:original**
 - **Livestreamfails**
 - **Lnk**
 - **loc**: Library of Congress
 - **Loco**
 - **loom**
 - **loom:folder**: (**Currently broken**)
 - **LoveHomePorn**
 - **LRTRadio**
 - **LRTStream**
 - **LRTVOD**
 - **LSMLREmbed**
 - **LSMLTVEmbed**
 - **LSMReplay**
 - **Lumni**
 - **lynda**: [*lynda*](## "netrc machine") lynda.com videos
 - **lynda:course**: [*lynda*](## "netrc machine") lynda.com online courses
 - **maariv.co.il**
 - **MagellanTV**
 - **MagentaMusik**
 - **mailru**: Видео@Mail.Ru
 - **mailru:music**: Музыка@Mail.Ru
 - **mailru:​music:search**: Музыка@Mail.Ru
 - **MainStreaming**: MainStreaming Player
 - **mangomolo:live**
 - **mangomolo:video**
 - **MangoTV**: 芒果TV
 - **ManyVids**
 - **MaoriTV**
 - **Markiza**: (**Currently broken**)
 - **MarkizaPage**: (**Currently broken**)
 - **massengeschmack.tv**
 - **Masters**
 - **MatchTV**
 - **mave**
 - **mave:channel**
 - **MBN**: mbn.co.kr (매일방송)
 - **MDR**: MDR.DE
 - **MedalTV**
 - **media.ccc.de**
 - **media.ccc.de:lists**
 - **Mediaite**
 - **MediaKlikk**
 - **Medialaan**
 - **Mediaset**
 - **MediasetShow**
 - **Mediasite**
 - **MediasiteCatalog**
 - **MediasiteNamedCatalog**
 - **MediaStream**
 - **MediaWorksNZVOD**
 - **Medici**
 - **megaphone.fm**: megaphone.fm embedded players
 - **megatvcom**: megatv.com videos
 - **megatvcom:embed**: megatv.com embedded videos
 - **Meipai**: 美拍
 - **MelonVOD**
 - **Metacritic**
 - **mewatch**
 - **MicrosoftBuild**
 - **MicrosoftEmbed**
 - **MicrosoftLearnEpisode**
 - **MicrosoftLearnPlaylist**
 - **MicrosoftLearnSession**
 - **MicrosoftMedius**
 - **microsoftstream**: Microsoft Stream
 - **minds**
 - **minds:channel**
 - **minds:group**
 - **Minoto**
 - **mir24.tv**
 - **mirrativ**
 - **mirrativ:user**
 - **MirrorCoUK**
 - **mixch**
 - **mixch:archive**
 - **mixch:movie**
 - **mixcloud**
 - **mixcloud:playlist**
 - **mixcloud:user**
 - **Mixlr**
 - **MixlrRecoring**
 - **MLB**
 - **MLBArticle**
 - **MLBTV**: [*mlb*](## "netrc machine")
 - **MLBVideo**
 - **MLSSoccer**
 - **MNetTV**: [*mnettv*](## "netrc machine")
 - **MNetTVLive**: [*mnettv*](## "netrc machine")
 - **MNetTVRecordings**: [*mnettv*](## "netrc machine")
 - **MochaVideo**
 - **Mojevideo**: mojevideo.sk
 - **Mojvideo**
 - **Monstercat**
 - **monstersiren**: 塞壬唱片
 - **Motherless**
 - **MotherlessGallery**
 - **MotherlessGroup**
 - **MotherlessUploader**
 - **Motorsport**: motorsport.com (**Currently broken**)
 - **MovieFap**
 - **moviepilot**: Moviepilot trailer
 - **MoviewPlay**
 - **Moviezine**
 - **MovingImage**
 - **MSN**
 - **mtg**: MTG services
 - **mtv**
 - **MTVUutisetArticle**: (**Currently broken**)
 - **MuenchenTV**: münchen.tv (**Currently broken**)
 - **MujRozhlas**
 - **Murrtube**
 - **MurrtubeUser**: Murrtube user profile (**Currently broken**)
 - **MuseAI**
 - **MuseScore**
 - **MusicdexAlbum**
 - **MusicdexArtist**
 - **MusicdexPlaylist**
 - **MusicdexSong**
 - **Mux**
 - **Mx3**
 - **Mx3Neo**
 - **Mx3Volksmusik**
 - **Mxplayer**
 - **MxplayerShow**
 - **MySpace**
 - **MySpace:album**
 - **MySpass**
 - **MyVideoGe**
 - **MyVidster**
 - **Mzaalo**
 - **n-tv.de**
 - **N1Info:article**
 - **N1InfoAsset**
 - **NascarClassics**
 - **Nate**
 - **NateProgram**
 - **natgeo:video**
 - **NationalGeographicTV**
 - **Naver**
 - **Naver:live**
 - **navernow**
 - **nba**: (**Currently broken**)
 - **nba:channel**: (**Currently broken**)
 - **nba:embed**: (**Currently broken**)
 - **nba:watch**: (**Currently broken**)
 - **nba:​watch:collection**: (**Currently broken**)
 - **nba:​watch:embed**: (**Currently broken**)
 - **NBC**
 - **NBCNews**
 - **nbcolympics**
 - **nbcolympics:stream**: (**Currently broken**)
 - **NBCSports**: (**Currently broken**)
 - **NBCSportsStream**: (**Currently broken**)
 - **NBCSportsVPlayer**: (**Currently broken**)
 - **NBCStations**
 - **ndr**: NDR.de - Norddeutscher Rundfunk
 - **ndr:embed**
 - **ndr:​embed:base**
 - **NDTV**: (**Currently broken**)
 - **nebula:channel**: [*watchnebula*](## "netrc machine")
 - **nebula:media**: [*watchnebula*](## "netrc machine")
 - **nebula:season**: [*watchnebula*](## "netrc machine")
 - **nebula:subscriptions**: [*watchnebula*](## "netrc machine")
 - **nebula:video**: [*watchnebula*](## "netrc machine")
 - **NekoHacker**
 - **NerdCubedFeed**
 - **Nest**
 - **NestClip**
 - **NetAppCollection**
 - **NetAppVideo**
 - **netease:album**: 网易云音乐 - 专辑
 - **netease:djradio**: 网易云音乐 - 电台
 - **netease:mv**: 网易云音乐 - MV
 - **netease:playlist**: 网易云音乐 - 歌单
 - **netease:program**: 网易云音乐 - 电台节目
 - **netease:singer**: 网易云音乐 - 歌手
 - **netease:song**: 网易云音乐
 - **NetPlusTV**: [*netplus*](## "netrc machine")
 - **NetPlusTVLive**: [*netplus*](## "netrc machine")
 - **NetPlusTVRecordings**: [*netplus*](## "netrc machine")
 - **Netverse**
 - **NetversePlaylist**
 - **NetverseSearch**: "netsearch:" prefix
 - **Netzkino**
 - **Newgrounds**: [*newgrounds*](## "netrc machine")
 - **Newgrounds:playlist**
 - **Newgrounds:user**
 - **NewsPicks**
 - **Newsy**
 - **Nexx**
 - **NexxEmbed**
 - **nfb**: nfb.ca and onf.ca films and episodes
 - **nfb:series**: nfb.ca and onf.ca series
 - **NFHSNetwork**
 - **nfl.com**
 - **nfl.com:article**
 - **nfl.com:​plus:episode**
 - **nfl.com:​plus:replay**
 - **NhkForSchoolBangumi**
 - **NhkForSchoolProgramList**
 - **NhkForSchoolSubject**: Portal page for each school subjects, like Japanese (kokugo, 国語) or math (sansuu/suugaku or 算数・数学)
 - **NhkRadioNewsPage**
 - **NhkRadiru**: NHK らじる (Radiru/Rajiru)
 - **NhkRadiruLive**
 - **NhkVod**
 - **NhkVodProgram**
 - **nhl.com**
 - **nick.com**
 - **niconico**: [*niconico*](## "netrc machine") ニコニコ動画
 - **niconico:history**: NicoNico user history or likes. Requires cookies.
 - **niconico:live**: [*niconico*](## "netrc machine") ニコニコ生放送
 - **niconico:playlist**
 - **niconico:series**
 - **niconico:tag**: NicoNico video tag URLs
 - **NiconicoChannelPlus**: ニコニコチャンネルプラス
 - **NiconicoChannelPlus:​channel:lives**: ニコニコチャンネルプラス - チャンネル - ライブリスト. nicochannel.jp/channel/lives
 - **NiconicoChannelPlus:​channel:videos**: ニコニコチャンネルプラス - チャンネル - 動画リスト. nicochannel.jp/channel/videos
 - **NiconicoUser**
 - **nicovideo:search**: Nico video search; "nicosearch:" prefix
 - **nicovideo:​search:date**: Nico video search, newest first; "nicosearchdate:" prefix
 - **nicovideo:search_url**: Nico video search URLs
 - **NinaProtocol**
 - **Nintendo**
 - **Nitter**
 - **njoy**: N-JOY
 - **njoy:embed**
 - **NobelPrize**
 - **NoicePodcast**
 - **NonkTube**
 - **NoodleMagazine**
 - **NOSNLArticle**
 - **Nova**: TN.cz, Prásk.tv, Nova.cz, Novaplus.cz, FANDA.tv, Krásná.cz and Doma.cz
 - **NovaEmbed**
 - **NovaPlay**
 - **NowCanal**
 - **nowness**
 - **nowness:playlist**
 - **nowness:series**
 - **Noz**: (**Currently broken**)
 - **npo**: npo.nl, ntr.nl, omroepwnl.nl, zapp.nl and npo3.nl
 - **npo.nl:live**
 - **npo.nl:radio**
 - **npo.nl:​radio:fragment**
 - **Npr**
 - **NRK**
 - **NRKPlaylist**
 - **NRKRadioPodkast**
 - **NRKSkole**: NRK Skole
 - **NRKTV**: NRK TV and NRK Radio
 - **NRKTVDirekte**: NRK TV Direkte and NRK Radio Direkte
 - **NRKTVEpisode**
 - **NRKTVEpisodes**
 - **NRKTVSeason**
 - **NRKTVSeries**
 - **NRLTV**: (**Currently broken**)
 - **nts.live**
 - **ntv.ru**
 - **NubilesPorn**: [*nubiles-porn*](## "netrc machine")
 - **nuum:live**
 - **nuum:media**
 - **nuum:tab**
 - **Nuvid**
 - **NYTimes**
 - **NYTimesArticle**
 - **NYTimesCookingGuide**
 - **NYTimesCookingRecipe**
 - **nzherald**
 - **NZOnScreen**
 - **NZZ**
 - **ocw.mit.edu**
 - **Odnoklassniki**
 - **OfTV**
 - **OfTVPlaylist**
 - **OktoberfestTV**
 - **OlympicsReplay**
 - **on24**: ON24
 - **OnDemandChinaEpisode**
 - **OnDemandKorea**
 - **OnDemandKoreaProgram**
 - **OneFootball**
 - **OnePlacePodcast**
 - **onet.pl**
 - **onet.tv**
 - **onet.tv:channel**
 - **OnetMVP**
 - **OnionStudios**
 - **onsen**: [*onsen*](## "netrc machine") インターネットラジオステーション＜音泉＞
 - **Opencast**
 - **OpencastPlaylist**
 - **openrec**
 - **openrec:capture**
 - **openrec:movie**
 - **OraTV**
 - **orf:​fm4:story**: fm4.orf.at stories
 - **orf:iptv**: iptv.ORF.at
 - **orf:on**
 - **orf:podcast**
 - **orf:radio**
 - **OsnatelTV**: [*osnateltv*](## "netrc machine")
 - **OsnatelTVLive**: [*osnateltv*](## "netrc machine")
 - **OsnatelTVRecordings**: [*osnateltv*](## "netrc machine")
 - **OutsideTV**
 - **OwnCloud**
 - **PacktPub**: [*packtpub*](## "netrc machine")
 - **PacktPubCourse**
 - **PalcoMP3:artist**
 - **PalcoMP3:song**
 - **PalcoMP3:video**
 - **PandaTv**: pandalive.co.kr (팬더티비)
 - **Panopto**
 - **PanoptoList**
 - **PanoptoPlaylist**
 - **ParamountPressExpress**
 - **Parler**: Posts on parler.com
 - **parliamentlive.tv**: UK parliament videos
 - **Parlview**
 - **parti:livestream**
 - **parti:video**
 - **patreon**
 - **patreon:campaign**
 - **pbs**: Public Broadcasting Service (PBS) and member stations: PBS: Public Broadcasting Service, APT - Alabama Public Television (WBIQ), GPB/Georgia Public Broadcasting (WGTV), Mississippi Public Broadcasting (WMPN), Nashville Public Television (WNPT), WFSU-TV (WFSU), WSRE (WSRE), WTCI (WTCI), WPBA/Channel 30 (WPBA), Alaska Public Media (KAKM), Arizona PBS (KAET), KNME-TV/Channel 5 (KNME), Vegas PBS (KLVX), AETN/ARKANSAS ETV NETWORK (KETS), KET (WKLE), WKNO/Channel 10 (WKNO), LPB/LOUISIANA PUBLIC BROADCASTING (WLPB), OETA (KETA), Ozarks Public Television (KOZK), WSIU Public Broadcasting (WSIU), KEET TV (KEET), KIXE/Channel 9 (KIXE), KPBS San Diego (KPBS), KQED (KQED), KVIE Public Television (KVIE), PBS SoCal/KOCE (KOCE), ValleyPBS (KVPT), CONNECTICUT PUBLIC TELEVISION (WEDH), KNPB Channel 5 (KNPB), SOPTV (KSYS), Rocky Mountain PBS (KRMA), KENW-TV3 (KENW), KUED Channel 7 (KUED), Wyoming PBS (KCWC), Colorado Public Television / KBDI 12 (KBDI), KBYU-TV (KBYU), Thirteen/WNET New York (WNET), WGBH/Channel 2 (WGBH), WGBY (WGBY), NJTV Public Media NJ (WNJT), WLIW21 (WLIW), mpt/Maryland Public Television (WMPB), WETA Television and Radio (WETA), WHYY (WHYY), PBS 39 (WLVT), WVPT - Your Source for PBS and More! (WVPT), Howard University Television (WHUT), WEDU PBS (WEDU), WGCU Public Media (WGCU), WPBT2 (WPBT), WUCF TV (WUCF), WUFT/Channel 5 (WUFT), WXEL/Channel 42 (WXEL), WLRN/Channel 17 (WLRN), WUSF Public Broadcasting (WUSF), ETV (WRLK), UNC-TV (WUNC), PBS Hawaii - Oceanic Cable Channel 10 (KHET), Idaho Public Television (KAID), KSPS (KSPS), OPB (KOPB), KWSU/Channel 10 & KTNW/Channel 31 (KWSU), WILL-TV (WILL), Network Knowledge - WSEC/Springfield (WSEC), WTTW11 (WTTW), Iowa Public Television/IPTV (KDIN), Nine Network (KETC), PBS39 Fort Wayne (WFWA), WFYI Indianapolis (WFYI), Milwaukee Public Television (WMVS), WNIN (WNIN), WNIT Public Television (WNIT), WPT (WPNE), WVUT/Channel 22 (WVUT), WEIU/Channel 51 (WEIU), WQPT-TV (WQPT), WYCC PBS Chicago (WYCC), WIPB-TV (WIPB), WTIU (WTIU), CET  (WCET), ThinkTVNetwork (WPTD), WBGU-TV (WBGU), WGVU TV (WGVU), NET1 (KUON), Pioneer Public Television (KWCM), SDPB Television (KUSD), TPT (KTCA), KSMQ (KSMQ), KPTS/Channel 8 (KPTS), KTWU/Channel 11 (KTWU), East Tennessee PBS (WSJK), WCTE-TV (WCTE), WLJT, Channel 11 (WLJT), WOSU TV (WOSU), WOUB/WOUC (WOUB), WVPB (WVPB), WKYU-PBS (WKYU), KERA 13 (KERA), MPBN (WCBB), Mountain Lake PBS (WCFE), NHPTV (WENH), Vermont PBS (WETK), witf (WITF), WQED Multimedia (WQED), WMHT Educational Telecommunications (WMHT), Q-TV (WDCQ), WTVS Detroit Public TV (WTVS), CMU Public Television (WCMU), WKAR-TV (WKAR), WNMU-TV Public TV 13 (WNMU), WDSE - WRPT (WDSE), WGTE TV (WGTE), Lakeland Public Television (KAWE), KMOS-TV - Channels 6.1, 6.2 and 6.3 (KMOS), MontanaPBS (KUSM), KRWG/Channel 22 (KRWG), KACV (KACV), KCOS/Channel 13 (KCOS), WCNY/Channel 24 (WCNY), WNED (WNED), WPBS (WPBS), WSKG Public TV (WSKG), WXXI (WXXI), WPSU (WPSU), WVIA Public Media Studios (WVIA), WTVI (WTVI), Western Reserve PBS (WNEO), WVIZ/PBS ideastream (WVIZ), KCTS 9 (KCTS), Basin PBS (KPBT), KUHT / Channel 8 (KUHT), KLRN (KLRN), KLRU (KLRU), WTJX Channel 12 (WTJX), WCVE PBS (WCVE), KBTC Public Television (KBTC)
 - **PBSKids**
 - **PearVideo**
 - **PeekVids**
 - **peer.tv**
 - **PeerTube**
 - **PeerTube:Playlist**
 - **peloton**: [*peloton*](## "netrc machine")
 - **peloton:live**: Peloton Live
 - **PerformGroup**
 - **periscope**: Periscope
 - **periscope:user**: Periscope user videos
 - **PGATour**
 - **PhilharmonieDeParis**: Philharmonie de Paris
 - **phoenix.de**
 - **Photobucket**
 - **PiaLive**
 - **Piapro**: [*piapro*](## "netrc machine")
 - **picarto**
 - **picarto:vod**
 - **Piksel**
 - **Pinkbike**
 - **Pinterest**
 - **PinterestCollection**
 - **PiramideTV**
 - **PiramideTVChannel**
 - **PlanetMarathi**
 - **Platzi**: [*platzi*](## "netrc machine")
 - **PlatziCourse**: [*platzi*](## "netrc machine")
 - **play.tv**: [*goplay*](## "netrc machine") PLAY (formerly goplay.be)
 - **player.sky.it**
 - **PlayerFm**
 - **playeur**
 - **PlayPlusTV**: [*playplustv*](## "netrc machine")
 - **PlaySuisse**: [*playsuisse*](## "netrc machine")
 - **Playtvak**: Playtvak.cz, iDNES.cz and Lidovky.cz
 - **PlayVids**
 - **Playwire**
 - **pluralsight**: [*pluralsight*](## "netrc machine")
 - **pluralsight:course**
 - **PlutoTV**: (**Currently broken**)
 - **PlVideo**: Платформа
 - **PlyrEmbed**
 - **PodbayFM**
 - **PodbayFMChannel**
 - **Podchaser**
 - **podomatic**: (**Currently broken**)
 - **PokerGo**: [*pokergo*](## "netrc machine")
 - **PokerGoCollection**: [*pokergo*](## "netrc machine")
 - **PolsatGo**
 - **PolskieRadio**
 - **polskieradio:audition**
 - **polskieradio:category**
 - **polskieradio:legacy**
 - **polskieradio:player**
 - **polskieradio:podcast**
 - **polskieradio:​podcast:list**
 - **Popcorntimes**
 - **PopcornTV**
 - **Pornbox**
 - **PornerBros**
 - **PornFlip**
 - **PornHub**: [*pornhub*](## "netrc machine") PornHub and Thumbzilla
 - **PornHubPagedVideoList**: [*pornhub*](## "netrc machine")
 - **PornHubPlaylist**: [*pornhub*](## "netrc machine")
 - **PornHubUser**: [*pornhub*](## "netrc machine")
 - **PornHubUserVideosUpload**: [*pornhub*](## "netrc machine")
 - **Pornotube**
 - **PornoVoisines**: (**Currently broken**)
 - **PornoXO**: (**Currently broken**)
 - **PornTop**
 - **PornTube**
 - **Pr0gramm**
 - **PrankCast**
 - **PrankCastPost**
 - **PremiershipRugby**
 - **PressTV**
 - **ProjectVeritas**: (**Currently broken**)
 - **prosiebensat1**: ProSiebenSat.1 Digital
 - **PRXAccount**
 - **PRXSeries**
 - **prxseries:search**: PRX Series Search; "prxseries:" prefix
 - **prxstories:search**: PRX Stories Search; "prxstories:" prefix
 - **PRXStory**
 - **puhutv**
 - **puhutv:serie**
 - **Puls4**
 - **Pyvideo**
 - **QDance**: [*qdance*](## "netrc machine")
 - **QingTing**
 - **qqmusic**: QQ音乐
 - **qqmusic:album**: QQ音乐 - 专辑
 - **qqmusic:mv**: QQ音乐 - MV
 - **qqmusic:playlist**: QQ音乐 - 歌单
 - **qqmusic:singer**: QQ音乐 - 歌手
 - **qqmusic:toplist**: QQ音乐 - 排行榜
 - **QuantumTV**: [*quantumtv*](## "netrc machine")
 - **QuantumTVLive**: [*quantumtv*](## "netrc machine")
 - **QuantumTVRecordings**: [*quantumtv*](## "netrc machine")
 - **R7**: (**Currently broken**)
 - **R7Article**: (**Currently broken**)
 - **Radiko**
 - **RadikoRadio**
 - **radio.de**: (**Currently broken**)
 - **Radio1Be**
 - **radiocanada**
 - **radiocanada:audiovideo**
 - **RadioComercial**
 - **RadioComercialPlaylist**
 - **radiofrance**
 - **RadioFranceLive**
 - **RadioFrancePodcast**
 - **RadioFranceProfile**
 - **RadioFranceProgramSchedule**
 - **RadioJavan**: (**Currently broken**)
 - **radiokapital**
 - **radiokapital:show**
 - **RadioRadicale**
 - **RadioZetPodcast**
 - **radlive**
 - **radlive:channel**
 - **radlive:season**
 - **Rai**
 - **RaiCultura**
 - **RaiNews**
 - **RaiPlay**
 - **RaiPlayLive**
 - **RaiPlayPlaylist**
 - **RaiPlaySound**
 - **RaiPlaySoundLive**
 - **RaiPlaySoundPlaylist**
 - **RaiSudtirol**
 - **RayWenderlich**
 - **RayWenderlichCourse**
 - **RbgTum**
 - **RbgTumCourse**
 - **RbgTumNewCourse**
 - **RCS**
 - **RCSEmbeds**
 - **RCSVarious**
 - **RCTIPlus**
 - **RCTIPlusSeries**
 - **RCTIPlusTV**
 - **RDS**: RDS.ca (**Currently broken**)
 - **RedBull**
 - **RedBullEmbed**
 - **RedBullTV**
 - **RedBullTVRrnContent**
 - **redcdnlivx**
 - **Reddit**: [*reddit*](## "netrc machine")
 - **RedGifs**
 - **RedGifsSearch**: Redgifs search
 - **RedGifsUser**: Redgifs user
 - **RedTube**
 - **RENTV**: (**Currently broken**)
 - **RENTVArticle**: (**Currently broken**)
 - **Restudy**: (**Currently broken**)
 - **Reuters**: (**Currently broken**)
 - **ReverbNation**
 - **RheinMainTV**
 - **RideHome**
 - **RinseFM**
 - **RinseFMArtistPlaylist**
 - **RMCDecouverte**
 - **RockstarGames**: (**Currently broken**)
 - **Rokfin**: [*rokfin*](## "netrc machine")
 - **rokfin:channel**: Rokfin Channels
 - **rokfin:search**: Rokfin Search; "rkfnsearch:" prefix
 - **rokfin:stack**: Rokfin Stacks
 - **RoosterTeeth**: [*roosterteeth*](## "netrc machine")
 - **RoosterTeethSeries**: [*roosterteeth*](## "netrc machine")
 - **RottenTomatoes**
 - **RoyaLive**
 - **Rozhlas**
 - **RozhlasVltava**
 - **RTBF**: [*rtbf*](## "netrc machine") (**Currently broken**)
 - **RTDocumentry**
 - **RTDocumentryPlaylist**
 - **rte**: Raidió Teilifís Éireann TV
 - **rte:radio**: Raidió Teilifís Éireann radio
 - **rtl.lu:article**
 - **rtl.lu:tele-vod**
 - **rtl.nl**: rtl.nl and rtlxl.nl
 - **rtl2**
 - **RTLLuLive**
 - **RTLLuRadio**
 - **RTNews**
 - **RTP**
 - **RTRFM**
 - **RTS**: RTS.ch (**Currently broken**)
 - **RTVCKaltura**
 - **RTVCPlay**
 - **RTVCPlayEmbed**
 - **rtve.es:alacarta**: RTVE a la carta and Play
 - **rtve.es:audio**: RTVE audio
 - **rtve.es:live**: RTVE.es live streams
 - **rtve.es:program**: RTVE.es programs
 - **rtve.es:television**
 - **rtvslo.si**
 - **rtvslo.si:show**
 - **RudoVideo**
 - **Rule34Video**
 - **Rumble**
 - **RumbleChannel**
 - **RumbleEmbed**
 - **Ruptly**
 - **rutube**: Rutube videos
 - **rutube:channel**: Rutube channel
 - **rutube:embed**: Rutube embedded videos
 - **rutube:movie**: Rutube movies
 - **rutube:person**: Rutube person videos
 - **rutube:playlist**: Rutube playlists
 - **rutube:tags**: Rutube tags
 - **Ruutu**: (**Currently broken**)
 - **Ruv**
 - **ruv.is:spila**
 - **S4C**
 - **S4CSeries**
 - **safari**: [*safari*](## "netrc machine") safaribooksonline.com online video
 - **safari:api**: [*safari*](## "netrc machine")
 - **safari:course**: [*safari*](## "netrc machine") safaribooksonline.com online courses
 - **Saitosan**: (**Currently broken**)
 - **SAKTV**: [*saktv*](## "netrc machine")
 - **SAKTVLive**: [*saktv*](## "netrc machine")
 - **SAKTVRecordings**: [*saktv*](## "netrc machine")
 - **SaltTV**: [*salttv*](## "netrc machine")
 - **SaltTVLive**: [*salttv*](## "netrc machine")
 - **SaltTVRecordings**: [*salttv*](## "netrc machine")
 - **SampleFocus**
 - **Sangiin**: 参議院インターネット審議中継 (archive)
 - **Sapo**: SAPO Vídeos
 - **SaucePlus**: Sauce+
 - **SBS**: sbs.com.au
 - **sbs.co.kr**
 - **sbs.co.kr:allvod_program**
 - **sbs.co.kr:programs_vod**
 - **schooltv**
 - **ScienceChannel**
 - **Screen9**
 - **Screencast**
 - **Screencastify**
 - **ScreencastOMatic**
 - **ScreenRec**
 - **ScrippsNetworks**
 - **scrippsnetworks:watch**
 - **Scrolller**
 - **sejm**
 - **Sen**
 - **SenalColombiaLive**: (**Currently broken**)
 - **senate.gov**
 - **senate.gov:isvp**
 - **SendtoNews**: (**Currently broken**)
 - **Servus**
 - **Sexu**: (**Currently broken**)
 - **SeznamZpravy**
 - **SeznamZpravyArticle**
 - **Shahid**: [*shahid*](## "netrc machine")
 - **ShahidShow**
 - **SharePoint**
 - **ShareVideosEmbed**
 - **ShemarooMe**
 - **Shiey**
 - **ShowRoomLive**
 - **ShugiinItvLive**: 衆議院インターネット審議中継
 - **ShugiinItvLiveRoom**: 衆議院インターネット審議中継 (中継)
 - **ShugiinItvVod**: 衆議院インターネット審議中継 (ビデオライブラリ)
 - **SibnetEmbed**
 - **simplecast**
 - **simplecast:episode**
 - **simplecast:podcast**
 - **Sina**
 - **Skeb**
 - **sky.it**
 - **sky:news**
 - **sky:​news:story**
 - **sky:sports**
 - **sky:​sports:news**
 - **SkylineWebcams**: (**Currently broken**)
 - **skynewsarabia:article**: (**Currently broken**)
 - **skynewsarabia:video**: (**Currently broken**)
 - **SkyNewsAU**
 - **Slideshare**
 - **SlidesLive**
 - **Slutload**
 - **smotrim**
 - **smotrim:audio**
 - **smotrim:live**
 - **smotrim:playlist**
 - **SnapchatSpotlight**
 - **Snotr**
 - **SoftWhiteUnderbelly**: [*softwhiteunderbelly*](## "netrc machine")
 - **Sohu**
 - **SohuV**
 - **SonyLIV**: [*sonyliv*](## "netrc machine")
 - **SonyLIVSeries**
 - **soop**: [*afreecatv*](## "netrc machine") sooplive.co.kr
 - **soop:catchstory**: [*afreecatv*](## "netrc machine") sooplive.co.kr catch story
 - **soop:live**: [*afreecatv*](## "netrc machine") sooplive.co.kr livestreams
 - **soop:user**: [*afreecatv*](## "netrc machine")
 - **soundcloud**: [*soundcloud*](## "netrc machine")
 - **soundcloud:playlist**: [*soundcloud*](## "netrc machine")
 - **soundcloud:related**: [*soundcloud*](## "netrc machine")
 - **soundcloud:search**: [*soundcloud*](## "netrc machine") Soundcloud search; "scsearch:" prefix
 - **soundcloud:set**: [*soundcloud*](## "netrc machine")
 - **soundcloud:trackstation**: [*soundcloud*](## "netrc machine")
 - **soundcloud:user**: [*soundcloud*](## "netrc machine")
 - **soundcloud:​user:permalink**: [*soundcloud*](## "netrc machine")
 - **SoundcloudEmbed**
 - **soundgasm**
 - **soundgasm:profile**
 - **southpark.cc.com**
 - **southpark.cc.com:español**
 - **southpark.de**
 - **southpark.lat**
 - **southparkstudios.co.uk**
 - **southparkstudios.com.br**
 - **southparkstudios.nu**
 - **SovietsCloset**
 - **SovietsClosetPlaylist**
 - **SpankBang**
 - **SpankBangPlaylist**
 - **Spiegel**
 - **Sport5**
 - **SportBox**: (**Currently broken**)
 - **sporteurope**
 - **Spreaker**
 - **SpreakerShow**
 - **SpringboardPlatform**
 - **SproutVideo**
 - **sr:mediathek**: Saarländischer Rundfunk
 - **SRGSSR**
 - **SRGSSRPlay**: srf.ch, rts.ch, rsi.ch, rtr.ch and swissinfo.ch play sites
 - **StacommuLive**: [*stacommu*](## "netrc machine")
 - **StacommuVOD**: [*stacommu*](## "netrc machine")
 - **StagePlusVODConcert**: [*stageplus*](## "netrc machine")
 - **stanfordoc**: Stanford Open ClassRoom
 - **startrek**: STAR TREK
 - **startv**
 - **Steam**
 - **SteamCommunity**
 - **SteamCommunityBroadcast**
 - **Stitcher**
 - **StitcherShow**
 - **StoryFire**
 - **StoryFireSeries**
 - **StoryFireUser**
 - **Streaks**
 - **Streamable**
 - **StreamCZ**
 - **StreetVoice**
 - **StretchInternet**
 - **Stripchat**
 - **stv:player**
 - **stvr**: Slovak Television and Radio (formerly RTVS)
 - **Subsplash**
 - **subsplash:playlist**
 - **Substack**
 - **SunPorno**
 - **sverigesradio:episode**
 - **sverigesradio:publication**
 - **svt:page**
 - **svt:play**: SVT Play and Öppet arkiv
 - **svt:​play:series**
 - **SwearnetEpisode**
 - **Syfy**
 - **SYVDK**
 - **SztvHu**
 - **t-online.de**: (**Currently broken**)
 - **Tagesschau**: (**Currently broken**)
 - **TapTapApp**
 - **TapTapAppIntl**
 - **TapTapMoment**
 - **TapTapPostIntl**
 - **tarangplus:episodes**
 - **tarangplus:playlist**
 - **tarangplus:video**
 - **Tass**: (**Currently broken**)
 - **TBS**
 - **TBSJPEpisode**
 - **TBSJPPlaylist**
 - **TBSJPProgram**
 - **Teachable**: [*teachable*](## "netrc machine") (**Currently broken**)
 - **TeachableCourse**: [*teachable*](## "netrc machine")
 - **teachertube**: teachertube.com videos (**Currently broken**)
 - **teachertube:​user:collection**: teachertube.com user and collection videos (**Currently broken**)
 - **TeachingChannel**: (**Currently broken**)
 - **Teamcoco**
 - **TeamTreeHouse**: [*teamtreehouse*](## "netrc machine")
 - **techtv.mit.edu**
 - **TedEmbed**
 - **TedPlaylist**
 - **TedSeries**
 - **TedTalk**
 - **Tele13**
 - **Tele5**
 - **TeleBruxelles**
 - **TelecaribePlay**
 - **Telecinco**: telecinco.es, cuatro.com and mediaset.es
 - **Telegraaf**
 - **telegram:embed**
 - **TeleMB**: (**Currently broken**)
 - **Telemundo**: (**Currently broken**)
 - **TeleQuebec**
 - **TeleQuebecEmission**
 - **TeleQuebecLive**
 - **TeleQuebecSquat**
 - **TeleQuebecVideo**
 - **TeleTask**: (**Currently broken**)
 - **Telewebion**: (**Currently broken**)
 - **Tempo**
 - **TennisTV**: [*tennistv*](## "netrc machine")
 - **TF1**
 - **TFO**: (**Currently broken**)
 - **theatercomplextown:ppv**: [*theatercomplextown*](## "netrc machine")
 - **theatercomplextown:vod**: [*theatercomplextown*](## "netrc machine")
 - **TheChosen**
 - **TheChosenGroup**
 - **TheGuardianPodcast**
 - **TheGuardianPodcastPlaylist**
 - **TheHighWire**
 - **TheHoleTv**
 - **TheIntercept**
 - **ThePlatform**
 - **ThePlatformFeed**
 - **TheStar**
 - **TheSun**
 - **TheWeatherChannel**
 - **ThisAmericanLife**
 - **ThisOldHouse**: [*thisoldhouse*](## "netrc machine")
 - **ThisVid**
 - **ThisVidMember**
 - **ThisVidPlaylist**
 - **ThreeSpeak**
 - **ThreeSpeakUser**
 - **TikTok**
 - **tiktok:collection**
 - **tiktok:effect**: (**Currently broken**)
 - **tiktok:live**
 - **tiktok:sound**: (**Currently broken**)
 - **tiktok:tag**: (**Currently broken**)
 - **tiktok:user**
 - **TLC**
 - **TMZ**
 - **TNAFlix**
 - **TNAFlixNetworkEmbed**
 - **toggle**
 - **toggo**
 - **tokfm:audition**
 - **tokfm:podcast**
 - **ToonGoggles**
 - **tou.tv**: [*toutv*](## "netrc machine")
 - **toutiao**: 今日头条
 - **Toypics**: Toypics video (**Currently broken**)
 - **ToypicsUser**: Toypics user profile (**Currently broken**)
 - **TrailerAddict**: (**Currently broken**)
 - **TravelChannel**
 - **Triller**: [*triller*](## "netrc machine")
 - **TrillerShort**
 - **TrillerUser**: [*triller*](## "netrc machine")
 - **Trovo**
 - **TrovoChannelClip**: All Clips of a trovo.live channel; "trovoclip:" prefix
 - **TrovoChannelVod**: All VODs of a trovo.live channel; "trovovod:" prefix
 - **TrovoVod**
 - **TrtCocukVideo**
 - **TrtWorld**
 - **TrueID**
 - **TruNews**
 - **Truth**
 - **ttinglive**: 띵라이브 (formerly FlexTV)
 - **Tube8**: (**Currently broken**)
 - **TubeTuGraz**: [*tubetugraz*](## "netrc machine") tube.tugraz.at
 - **TubeTuGrazSeries**: [*tubetugraz*](## "netrc machine")
 - **tubitv**: [*tubitv*](## "netrc machine")
 - **tubitv:series**
 - **Tumblr**: [*tumblr*](## "netrc machine")
 - **tunein:embed**
 - **tunein:podcast**
 - **tunein:​podcast:program**
 - **tunein:station**
 - **tv.dfb.de**
 - **TV2**
 - **TV2Article**
 - **TV2DK**
 - **TV2DKBornholmPlay**
 - **tv2play.hu**
 - **tv2playseries.hu**
 - **TV4**: tv4.se and tv4play.se
 - **TV5MONDE**
 - **tv5unis**
 - **tv5unis:video**
 - **tv8.it**
 - **tv8.it:live**: TV8 Live
 - **tv8.it:playlist**: TV8 Playlist
 - **TVANouvelles**
 - **TVANouvellesArticle**
 - **tvaplus**: TVA+
 - **TVC**
 - **TVCArticle**
 - **TVer**
 - **tvigle**: Интернет-телевидение Tvigle.ru
 - **TVIPlayer**
 - **TVN24**: (**Currently broken**)
 - **tvnoe**: Televize Noe
 - **tvopengr:embed**: tvopen.gr embedded videos
 - **tvopengr:watch**: tvopen.gr (and ethnos.gr) videos
 - **tvp**: Telewizja Polska
 - **tvp:embed**: Telewizja Polska
 - **tvp:stream**
 - **tvp:vod**
 - **tvp:​vod:series**
 - **TVPlayer**
 - **TVPlayHome**
 - **tvw**
 - **tvw:news**
 - **tvw:tvchannels**
 - **Tweakers**
 - **TwitCasting**
 - **TwitCastingLive**
 - **TwitCastingUser**
 - **twitch:clips**: [*twitch*](## "netrc machine")
 - **twitch:collection**: [*twitch*](## "netrc machine")
 - **twitch:stream**: [*twitch*](## "netrc machine")
 - **twitch:videos**: [*twitch*](## "netrc machine")
 - **twitch:​videos:clips**: [*twitch*](## "netrc machine")
 - **twitch:​videos:collections**: [*twitch*](## "netrc machine")
 - **twitch:vod**: [*twitch*](## "netrc machine")
 - **twitter**
 - **twitter:amplify**
 - **twitter:broadcast**
 - **twitter:card**
 - **twitter:shortener**
 - **twitter:spaces**
 - **Txxx**
 - **udemy**: [*udemy*](## "netrc machine")
 - **udemy:course**: [*udemy*](## "netrc machine")
 - **UDNEmbed**: 聯合影音
 - **UFCArabia**: [*ufcarabia*](## "netrc machine")
 - **UFCTV**: [*ufctv*](## "netrc machine")
 - **ukcolumn**: (**Currently broken**)
 - **UKTVPlay**
 - **UlizaPlayer**
 - **UlizaPortal**: ulizaportal.jp
 - **umg:de**: Universal Music Deutschland
 - **Unistra**
 - **UnitedNationsWebTv**
 - **Unity**: (**Currently broken**)
 - **uol.com.br**
 - **uplynk**
 - **uplynk:preplay**
 - **Urort**: NRK P3 Urørt (**Currently broken**)
 - **URPlay**
 - **USANetwork**
 - **USAToday**
 - **ustream**
 - **ustream:channel**
 - **ustudio**
 - **ustudio:embed**
 - **Varzesh3**: (**Currently broken**)
 - **Vbox7**
 - **Veo**
 - **Vevo**
 - **VevoPlaylist**
 - **VGTV**: VGTV, BTTV, FTV, Aftenposten and Aftonbladet
 - **vh1.com**
 - **vhx:embed**: [*vimeo*](## "netrc machine")
 - **vice**: (**Currently broken**)
 - **vice:article**: (**Currently broken**)
 - **vice:show**: (**Currently broken**)
 - **Viddler**: (**Currently broken**)
 - **Videa**
 - **video.arnes.si**: Arnes Video
 - **video.google:search**: Google Video search; "gvsearch:" prefix
 - **video.sky.it**
 - **video.sky.it:live**
 - **VideoDetective**
 - **videofy.me**: (**Currently broken**)
 - **VideoKen**
 - **VideoKenCategory**
 - **VideoKenPlayer**
 - **VideoKenPlaylist**
 - **VideoKenTopic**
 - **videomore**
 - **videomore:season**
 - **videomore:video**
 - **VideoPress**
 - **Vidflex**
 - **Vidio**: [*vidio*](## "netrc machine")
 - **VidioLive**: [*vidio*](## "netrc machine")
 - **VidioPremier**: [*vidio*](## "netrc machine")
 - **VidLii**
 - **Vidly**
 - **vids.io**
 - **Vidyard**
 - **viewlift**
 - **viewlift:embed**
 - **Viidea**
 - **vimeo**: [*vimeo*](## "netrc machine")
 - **vimeo:album**: [*vimeo*](## "netrc machine")
 - **vimeo:channel**: [*vimeo*](## "netrc machine")
 - **vimeo:event**: [*vimeo*](## "netrc machine")
 - **vimeo:group**: [*vimeo*](## "netrc machine")
 - **vimeo:likes**: [*vimeo*](## "netrc machine") Vimeo user likes
 - **vimeo:ondemand**: [*vimeo*](## "netrc machine")
 - **vimeo:pro**: [*vimeo*](## "netrc machine")
 - **vimeo:review**: [*vimeo*](## "netrc machine") Review pages on vimeo
 - **vimeo:user**: [*vimeo*](## "netrc machine")
 - **vimeo:watchlater**: [*vimeo*](## "netrc machine") Vimeo watch later list, ":vimeowatchlater" keyword (requires authentication)
 - **Vimm:recording**
 - **Vimm:stream**
 - **ViMP**
 - **ViMP:Playlist**
 - **Viously**
 - **Viqeo**: (**Currently broken**)
 - **Viu**
 - **viu:ott**: [*viu*](## "netrc machine")
 - **viu:playlist**
 - **ViuOTTIndonesia**
 - **vk**: [*vk*](## "netrc machine") VK
 - **vk:uservideos**: [*vk*](## "netrc machine") VK - User's Videos
 - **vk:wallpost**: [*vk*](## "netrc machine")
 - **VKPlay**
 - **VKPlayLive**
 - **vm.tiktok**
 - **Vocaroo**
 - **VODPl**
 - **VODPlatform**
 - **voicy**: (**Currently broken**)
 - **voicy:channel**: (**Currently broken**)
 - **volejtv:category**
 - **volejtv:club**
 - **volejtv:match**
 - **VoxMedia**
 - **VoxMediaVolume**
 - **vpro**: npo.nl, ntr.nl, omroepwnl.nl, zapp.nl and npo3.nl
 - **vqq:series**
 - **vqq:video**
 - **vrsquare**: VR SQUARE
 - **vrsquare:channel**
 - **vrsquare:search**
 - **vrsquare:section**
 - **VRT**: VRT NWS, Flanders News, Flandern Info and Sporza
 - **vrtmax**: [*vrtnu*](## "netrc machine") VRT MAX (formerly VRT NU)
 - **VTM**
 - **VTV**
 - **VTVGo**
 - **VTXTV**: [*vtxtv*](## "netrc machine")
 - **VTXTVLive**: [*vtxtv*](## "netrc machine")
 - **VTXTVRecordings**: [*vtxtv*](## "netrc machine")
 - **VuClip**
 - **VVVVID**
 - **VVVVIDShow**
 - **Walla**
 - **WalyTV**: [*walytv*](## "netrc machine")
 - **WalyTVLive**: [*walytv*](## "netrc machine")
 - **WalyTVRecordings**: [*walytv*](## "netrc machine")
 - **washingtonpost**
 - **washingtonpost:article**
 - **wat.tv**
 - **WatchESPN**
 - **WDR**
 - **wdr:mobile**: (**Currently broken**)
 - **WDRElefant**
 - **WDRPage**
 - **web.archive:youtube**: web.archive.org saved youtube videos, "ytarchive:" prefix
 - **Webcamerapl**
 - **Webcaster**
 - **WebcasterFeed**
 - **WebOfStories**
 - **WebOfStoriesPlaylist**
 - **Weibo**
 - **WeiboUser**
 - **WeiboVideo**
 - **WeiqiTV**: WQTV (**Currently broken**)
 - **wetv:episode**
 - **WeTvSeries**
 - **Weverse**: [*weverse*](## "netrc machine")
 - **WeverseLive**: [*weverse*](## "netrc machine")
 - **WeverseLiveTab**: [*weverse*](## "netrc machine")
 - **WeverseMedia**: [*weverse*](## "netrc machine")
 - **WeverseMediaTab**: [*weverse*](## "netrc machine")
 - **WeverseMoment**: [*weverse*](## "netrc machine")
 - **WeVidi**
 - **Weyyak**
 - **whowatch**
 - **Whyp**
 - **wikimedia.org**
 - **Wimbledon**
 - **WimTV**
 - **WinSportsVideo**
 - **Wistia**
 - **WistiaChannel**
 - **WistiaPlaylist**
 - **wnl**: npo.nl, ntr.nl, omroepwnl.nl, zapp.nl and npo3.nl
 - **wordpress:mb.miniAudioPlayer**
 - **wordpress:playlist**
 - **WorldStarHipHop**
 - **wppilot**
 - **wppilot:channels**
 - **WrestleUniversePPV**: [*wrestleuniverse*](## "netrc machine")
 - **WrestleUniverseVOD**: [*wrestleuniverse*](## "netrc machine")
 - **WSJ**: Wall Street Journal
 - **WSJArticle**
 - **WWE**
 - **wyborcza:video**
 - **WyborczaPodcast**
 - **wykop:dig**
 - **wykop:​dig:comment**
 - **wykop:post**
 - **wykop:​post:comment**
 - **XboxClips**
 - **XHamster**
 - **XHamsterEmbed**
 - **XHamsterUser**
 - **XiaoHongShu**: 小红书
 - **ximalaya**: 喜马拉雅FM
 - **ximalaya:album**: 喜马拉雅FM 专辑
 - **Xinpianchang**: 新片场
 - **XMinus**: (**Currently broken**)
 - **XNXX**
 - **Xstream**
 - **XVideos**
 - **xvideos:quickies**
 - **XXXYMovies**
 - **yahoo**
 - **yahoo:japannews**: Yahoo! Japan News
 - **yahoo:search**: "yvsearch:" prefix
 - **YandexDisk**
 - **yandexmusic:album**: Яндекс.Музыка - Альбом
 - **yandexmusic:​artist:albums**: Яндекс.Музыка - Артист - Альбомы
 - **yandexmusic:​artist:tracks**: Яндекс.Музыка - Артист - Треки
 - **yandexmusic:playlist**: Яндекс.Музыка - Плейлист
 - **yandexmusic:track**: Яндекс.Музыка - Трек
 - **YandexVideo**
 - **YandexVideoPreview**
 - **YapFiles**: (**Currently broken**)
 - **Yappy**: (**Currently broken**)
 - **YappyProfile**
 - **yfanefa**
 - **YleAreena**
 - **YouJizz**
 - **youku**: 优酷
 - **youku:show**
 - **YouNowChannel**
 - **YouNowLive**
 - **YouNowMoment**
 - **YouPorn**
 - **YouPornCategory**: YouPorn category, with sorting, filtering and pagination
 - **YouPornChannel**: YouPorn channel, with sorting and pagination
 - **YouPornCollection**: YouPorn collection (user playlist), with sorting and pagination
 - **YouPornStar**: YouPorn Pornstar, with description, sorting and pagination
 - **YouPornTag**: YouPorn tag (porntags), with sorting, filtering and pagination
 - **YouPornVideos**: YouPorn video (browse) playlists, with sorting, filtering and pagination
 - **youtube**: [*youtube*](## "netrc machine") YouTube
 - **youtube:clip**: [*youtube*](## "netrc machine")
 - **youtube:favorites**: [*youtube*](## "netrc machine") YouTube liked videos; ":ytfav" keyword (requires cookies)
 - **youtube:history**: [*youtube*](## "netrc machine") Youtube watch history; ":ythis" keyword (requires cookies)
 - **youtube:​music:search_url**: [*youtube*](## "netrc machine") YouTube music search URLs with selectable sections, e.g. #songs
 - **youtube:notif**: [*youtube*](## "netrc machine") YouTube notifications; ":ytnotif" keyword (requires cookies)
 - **youtube:playlist**: [*youtube*](## "netrc machine") YouTube playlists
 - **youtube:recommended**: [*youtube*](## "netrc machine") YouTube recommended videos; ":ytrec" keyword
 - **youtube:search**: [*youtube*](## "netrc machine") YouTube search; "ytsearch:" prefix
 - **youtube:​search:date**: [*youtube*](## "netrc machine") YouTube search, newest videos first; "ytsearchdate:" prefix
 - **youtube:search_url**: [*youtube*](## "netrc machine") YouTube search URLs with sorting and filter support
 - **youtube:​shorts:pivot:audio**: [*youtube*](## "netrc machine") YouTube Shorts audio pivot (Shorts using audio of a given video)
 - **youtube:subscriptions**: [*youtube*](## "netrc machine") YouTube subscriptions feed; ":ytsubs" keyword (requires cookies)
 - **youtube:tab**: [*youtube*](## "netrc machine") YouTube Tabs
 - **youtube:user**: [*youtube*](## "netrc machine") YouTube user videos; "ytuser:" prefix
 - **youtube:watchlater**: [*youtube*](## "netrc machine") Youtube watch later list; ":ytwatchlater" keyword (requires cookies)
 - **YoutubeLivestreamEmbed**: [*youtube*](## "netrc machine") YouTube livestream embeds
 - **YoutubeYtBe**: [*youtube*](## "netrc machine") youtu.be
 - **Zaiko**
 - **ZaikoETicket**
 - **Zapiks**
 - **Zattoo**: [*zattoo*](## "netrc machine")
 - **ZattooLive**: [*zattoo*](## "netrc machine")
 - **ZattooMovies**: [*zattoo*](## "netrc machine")
 - **ZattooRecordings**: [*zattoo*](## "netrc machine")
 - **zdf**
 - **zdf:channel**
 - **Zee5**: [*zee5*](## "netrc machine")
 - **zee5:series**
 - **ZeeNews**: (**Currently broken**)
 - **ZenPorn**
 - **ZetlandDKArticle**
 - **Zhihu**
 - **zingmp3**: zingmp3.vn
 - **zingmp3:album**
 - **zingmp3:chart-home**
 - **zingmp3:chart-music-video**
 - **zingmp3:hub**
 - **zingmp3:liveradio**
 - **zingmp3:podcast**
 - **zingmp3:podcast-episode**
 - **zingmp3:user**
 - **zingmp3:week-chart**
 - **zoom**
 - **Zype**
 - **generic**: Generic downloader that works on some sites

path: .clawhub/origin.json
content: version: 1
registry: https://clawhub.ai
slug: video-download
installedVersion: 0.1.5
installedAt: 1772354049428

Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: suspicious | SkillSpector: suspicious (CRITICAL)