视频嵌入指南


难度 中等

matery 主题自带的视频能力盘点 + 4 种主流嵌入方式的一步步操作。所有改动都在仓库里 git commit + push 后,CI 自动构建并部署到 growdu.cn

文档约定

  • 所有示例路径相对仓库根目录(如 _config.matery.yml
  • 改完任何配置后,npx hexo generate 本地预览、git push 触发 CI 部署
  • <!-- more --> 是 hexo 的摘要分割符,可选

4 种嵌入方式一览

方式 适合场景 渲染位置 播放器
A. 首页视频 widget 想让首页有一个”精彩视频”section 首页 widgets 区 DPlayer / B 站 iframe
B. 首页背景视频 想用视频做首页 banner 背景 首页 bg-cover 区域 <video> 全屏
C. 文章内嵌视频 在某篇具体文章里插一个或多个视频 任意文章正文 B 站 iframe / <video>
D. 视频合集页 想做 /movies/ 视频列表 单独路由 自由组合

下面 A → D 一一拆解。


方式 A:首页视频 widget

这一节会改两个文件:_config.matery.yml(启用 + 配置视频源),themes/matery/layout/index.ejs(确认 widget 引入位置)。

步骤 1:打开 _config.matery.yml,启用 video 块

定位到第 93 行附近的 video:,改成下面这样(以 B 站视频为例):

# Disable other homepage widgets
music:
  enable: false
video:
  enable: true
  showTitle: true
  title: 精彩视频
  # 1) 走 iframe 模式(推荐给 B 站 / 爱奇艺 / YouTube embed)
  iframeUrl: //player.bilibili.com/player.html?aid=YOUR_AID&bvid=YOUR_BVID&cid=YOUR_CID&page=1
  height: 480
  # 2) 走 DPlayer 模式(推荐给自托管 .mp4)
  url:           # 留空表示用 iframe 模式
  pic:           # 封面图(仅 DPlayer 模式生效)
  thumbnails:    # 缩略图(仅 DPlayer 模式生效)
  autoplay: false
  loop: false
  theme: '#42b983'

关键开关:

  • enable: true —— 不开等于没装
  • iframeUrl 优先于 urliframeUrl 非空就用 iframe,留空才走 DPlayer
  • height 是像素高度,不写就让 iframe 自适应

步骤 2:拿到 B 站视频的 iframe URL

  1. 打开 B 站视频页(如 https://www.bilibili.com/video/BV1xxxxxxxx
  2. 点视频下方 分享 → 嵌入代码(不是”复制视频链接”)
  3. 复制 src="..." 双引号里的 URL,形如 //player.bilibili.com/player.html?aid=...&bvid=...&cid=...&page=1
  4. 粘到上面的 iframeUrl:

如果只有 B 站视频链接没有嵌入 URL,也可以手工拼://player.bilibili.com/player.html?bvid=YOUR_BV_ID&page=1(去掉 aidcid 也能播)。

步骤 3:把 video widget 注入首页

关键:matery 默认的 themes/matery/layout/index.ejs 不引用 _widget/video,仅渲染 banner。即使 _config.matery.ymlvideo.enable: true,首页上也不会有任何 video widget 出现。必须手动加一行。

打开 themes/matery/layout/index.ejs,文件当前内容大致是:

<% if (is_home() && page.current === 1) { %>
<%- partial('_partial/index-cover') %>
<% } else { %>
    <%- partial('_partial/bg-cover') %>
<% } %>
<%- partial('_partial/bg-video') %>

在文件末尾追加:

<%- partial('_widget/video') %>

想把 widget 放在 banner 下方、其它内容之上,就在 bg-video 那一行之后追加;想放到页面最底部,就直接放文件最末。

步骤 4:本地预览

npx hexo clean && npx hexo generate && npx hexo server

打开 http://localhost:4000/,首页往下滚应该能看到标题”精彩视频”和 B 站播放器。

步骤 5:提交并推送

git add _config.matery.yml themes/matery/layout/index.ejs
git commit -m "feat(home): add featured video widget (bilibili BVxxxxx)"
git push origin master

CI 跑完(约 2-3 分钟)后,线上 growdu.cn 首页生效。

自托管 mp4 用 DPlayer 的等价配置

如果视频是你自己的 .mp4(比如录屏),把 .mp4 放到 themes/matery/source/videos/xxx.mp4(或任意 hexo 会发布的目录),然后:

video:
  enable: true
  showTitle: true
  title: 录屏演示
  url: /videos/xxx.mp4
  pic: /videos/xxx.jpg          # 封面图(可选)
  autoplay: false
  loop: false
  theme: '#42b983'
  height: 480

DPlayer 的额外能力(弹幕 / 速度 / 字幕)由 themes/matery/layout/_widget/video.ejs 里的 new DPlayer({...}) 配置;按需改那段 JS 即可。


方式 B:首页背景视频

把首页 banner 图替换成自动循环静音的视频。注意:背景视频在移动端(<760px)会自动隐藏,仍显示 banner 图。

步骤 1:把视频放到可访问路径

把视频文件放到 themes/matery/source/videos/cover.mp4(以及同名的 .webm 备用)。

体积建议 < 5MB,时长 10-30 秒,分辨率 1920×1080 或更低。
浏览器 autoplay 要求视频必须静音bg-video.ejs 已经写好 muted)。

步骤 2:打开 _config.matery.yml,加 cover.video

# 在文件合适位置(通常在 # Cover / banner 配置附近)追加:
cover:
  video:
    enable: true
    src:
      - /videos/cover.mp4
      - /videos/cover.webm    # 浏览器格式回退,可选

步骤 3:确认 bg-video 已被 layout 引用

打开 themes/matery/layout/index.ejs,文件最后一行应该是:

<%- partial('_partial/bg-video') %>

仓库当前已经引用;如果没有,把它加到 index.ejs 文件末尾即可(bg-video.ejs 内部根据 theme.cover.video.enable 自行判断是否输出 <video>,所以无论开不开启背景视频,这行 partial 都可以常驻)。

步骤 4:可选 —— 关闭 banner 轮播图

cover.video.enable: true 时,背景图(/medias/banner/*.jpg)就被视频覆盖。无需手动关,但如果你想彻底停掉 banner 轮播,可以把 _config.matery.ymlbanner.enable: false

步骤 5:本地预览 + 提交

npx hexo clean && npx hexo generate && npx hexo server

打开首页,PC 端应该看到循环播放的全屏视频;手机端仍显示原 banner 图。

git add _config.matery.yml themes/matery/source/videos/
git commit -m "feat(home): autoplay background video on cover"
git push origin master

方式 C:文章内嵌视频

最灵活 —— 任何一篇 markdown 文章里都能插视频。两种写法:B 站/爱奇艺 iframe,或自托管 <video>

C-1:B 站/爱奇艺 iframe 嵌入

在文章的 markdown 正文里直接写:

## 演示视频

<iframe src="//player.bilibili.com/player.html?bvid=BV1xxxxxxxx&page=1"
        scrolling="no" border="0" frameborder="no" framespacing="0"
        allowfullscreen="true"
        width="100%" height="480"></iframe>

要点:

  • width="100%" 让它自适应容器宽度
  • height 按视频比例 16:9 算,如 480 / 540 / 600
  • B 站 URL 的 bvid= 是必须的(aid / cid 可选)

爱奇艺同源:分享视频时点”通用代码”,把 <iframe> 整段粘进来即可。

C-2:自托管 mp4 嵌入

.mp4 放到 themes/matery/source/videos/xxx.mp4,然后在文章里写:

## 录屏演示

<video src="/videos/xxx.mp4" controls width="100%"></video>

可选属性:

  • controls —— 显示播放控件(必加)
  • autoplay muted playsinline —— 静音自动播放(移动端友好)
  • loop —— 循环
  • preload="metadata" —— 只预载元数据,省流量
  • poster="/videos/xxx.jpg" —— 视频封面

C-3:放进页面捆绑目录(推荐)

如果视频只属于某一篇文章,把 .mp4 放在文章同目录下,引用更直观。

例如 docs/pgsql/some-post/index.md + docs/pgsql/some-post/demo.mp4

docs/pgsql/some-post/
├── index.md      # 文章正文
└── demo.mp4      # 视频文件

文章里写:

<video src="./demo.mp4" controls width="100%"></video>

sync-hexo.py 会把整个目录复制到 source/_posts/pgsql/some-post/,hexo 发布时把 demo.mp4 复制到 public/pgsql/some-post/demo.mp4(同目录相对路径依然有效)。

提交

git add docs/pgsql/some-post/
git commit -m "feat(post): embed demo video"
git push origin master

方式 D:视频合集页(/movies/ 路由)

做一个独立的视频列表页,hexo 提供现成的 layout: movies 模板。

步骤 1:创建 docs/movies/index.md

mkdir -p docs/movies

docs/movies/index.md 内容:

---
title: 视频合集
date: 2026-08-11 12:00:00
layout: movies
---

这里收录我的技术分享视频。

layout: movies 这一行是关键 —— 它让 hexo 渲染走 themes/matery/layout/movies.ejs 模板(不是默认的 post.ejs)。

步骤 2:编辑 themes/matery/layout/movies.ejs

打开 themes/matery/layout/movies.ejs,在合适位置(一般在 <%- partial('_partial/bg-cover') %> 之后)写自己的视频列表:

<%- partial('_partial/bg-cover') %>

<div class="movies-list container">
  <h2>PostgreSQL 系列</h2>

  <div class="movie-item">
    <h3>1. 逻辑解码入门</h3>
    <iframe src="//player.bilibili.com/player.html?bvid=BV1xxxxA&page=1"
            scrolling="no" border="0" frameborder="no" framespacing="0"
            allowfullscreen="true" width="100%" height="480"></iframe>
  </div>

  <div class="movie-item">
    <h3>2. openGauss DCF 源码解读</h3>
    <iframe src="//player.bilibili.com/player.html?bvid=BV1xxxxB&page=1"
            scrolling="no" border="0" frameborder="no" framespacing="0"
            allowfullscreen="true" width="100%" height="480"></iframe>
  </div>
</div>

<style>
.movie-item { margin: 32px 0; }
.movie-item h3 { font-size: 1.2rem; margin-bottom: 12px; }
</style>

这是纯 HTML —— 你想用什么播放器(B 站 / 自托管 <video> / 第三方)都自由。

步骤 3:顶部导航加一个入口(可选)

_config.matery.ymlmenu: 段追加:

menu:
  视频:
    url: /movies/
    icon: fas fa-video

步骤 4:提交

git add docs/movies/ themes/matery/layout/movies.ejs _config.matery.yml
git commit -m "feat: add /movies/ video collection page"
git push origin master

常见问题

Q:iframe 嵌入 B 站视频,PC 端能播但手机端黑屏?

B 站 iframe 默认有 2 分钟试看限制。给 URL 加参数绕过:

?t=0+0&autoplay=0

完整示例:

<iframe src="//player.bilibili.com/player.html?bvid=BV1xxxxxxxx&page=1&autoplay=0&t=0"
        ...></iframe>

Q:mp4 太大,git push 慢?

.mp4 放在仓库外的服务器,文章里用外链:

<video src="https://growdu.cn/videos/xxx.mp4" controls width="100%"></video>

需要把 videos/ 目录放在 nginx 站点下,绕过 hexo 构建。

Q:DPlayer 报错 “Cannot read property ‘url’ of undefined”?

url: 留空时不要走 DPlayer 模式,iframeUrl 配 URL;或者反过来,url 配路径。两者不能同时留空。

Q:背景视频在手机端不显示?

bg-video.ejs 里有 @media (max-width: 760px) { #index-video { display: none; } },这是设计行为(移动端节省流量)。想强制显示就把这条 media query 删了。

Q:视频播放页 SEO 怎么办?

每篇带视频的文章在 front matter 加:

---
title: 演示视频
description: 视频简介
keywords: 视频,演示
---

搜索引擎会爬标题/描述;视频本身的 SEO 由 B 站原页面贡献。


速查:哪个文件改什么

想做的事 改的文件
首页 widget 显示 B 站视频 _config.matery.ymlvideo.iframeUrl
首页 widget 显示自托管 mp4 themes/matery/source/videos/xxx.mp4 + _config.matery.ymlvideo.url
首页背景视频 themes/matery/source/videos/cover.{mp4,webm} + _config.matery.ymlcover.video
文章里嵌一个视频 文章 .md<iframe><video> 标签
单独 /movies/ 视频页 docs/movies/index.mdlayout: movies)+ 编辑 themes/matery/layout/movies.ejs
导航加视频入口 _config.matery.ymlmenu:

文章作者: growdu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 growdu !
  目录
分类导航
随笔2 AI27 算法1 计算机基础13 博客搭建7 ChatGPT2 集群63 计算机通信1 数据库34 数据库深入80 DPDK26 Docker11 Elasticsearch4 编辑工具4 FAQ1 Go Web1 hometown2 编程语言16 网络9 OPC1 Linux38 openGauss4 页面12 PostgreSQL54 程序员自我修养1 协议11 成长之路1 stock1 存储5 工具20 VPP18 视频作品1 Vue13 Web1 代码示例11 数据库15 BenchmarkSQL1 PostgreSQL 源码修炼之路14
最热文章
1
13 逻辑复制深入
数据库深入🔥 1570
2
0 Postgresql存储、索引及系统优化、主备切换
PostgreSQL🔥 1495
3
一文读懂openguass dcf网络模块
集群🔥 1420
4
逻辑复制源码分析
数据库深入🔥 1327
5
PostgreSQL 分区表:从一行 `PARTITION BY` 到路由热路径的全链路拆解
数据库🔥 1094
6
applyparallelworker.c 之 LA 端源码深度解析:Leader Apply Worker 的指挥中枢
数据库深入🔥 1082
7
PostgreSQL Background Worker 全解:从 `RegisterBackgroundWorker` 到逻辑复制 4 类 worker 的全生命周期
数据库🔥 1078
8
PostgreSQL的后台进程walsender分析 - 关系型数据库 - 亿速云
PostgreSQL🔥 1033
9
PostgreSQL 逻辑复制的监控:六张视图 + 一组可执行 SQL,把 publisher/subscriber 的速率与健康度彻底看透
数据库🔥 1032
10
PostgreSQL 逻辑复制支持 DDL 之后:DDL 与 DML 的时序难题(重点:分区表)
数据库🔥 999
11
reorderbuffer.c 源码深度解析:PostgreSQL 逻辑复制的"事务重组引擎
数据库深入🔥 953
12
PostgreSQL 内核开发:读取一张表的 9 步标准流程与缓存全景
数据库🔥 938
13
从 `postgres` 二进制到生产级守护 —— PostgreSQL 最外层模块与启动全流程拆解
数据库🔥 936
14
支持逻辑复制同步 DDL 适配 SQL Server 方案
数据库深入🔥 934
15
PostgreSQL 逻辑复制的 ReorderBuffer 与事务机制:从一行 WAL 到一致性变更流的全链路绑定
数据库🔥 913
16
DDL同步架构(美化版)
数据库深入🔥 908
17
PostgreSQL Latch 机制详解:从一行 SetLatch 到 epoll 的内核之旅
数据库🔥 871
18
pgbench 源码全解:一个 C 文件如何撑起 PostgreSQL 官方压测工具
数据库🔥 860
19
PostgreSQL libpq 机制与缓冲区详解
数据库🔥 850
20
PostgreSQL 逻辑复制 spill 文件深度剖析:从 `xid-*.spill` 到 TPC-C 的增长方程
数据库🔥 845