给Markdown添加视频支持

栏目: IT技术 · 发布时间: 4年前

内容简介:都2020年了,现在最流行的就是什么直播弹幕短视频,你的博客要是还不支持插视频那可就OUT啦!本博客目前使用Markdown写文,可惜它原生的语法并不支持视频,于是只能自己来实现这功能了。视频是个好东西啊,它要不好现在的直播弹幕短视频怎么火的……咳咳,扯远了,就说写博客,比如写教程啊总会遇到需要动态演示的东西吧,比如我自己的

都2020年了,现在最流行的就是什么直播弹幕短视频,你的博客要是还不支持插视频那可就OUT啦!

本博客目前使用Markdown写文,可惜它原生的语法并不支持视频,于是只能自己来实现这功能了。

视频好处都有啥?

视频是个好东西啊,它要不好现在的直播弹幕短视频怎么火的……咳咳,扯远了,就说写博客,比如写教程啊总会遇到需要动态演示的东西吧,比如我自己的 纯CSS解决图片加载的布局移动问题 里一开头的动图(其实是视频啦),要用图片或者文字来说明文本下移的现象肯定没有动态的演示好。

另外玩过Twitter的都知道它里面插入的GIF图会转换为视频, GIF是1987年发明的东西,在我看来早是就该进入垃圾堆的技术,因为当年浏览器不支持视频才得以流行 。动图这一技术完全能被视频所替代,视频本身就不是一连串图像的序列吗(当然还包括声音)。

在性能上, H.246编码的视频体积仅为GIF的13分之一 ,虽然GIF也有gifsicle能压缩一下,但效果仍不如视频。

从我的实际经验来看,技术类文章里大部分动态演示都来源于录屏,录屏软件生成的本来就是视频格式,把它们转GIF多此一举。 综上所述,视频的支持是一个现代化博客必需的功能

语法的选择

给Markdown添加视频支持 Markdown版本演进

上图来自 https://juejin.im/post/5baa5b346fb9a05d2d0225cc#heading-6

主要的几个Markdown版本原生都不支持视频,我不知道它的作者是怎么想的,如此重要的功能竟然能没有。既然官方没有,那就自己做呗,于是种各样的实现方案就跑了出来, 按照本人强迫症的做法当然要对比一番

直接插HTML

这是我看到的最多的做法,其优势就是简单,现有的转换库都支持写HTML,但我认为这种方式并不好。

  • XSS风险:若是自己用还好说,一旦给评论之类的第三方输入用上,你都猜不到他们会搞些什么出来。

  • 扩展性差:一旦写死,以后想改动下输出的HTML可就麻烦了,需要把所有文章都扫一遍,本博客就遇到过需要改动渲染结果的情况。

  • 可读性差:Markdown作为轻量级标记语言,扫一眼即可轻松Parse是其一大优势,一旦混入重量级的HTML则可读性大打折扣。

这缺点太多,所以我决定还是得用Markdown的方式来做。

GitLab Flavored Markdown

GitLab Flavored Markdown(下称GFM) 是Markdown的一种修改版,它复用了图片的语法,以扩展名来区分媒体的类型,比如 ![label](foobar.mp4) 因为链接是 .mp4 结尾所以渲染为视频。

GFM的支持也很广泛,实现又简单,还有GitLab背书,自然也是个不错的选择。

但它的缺点也很明显,强制了链接的文件名必须是视频常用的扩展名,然而并不是所有链接都是如此,Twitter的视频链接就没有扩展名。另外既然都修改了原始的Markdown语义,何不直接另起一个新语法呢?

自己编个语法

关于自定义的语法 有很多讨论 ,我认为比较好的一种是使用 通用指令语法 ,它的格式是 @<指令类型>[...](..){...} 这样的,前面的@可以换成别的,指令类型用于区分视频、音频、GIF视频等,后面三个括号里的内容可以自由发挥。

最终我决定使用这种语法,它跟原生的图片语法一样简洁,又给足了自由发挥的余地。

