给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视频哦

下面是普通的视频:

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


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

查看所有标签

猜你喜欢:

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

操作系统

操作系统

William Stallings / 陈向群、陈渝 / 机械工业出版社 / 2010.9 / 69.00元

本书不仅全面地讲述了操作系统的基本概念、原理和方法,还清楚地展现了当代操作系统的本质和特点。作者针对近几年操作系统领域的最新变化,对操作系统的设计原理进行深入的阐述,同时将其对操作系统整个领域全面而深入的理解呈现给读者。 本书特色 ·选择Windows Vista、UNIX和Linux三个操作系统作为示例,以帮助读者熟悉当代操作系统的设计原理和实现问题。 ·新增嵌入式操作系统一章......一起来看看 《操作系统》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

随机密码生成器
随机密码生成器

多种字符组合密码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具