Tiptap Twitch 扩展(@tiptap/extension-twitch)使用指南:嵌入视频、直播频道与剪辑的完整方案
【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap
@tiptap/extension-twitch是 Tiptap 官方提供的无头(headless)节点扩展,用于在富文本编辑器中内嵌 Twitch 直播流、点播视频(VOD)与剪辑(Clip),支持自动播放、静音、起始播放时间等可定制参数,并允许通过节点属性实现单条嵌入覆盖全局配置。阅读完本文,你将掌握该扩展的安装配置、URL 解析规则、嵌入渲染与回读机制,以及如何在 React / Vue 工程中通过setTwitchVideo命令与粘贴规则真正落地使用。
本扩展从属于 Tiptap 3.x 系列(当前仓库版本为 3.30.3),其发布与修复历史完整记录在 packages/extension-twitch/CHANGELOG.md:3.0.0 首次发布;3.14.0 作为 Minor Change 引入完整能力(见 twitch.ts 与 utils.ts);3.23.2 修复了 Twitch/YouTube 嵌入在 HTML 回载时丢失原始视频、剪辑、频道或播放列表 URL 的问题;其余版本均为随 @tiptap/core 的依赖同步升级(Patch Changes)。
安装与依赖
该扩展作为独立 npm 包发布,包元数据见 package.json。它采用 ESM 优先的模块格式,同时导出 CJS 与类型声明(main/module/types与exports映射均已配置)。@tiptap/core同时出现在peerDependencies与devDependencies(workspace 引用),因此你的项目中需先安装与扩展同版本的 core:
# 使用与 @tiptap/core 相匹配的版本 pnpm add @tiptap/extension-twitch # 或 npm / yarn 等任意包管理器扩展本身没有运行时外部依赖,渲染时生成的<iframe>直接指向 Twitch 官方播放器(player.twitch.tv/clips.twitch.tv/embed),无需申请 API Key。
快速上手:在编辑器中加入 Twitch 节点
安装后,将Twitch加入扩展列表,并用parent选项指定承载页面的域名即可工作。以 React 为例(完整可运行示例见 demos/src/Nodes/Twitch/React/index.jsx):
import { EditorContent, useEditor } from '@tiptap/react' import StarterKit from '@tiptap/starter-kit' import Twitch from '@tiptap/extension-twitch' const editor = useEditor({ extensions: [ StarterKit, Twitch.configure({ // 当前页面域名,Twitch 官方要求 parent 必须匹配 iframe 宿主域名 parent: window.location.hostname, allowFullscreen: true, }), ], content: `<div>editor.commands.setTwitchVideo({ src: 'https://www.twitch.tv/videos/1234567890', width: 800, height: 450, autoplay: true, muted: true, time: '1h2m3s', // 仅对点播视频生效 })命令返回boolean:URL 非法时返回false且不产生任何内容变更。真实演示(React/Vue 双实现)里用输入框控制宽高并调用该命令,demo 源码 中做了Math.max(320, width)、Math.max(180, height)这类下限约束,可作参考。
支持的 Twitch URL 类型与解析
扩展围绕三类 Twitch 内容工作,其 URL 匹配规则由 utils.ts 中的TWITCH_REGEX定义:
| 类型 | 支持的 URL 形态 | 说明 |
|---|---|---|
| 点播视频 VOD | https://twitch.tv/videos/1234567890、https://www.twitch.tv/videos/1234567890 | 匹配/videos/<数字ID> |
| 剪辑 Clip | https://twitch.tv/某频道/clip/ClipName-123、https://clips.twitch.tv/ClipName(含www.前缀) | 频道内剪辑与clips.twitch.tv短链 |
| 直播频道 Channel | https://twitch.tv/某频道、https://www.twitch.tv/某频道 | 形如LofiGirl的频道名 |
正则同样允许 URL 携带任意 query 参数((\?.*)?结尾),因此在粘贴/插入?filter=archives&sort=time这类带查询串的链接时,扩展会安全剔除多余参数、只保留嵌入所需的标识信息(详见下文渲染与测试)。从源码结构可以推断,URL 到“类型 + ID”的映射由工具函数getTwitchIdentifier统一完成:
getTwitchIdentifier('https://www.twitch.tv/videos/1234567890') // { type: 'video', id: '1234567890' } getTwitchIdentifier('https://www.twitch.tv/examplechannel/clip/ExampleClipName-ABC123') // { type: 'clip', id: 'ExampleClipName-ABC123' } getTwitchIdentifier('https://www.twitch.tv/examplechannel') // { type: 'channel', id: 'examplechannel' }这些函数与正则均从 packages/extension-twitch/src/index.ts 对外导出,可在编辑器之外的场景直接复用(例如表单预校验、播放链接转换)。
配置选项(Options)详解
Twitch节点通过Node.create<TwitchOptions>定义,全部选项的默认值见 twitch.ts 的addOptions():
| 选项 | 类型 | 默认值 | 作用 |
|---|---|---|---|
addPasteHandler | boolean | true | 是否启用粘贴/拖入 Twitch URL 自动转为嵌入节点的规则 |
allowFullscreen | boolean | true | 是否允许播放器全屏(渲染为 iframe 的allowfullscreen与播放器 query 参数) |
autoplay | boolean | false | 是否自动播放 |
muted | boolean | false | 是否默认静音(浏览器自动播放策略下通常需要与 autoplay 搭配) |
time | string \| undefined | undefined | 起始播放时间,格式形如1h2m3s,仅对点播视频生效,不适用于剪辑与频道 |
parent | string | 'localhost' | 承载嵌入的父级域名,Twitch 官方要求必填且需与页面域名一致,生产环境必须显式配置为你的域名 |
height | number | 480 | iframe 高度(像素) |
width | number | 640 | iframe 宽度(像素) |
HTMLAttributes | Record<string, any> | {} | 附加到 iframe 上的 HTML 属性,例如{ class: 'foo' } |
inline | boolean | false | 节点是否作为行内元素。为false时节点组为block,为true时组为inline |
配置示例:
Twitch.configure({ parent: 'example.com', // 必须替换为实际部署域名 allowFullscreen: true, autoplay: true, muted: true, // 自动播放策略通常要求同时开启 width: 1280, height: 720, HTMLAttributes: { class: 'twitch-embed' }, })选项与属性的优先级:per-embed 覆盖
3.14.0 引入的“属性级覆盖”(attribute-level overrides)是这套配置体系的关键设计:autoplay、muted、time以及width、height同时既可以是全局选项,也可以是单个节点的attrs。渲染时按“节点属性优先于全局选项”合并(见 twitch.ts 的renderHTML中HTMLAttributes.autoplay ?? this.options.autoplay这类表达式)。即:全局默认全自动播放时,某个具体视频节点仍可通过自己的autoplay: false关闭。
从 URL 到 iframe:嵌入渲染原理
Twitch节点把“用户友好的分享链接”转换渲染为“Twitch 官方播放器嵌入地址”,核心链路为:
用户URL → getTwitchIdentifier(识别类型+ID) → getEmbedUrlFromTwitchUrl(组装 player.twitch.tv / clips.twitch.tv/embed) → renderHTML 输出 <div><div>Twitch.configure({ parent: 'example.com', addPasteHandler: false, })测试与行为保障
扩展的行为有较完整的自动化测试覆盖(packages/extension-twitch/tests/twitch.spec.ts),可以作为使用时理解行为边界的“活的文档”:
- 安全校验:
javascript:scheme 与仿冒域名(twitch.google.com、twitch.com.bad、twtich.tv拼写错误)不会被输出为可点击/可嵌入的 HTML; - 三类 URL 渲染:视频、剪辑、频道分别断言了生成的 iframe 指向
player.twitch.tv或clips.twitch.tv/embed且携带parent; - 选项生效:
allowFullscreen、自定义宽高、muted、视频time=1h2m3s均能在输出 HTML 中体现; - 属性覆盖:全局
autoplay: true+ 节点autoplay: false时最终输出不含autoplay=true;time同理以节点属性为准(如全局1h0m0s被节点2h30m15s覆盖); - 来回往返:视频/剪辑/频道三种 URL 经
getHTML()后再载回编辑器,getJSON()中的src保持原始链接(对应 3.23.2 修复的回归测试); - 容错:宽高为
100%/auto时不会产生NaN属性(getParsedDimension兜底为null);非法 src 回载不抛错并输出Invalid Twitch URL;畸形 embed 标识(如video=abc、含非法字符的 clip)返回null。
版本演进一览
结合 CHANGELOG.md 可看到清晰的演进脉络:
- 3.0.0(Major):Twitch 扩展首次发布;
- 3.14.0(Minor):引入视频、剪辑、直播频道三种嵌入能力,支持
autoplay、muted、起始时间等可定制参数,并支持单节点属性级覆盖(commit 5717dcf); - 3.23.2(Patch):修复 HTML 回载时 Twitch/YouTube 嵌入丢失原始视频/剪辑/频道/播放列表 URL 的问题(commit 79fc8b7),与
getAttributesFromTwitchEmbedUrl反哺解析机制直接相关; - 3.22.4(Patch):修复包升级后 peer dependency 解析冲突导致的依赖安装问题(commit 27ea931);
- 其余 Patch:均随
@tiptap/core版本同步升级,始终要求与 core 保持同版本,避免类型与行为错位。
当前仓库内扩展版本为 3.30.3,其 peer 依赖为@tiptap/core@3.30.3,安装时请注意保持版本一致。
【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考