通常来说,新的语法最好还是跟现有的保持相似,这里就以语法比较像的图片为基准。圆括号仍然跟图片一样包含视频的链接,方括号里填标签(GIF)或者poster(视频)。

通用指令语法里,花括号用来放置 key = "val" 这样的键值对,但它们同样可以放在链接URL的参数上,而且目前图片就是这么做的,为了保持一致,我选择不要这个花括号部分。

指令类型包含GIF视频和普通视频,另外Markdown同样不支持插入音频这里也给补上,所以最终的语法为:

  • @audio[](音频链接) 插入一个音频。

  • @gif[标签](视频链接) 插入视频,并尽可能模仿GIF图。

  • @video[视频封面](视频链接) 插入普通视频。

解析器的实现

我的博客使用 markdown-it 来转换Markdown为HTML,markdown-it 的流程分为解析和渲染两部分,所以要给这两个地方编写自己的函数实现。

首先是怎么识别 @<指令类型>[...](..) 这种文本呢,如果不考虑转义的话倒是一个正则就能搞定,但问题是如果标签里出现了方括号,或者链接里有圆括号咋办?当然是要转义了,Markdown对括号的转义方式有两种:配对计数和斜杠转义,其中配对计数需要一个变量来存储左括号数量挺麻烦,而且斜杠转义完全能用于所有场景,但反过来配对计数却无法用于右括号单独出现的情况(虽然不常见)。

综上所述,我决定不支持计数了,斜杠转义用一个前向环视 (?<!\\) 就能解决,再给指令部分加点限制,最后的正则如下:

  • 指令部分: ([a-z][a-z0-9\-_]*)

  • 标签部分: \[(.*?)(?<!\\)]

  • 链接部分: \((.*?)(?<!\\)\)

把它们三个连起来就可以匹配通用指令语法啦。

Markdown有块 block 和行内 inline 两种结构,原始的图片语法是属于行内的,这可以实现图文混排,但在使用中发现我并没有图文混排的需求,本站文章的图片都是单独一行。所以我决定新的语法作为块结构,这样可以降低解析函数被调用的频率,提升点性能。

最后要注意一下的是反转义和XSS检查,这些函数在markdown-it库里已有提供。

解析器代码见 kaciras-blog/web-server/packages/server/lib/markdown-media.ts

不同的渲染目标

Markdown渲染出来的HTML是跟场景相关的,比如在RSS里渲染的结果应尽量简单,毕竟阅读器的样式是没法由我来控制的;而在我的博客网站里,会有一些额外的样式和元素来展现更好的效果,比如 提前固定宽高比防止布局移动 、居中等。

在本站,GIF视频通过隐藏控制面板、静音、给下面加标签、以及IntersectionObserver实现的自动播放/暂停,实现了跟GIF图片一样的效果。另外由于RSS阅读器不会加载本站的样式表,也不会运行JS,所以RSS阅读器里的GIF视频只能跟普通视频一样。

除了这俩之外,我还准备让评论系统也使用Markdown(暂未实现),这又是一个新的渲染目标,用户评论属于第三方输入,对其的渲染必须加入一些限制以防滥用。

对无法控制的前端,渲染实现跟解析器写在一起,见上面的链接。

本站的渲染实现见 kaciras-blog/website/blob/master/src/markdown/media.js

最终效果

这是GIF视频哦

下面是普通的视频:

结果我还是很满意的,完全实现了我的想法,丰富的多媒体支让我写文更加得心应手!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Linux Device Drivers

Linux Device Drivers

Jonathan Corbet、Alessandro Rubini、Greg Kroah-Hartman / O'Reilly Media / 2005-2-17 / USD 39.95

Device drivers literally drive everything you're interested in--disks, monitors, keyboards, modems--everything outside the computer chip and memory. And writing device drivers is one of the few areas ......一起来看看 《Linux Device Drivers》 这本书的介绍吧!

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具