Add improved video syntax: links to.mp4 and.mov turn into videos. likegithub video features.
The following is a sample test of the video preview in GitHub:
This package isESM only: Node 12+ is needed to use it and it must be import instead of require.
npminstall rehype-videoimport{ unified}from'unified';importremark2rehypefrom'remark-rehype';importremarkParsefrom'remark-parse';importrehypeVideofrom'rehype-video';importstringifyfrom'rehype-stringify';const string=`https://files.github.com/001.mp4 hi!https://files.github.com/002.mp4Good \`idea\`!!https://github.com/002.mp4?!#title=Custom%20Title`;const htmlStr=unified().use(remarkParse).use(remark2rehype,{allowDangerousHtml:true}).use(rehypeVideo).use(stringify).processSync(string).toString();Output:
<p>https://files.github.com/001.mp4 hi!</p><detailsopen><summary><svgaria-hiddenheight="16"width="16"viewBox="0 0 16 16"version="1.1"class="octicon octicon-device-camera-video"><pathfill-rule="evenodd"d="M16 3.75a.75.75 0 00-1.136-.643L11 5.425V4.75A1.75 1.75 0 009.25 3h-7.5A1.75 1.75 0 000 4.75v6.5C0 12.216.784 13 1.75 13h7.5A1.75 1.75 0 0011 11.25v-.675l3.864 2.318A.75.75 0 0016 12.25v-8.5zm-5 5.075l3.5 2.1v-5.85l-3.5 2.1v1.65zM9.5 6.75v-2a.25.25 0 00-.25-.25h-7.5a.25.25 0 00-.25.25v6.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-4.5z"></path></svg><spanaria-label="Video description 002.mp4">002.mp4</span><spanclass="dropdown-caret"></span></summary><videomutedcontrolsstyle="max-height:640px;"src="https://github.com/002.mp4"></video></details><p>Good<code>idea</code>!!</p><detailsopen><summary><svgaria-hiddenheight="16"width="16"viewBox="0 0 16 16"version="1.1"class="octicon octicon-device-camera-video"><pathfill-rule="evenodd"d="M16 3.75a.75.75 0 00-1.136-.643L11 5.425V4.75A1.75 1.75 0 009.25 3h-7.5A1.75 1.75 0 000 4.75v6.5C0 12.216.784 13 1.75 13h7.5A1.75 1.75 0 0011 11.25v-.675l3.864 2.318A.75.75 0 0016 12.25v-8.5zm-5 5.075l3.5 2.1v-5.85l-3.5 2.1v1.65zM9.5 6.75v-2a.25.25 0 00-.25-.25h-7.5a.25.25 0 00-.25.25v6.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-4.5z"></path></svg><spanaria-label="Video description Custom Title">Custom Title</span><spanclass="dropdown-caret"></span></summary><videomutedcontrolsstyle="max-height:640px;"src="https://github.com/002.mp4"></video></details>import{ rehype}from'rehype';importrehypeVideofrom'rehype-video';const mrkStr=`<p>https://github.com/004.mp4</p>`;const htmlStr=rehype().data('settings',{fragment:true}).use(rehypeVideo,{details:false}).processSync(mrkStr).toString();Output:
<videomutedcontrolsstyle="max-height:640px;"src="https://github.com/004.mp4"></video>import{ rehype}from'rehype';importrehypeVideofrom'rehype-video';const mrkStr=`<p><a href="https://github.com/004.mp4">https://github.com/004.mp4</a></p`;const htmlStr=rehype().data('settings',{fragment:true}).use(rehypeVideo,{details:false}).processSync(mrkStr).toString();Output:
<videomutedcontrolsstyle="max-height:640px;"src="https://github.com/004.mp4"></video>importremarkParsefrom'remark-parse';importrehypeVideofrom'rehype-video';import{ unified}from'unified';importremark2rehypefrom'remark-rehype';importremarkParsefrom'remark-parse';importstringifyfrom'rehype-stringify';const mrkStr='https://github.com/user-attachments/assets/0d808e2e-84c7-46ca-a220-440fa9f34118?title=rehype-video&rehype=video'const htmlStr=unified().use(remarkParse).use(remark2rehype,{allowDangerousHtml:true}).use(rehypeVideo,{test:(url)=>{return/\.(mp4|mov)|[?&]rehype=video/i.test(url);}}).use(stringify).processSync(mrkStr).toString();Output:
<detailsopenclass="octicon octicon-video"><summary><svgaria-hiddenheight="16"width="16"viewBox="0 0 16 16"version="1.1"data-view-componentclass="octicon octicon-device-camera-video"><pathfill-rule="evenodd"d="M16 3.75a.75.75 0 00-1.136-.643L11 5.425V4.75A1.75 1.75 0 009.25 3h-7.5A1.75 1.75 0 000 4.75v6.5C0 12.216.784 13 1.75 13h7.5A1.75 1.75 0 0011 11.25v-.675l3.864 2.318A.75.75 0 0016 12.25v-8.5zm-5 5.075l3.5 2.1v-5.85l-3.5 2.1v1.65zM9.5 6.75v-2a.25.25 0 00-.25-.25h-7.5a.25.25 0 00-.25.25v6.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-4.5z"></path></svg><spanaria-label="Video description rehype-video">rehype-video</span><spanclass="dropdown-caret"></span></summary><videomutedcontrolsstyle="max-height:640px;"src="https://github.com/user-attachments/assets/0d808e2e-84c7-46ca-a220-440fa9f34118?title=rehype-video&rehype=video"></video></details>Define custom title parameter(E.g:title=RehypeVideo) with hash route:
const string=`https://github.com/002.mp4?!#title=Custom%20Title`;const htmlStr=unified().use(remarkParse).use(remark2rehype,{allowDangerousHtml:true}).use(rehypeVideo).use(stringify).processSync(string).toString();Output:
<detailsopen><summary><svgaria-hiddenheight="16"width="16"viewBox="0 0 16 16"version="1.1"class="octicon octicon-device-camera-video"><pathfill-rule="evenodd"d="M16 3.75a.75.75 0 00-1.136-.643L11 5.425V4.75A1.75 1.75 0 009.25 3h-7.5A1.75 1.75 0 000 4.75v6.5C0 12.216.784 13 1.75 13h7.5A1.75 1.75 0 0011 11.25v-.675l3.864 2.318A.75.75 0 0016 12.25v-8.5zm-5 5.075l3.5 2.1v-5.85l-3.5 2.1v1.65zM9.5 6.75v-2a.25.25 0 00-.25-.25h-7.5a.25.25 0 00-.25.25v6.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-4.5z"></path></svg><spanaria-label="Video description Custom Title">Custom Title</span><spanclass="dropdown-caret"></span></summary><videomutedcontrolsstyle="max-height:640px;"src="https://github.com/002.mp4"></video></details>We will reference all two of the relevant VTT files by adding<track> elements inside our HTML<video> element:
const mrkStr=`https://github.com/sintel-short.mp4?!#track['en']=captions/vtt/sintel-en.vtt&track['en:label']=English&track['en:kind']=subtitles&track['en:default']=true&track['de']=captions/vtt/sintel-de.vtt&track['de:label']=Deutsch&track['de:kind']=subtitles`;const htmlStr=unified().use(remarkParse).use(remark2rehype,{allowDangerousHtml:true}).use(rehypeVideo,{}).use(stringify).processSync(mrkStr).toString();Output:
<detailsopenclass="octicon octicon-video"><summary><svgaria-hiddenheight="16"width="16"viewBox="0 0 16 16"version="1.1"data-view-componentclass="octicon octicon-device-camera-video"><pathfill-rule="evenodd"d="M16 3.75a.75.75 0 00-1.136-.643L11 5.425V4.75A1.75 1.75 0 009.25 3h-7.5A1.75 1.75 0 000 4.75v6.5C0 12.216.784 13 1.75 13h7.5A1.75 1.75 0 0011 11.25v-.675l3.864 2.318A.75.75 0 0016 12.25v-8.5zm-5 5.075l3.5 2.1v-5.85l-3.5 2.1v1.65zM9.5 6.75v-2a.25.25 0 00-.25-.25h-7.5a.25.25 0 00-.25.25v6.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-4.5z"></path></svg><spanaria-label="Video description sintel-short.mp4">sintel-short.mp4</span><spanclass="dropdown-caret"></span></summary><videomutedcontrolsstyle="max-height:640px;"src="https://github.com/sintel-short.mp4?!#track['en']=captions/vtt/sintel-en.vtt&track['en:label']=English&track['en:kind']=subtitles&track['en:default']=true&track['de']=captions/vtt/sintel-de.vtt&track['de:label']=Deutsch&track['de:kind']=subtitles"><trackkind="subtitles"src="captions/vtt/sintel-en.vtt"label="English"default><trackkind="subtitles"src="captions/vtt/sintel-de.vtt"label="Deutsch"></video></details>exportdeclaretypeRehypeVideoOptions={/** * URL suffix verification. * @default /\/(.*)(.mp4|.mov)$/ */ test?: RegExp;/** * Support `<details>` tag to wrap <video>. * @default true */ details?:boolean;/** * Support `<track>` tag to wrap <video>. * @default true */ track?:boolean;};rehype-attr New syntax to add attributes to Markdown.rehype-rewrite Rewrite element with rehype.rehype-ignore Ignore content display via HTML comments, Shown in GitHub readme, excluded in HTML.remark-github-blockquote-alert Remark plugin to add support forGitHub AlertMIT ©Kenny Wong