从零开始建立个人博客V:插入音视频

音视频元素

HTML5提供了插入音乐及视频的元素:<video>,<audio>,使用非常简单,可以设置高度宽度等属性。

1
2
3
4
5
6
7
<video src="video.mp4" controls="controls"></video>

<audio src="music.mp3" controls="controls"></audio>

<audio autoplay controls style="display:block;margin:auto; text-align: center">
<source src="music.mp3" type="audio/mpeg">
</audio>

对于video标签,为使插入的视频宽度自适应屏幕需要一些额外设置,具体介绍可参考下面关于iframe的更新内容

1
2
3
4
<div style="position:relative;height:0;padding-bottom:56.25%">
<video style="position:absolute;left:0;top:0;width:100%;height:100%"
src="video.mp4" controls="controls"> </video>
</div>

音视频标签的使用相对简单,但显示效果通常不怎么美观,为实现更美观的效果可以选择使用Hexo标签插件。

Hexo标签插件

通过安装额外插件,可以扩展Hexo对多媒体的支持。HTML5的音频播放器有APlayer、cPlayer,视频播放器可以使用DPlayer。
首先安装插件

1
2
npm install hexo-tag-aplayer --save
npm install hexo-tag-dplayer --save

之后便可以使用插件对应的标签插入音视频了

1
2
{% aplayer title author url [img_url, narrow, autoplay, width:xxx, lrc:xxx] %}
{% dplayer "url=~url_to_video~" "pic=~url_to_image~" "theme=#FADFA3" % }

注意:aplayer与PJAX不兼容,开启PJAX后,包含aplayer的页面通过索引点击打开,播放器不显示,需要刷新页面(或直接输网址)才正常;而音乐开始播放后切换页面,音乐播放不会停止,但又没有可以控制停止的地方,同样需要刷新页面才正常。

内联框架iframe

由于版权问题,网上音视频资源基本都无法获取源文件地址,上述标签插件使用起来还是会比较麻烦,更常见的做法是使用内联框架<iframe>嵌入外部资源。
iframe使用也非常简单,最重要的是src属性,用于指向资源,除此之外还可调整宽度高度边框等属性。多媒体网站一般都会提供iframe代码,直接将相应代码插入md文件中即可,一般无需额外设置。

1
2
<iframe src="url_to_resource" [width="610px" height="343px"
frameborder="0" scrolling="no"...] ></iframe>

此外还可以使用Hexo内置的iframe标签插件

1
{% iframe url [width] [height] %}

一个烦心的事是,iframe在Firefox中显示总是有问题,在其他浏览器上就没有问题,比如Chrome或这手机浏览器。在Firefox Nightly也没问题,但即使Firefox更新到Nightly对应的版本后,还是不能正常显示,暂时没搞明白原因。


2018年07月13日更新(关于HTML/CSS知识参考VI.网页排版):

iframe有一个非常蛋疼的问题(主要是视频,音频问题不大):

  • 若不指定宽度、高度,默认的视频框是非常小的300px x 150px,只适合手机查看;
  • 而指定高度、宽度后,不会自适应缩放,尤其是手机上不能自适应缩小,观感很差;
  • 宽度可通过width="100%"来自适应屏幕宽度;但高度100%没用,自动的话又会是默认的150px,而不是保持视频长宽比进行缩放。
  • 上面提到的Hexo内置的iframe标签插件也存在该问题

这个问题似乎很普遍,网上有不少讨论。常见的做法就是将iframe放入一个容器中,并在容器的参数中设定一个高宽比(padding-bottom),从而实现视频高度随宽度按比例缩放。最后还要在容器外再加一层段落元素<p>...</p>来换行(对于Markdown,块级元素只需与正文以空行相隔,会自动添加换行)。具体可参考Responsive IFrames — The Right Way (CSS Only)!
这种做法缺点很明显:你需要在插入iframe代码的地方逐个手动添加容器代码;而且对于不同长宽比的视频还需要定义多个容器来设置不同比例,比如常见的16:9的视频就是56.25%(9/16),而4:3的视频则是75%(3/4)。不过对于插入视频不多的,这些缺点其实还好。

还有一种比较理想的做法,是使用jQuery(JavaScript),具体可参考Fluid Width VideoMake YouTube Videos Auto-Resize in a Responsive Site Layout.
这种做法的缺点就是你至少需要了解一点JavaScript;你也可以引入外部jQuery,但考虑到国内的网络环境还是蛋疼。

定义CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style type="text/css">
.videoWrapper{
position: relative;
overflow: hidden;
height: 0;
}

.ratio-16-9 {
padding-bottom: 56.25%; /* 16:9 */
}

.ratio-4-3 {
padding-bottom: 75%; /* 4:3 */
}

.videoWrapper iframe{
position: absolute;
width: 100% !important;
height: 100%;
left: 0;
top: 0;
}
</style>

插入视频

1
2
3
<p><div class="videoWrapper ratio-16-9">
<iframe .... ></iframe>
</div></p>

还可以将两者直接写在一起

1
2
3
<p><div style="position:relative;height:0;padding-bottom:56.25%">
<iframe style="position:absolute;left:0;top:0;width:100%;height:100%"...></iframe>
</div></p>

16:9

4:3


2019年09月01日更新
最新的NexT主题,解决了Bilibili视频尺寸自适应变化的问题,无需上述自定义样式。但需要注意NexT的会强制视频内容的宽度与页面宽度一致,从而与自定义样式不完全兼容:对于Bilibili的视频,由于播放器边框的存在,16:9的视频设置宽高比16:9后实际视频左右会存在黑边;新版NexT在此时会完全无视宽高比,强制视频宽度与页面宽度一致,高度也相应变化,而文字的位置却依然服从设置的宽高比,最终造成文字被视频窗口覆盖。解决办法是清除自定义样式,或者对于16:9的视频宽高比也设置为4:3。对于TED视频却依然不会自适应调整,不过好在TDE视频的iframe代码是自带上述样式的,所以没有问题。