Sign inSign up

luohaonan/recovery-gallery

By luohaonan

•Updated 1 day ago

自托管本地视频画廊:挂载目录即用,支持子目录、自动封面|amd64/arm64

Image
0

332

luohaonan/recovery-gallery repository overview

⁠本地视频画廊

一个零第三方依赖(只用 Python 标准库)的自托管视频画廊。把装着视频的文件夹挂载进容器, 就能在局域网里用浏览器浏览、播放自己的视频库。

  • 🎞️ 瀑布流 + 懒加载:几千个视频也能秒开,快速滚动不卡
  • 🖼️ 缩略图自动生成:镜像自带 ffmpeg,缺封面就自动抽帧,后台把整个库补齐
  • 📁 支持子目录:挂载目录下的子目录会一起扫描,网页顶部可按目录筛选
  • ▶️ 点击弹窗播放:竖屏视频完整显示不裁切,支持 Esc / ← → / 空格
  • ♥ 收藏:卡片和播放弹窗里都能收藏,有独立的「只看收藏」入口
  • 🔀 排序:按名称 / 时间 / 大小,共 7 种方式,入口在左上角
  • 🗑️ 删除(可选,需输入当天日期二次确认)
  • ⏻ 网页关机(可选,见下文说明)
  • 🌡️ 右上角可选显示 CPU 功耗(Intel RAPL)

支持 linux/amd64 与 linux/arm64。


⁠快速开始

镜像里只有程序本身;你只需要把视频目录挂进去,封面会自动生成,收藏也留在挂载目录里。

docker run -d --name video-gallery \
  --restart unless-stopped \
  -p 8080:8080 \
  -e TZ=Asia/Shanghai \
  -v /srv/videos:/data/recovery/mp4 \
  -v /srv/video-thumbs:/var/cache/recovery-gallery/thumbs \
  -v ./state:/var/lib/recovery-gallery \
  luohaonan/recovery-gallery:latest

然后打开 http://<宿主机IP>:8080。

注意:容器内固定从 /data/recovery/mp4 读视频、往 /var/cache/recovery-gallery/thumbs 写封面,所以左边宿主机路径随你改, 右边容器路径要照抄。视频目录不存在时容器会直接启动失败(有意的,避免起来后是一片空白)。


⁠docker-compose.yaml(推荐)

services:
  gallery:
    image: luohaonan/recovery-gallery:latest
    container_name: video-gallery
    restart: unless-stopped

    ports:
      # 左边宿主机端口可改;右边要与容器内 --port 一致
      - "8080:8080"

    environment:
      # 删除/关机要输入「当天日期」二次确认,时区必须设对
      TZ: Asia/Shanghai

    volumes:
      # 视频目录(必须)。左边换成你自己的视频文件夹;
      # 需要网页「删除」功能就要可写,纯只读播放库可加 :ro
      - /srv/videos:/data/recovery/mp4
      # 封面缓存(强烈建议):不挂则容器重建后要重新抽帧生成
      - /srv/video-thumbs:/var/cache/recovery-gallery/thumbs
      # 收藏名单 likes.json(强烈建议):不挂则删容器后收藏丢失
      - ./state:/var/lib/recovery-gallery
      # 时区文件(可选)
      - /etc/localtime:/etc/localtime:ro
      # CPU 功耗显示(可选):右上角功耗来自 Intel RAPL,虚拟机可能没有
      # - /sys/devices/virtual/powercap:/sys/devices/virtual/powercap:ro
      # 网页关机(可选):见「网页关机」一节
      # - /run/video-gallery:/run/video-gallery
docker compose up -d

⁠挂载点

宿主机路径容器内路径说明
你的视频目录/data/recovery/mp4必须。网页只读取这里的 .mp4
缩略图目录/var/cache/recovery-gallery/thumbs自动生成的封面缓存(文件名 <视频名>.mp4.jpg),强烈建议挂出来
收藏状态目录/var/lib/recovery-gallery收藏名单 likes.json 所在目录
/etc/localtime同左(:ro)时区,配合 TZ 使用
/sys/devices/virtual/powercap同左(:ro)可选,CPU 功耗显示
/run/video-gallery同左可选,仅「网页关机」方案用
⁠目录(子目录)

挂载进去的目录会递归扫描,子目录里的视频一样能看到:

  • 顶部工具栏的「目录」下拉框列出所有含视频的目录,括号里是数量(子目录带缩进)
  • 选中某个目录后,列表只显示它和它的子目录里的视频
  • 卡片右下角的 📁 目录名 胶囊点一下就能只看那个目录
  • 选择会记在浏览器里,刷新后还在

只列出含视频的目录:某个子目录里全是文档/图片的话,它不会出现在下拉框里。 以 . 开头的目录(.git、.DS_Store 之类)和符号链接指向目录外的文件不会被扫描,也不能通过 URL 访问。

镜像里带了 ffmpeg,不需要你预先准备封面图:

  • 浏览器请求某张封面时,如果还没有,服务会当场抽一帧生成再返回(首次会慢一点点)
  • 同时有个后台线程,会把整个视频库缺的封面慢慢补齐(一次一个,不抢满 CPU)
  • 默认取第 1 秒的画面,输出宽 640、等比缩放

想调整或关掉:

    command:
      - python3
      - app.py
      - --host
      - 0.0.0.0
      - --port
      - "8080"
      - --likes-file
      - /var/lib/recovery-gallery/likes.json
      # 从第 5 秒抽帧、宽 960、只看前台请求不跑后台补齐
      - --thumb-seek
      - "5"
      - --thumb-width
      - "960"
      - --no-thumb-prewarm
      # 完全不要缩略图功能:
      # - --no-thumbnails

生成结果缓存在 /var/cache/recovery-gallery/thumbs,建议挂出来, 容器重建后不用重新抽帧。源码损坏、抽不出帧的视频会跳过(日志里会写明原因), 页面会退回显示动态预览。


⁠端口与环境变量

名称默认说明
容器端口8080用 --port 可改,改了记得同步 compose 的端口映射
TZAsia/Shanghai影响「删除 / 关机」的日期确认

⁠网页关机(可选)

容器默认没有权限关掉宿主机,点「关机」会返回 500 —— 这是预期行为,不是 bug。

想让它真的生效,用「共享文件 + 宿主机 systemd path 单元」:

宿主机上:

mkdir -p /run/video-gallery

cat > /etc/systemd/system/video-gallery-poweroff.path <<'EOF'
[Unit]
Description=Watch video-gallery poweroff request

[Path]
PathExists=/run/video-gallery/poweroff.request

[Install]
WantedBy=paths.target
EOF

cat > /etc/systemd/system/video-gallery-poweroff.service <<'EOF'
[Unit]
Description=Poweroff requested from video-gallery

[Service]
Type=oneshot
ExecStart=/bin/rm -f /run/video-gallery/poweroff.request
ExecStart=/sbin/shutdown -h now
EOF

systemctl enable --now video-gallery-poweroff.path

compose 里放开 /run/video-gallery 挂载,并覆盖启动命令:

    volumes:
      - /run/video-gallery:/run/video-gallery
    command:
      - python3
      - app.py
      - --host
      - 0.0.0.0
      - --port
      - "8080"
      - --likes-file
      - /var/lib/recovery-gallery/likes.json
      - --poweroff-command
      - touch /run/video-gallery/poweroff.request

⁠启动参数

参数默认说明
--host0.0.0.0监听地址
--port8080监听端口
--likes-file/var/lib/recovery-gallery/likes.json收藏名单路径
--video-root/data/recovery/mp4视频目录(容器里一般不用改)
--thumb-root/var/cache/recovery-gallery/thumbs缩略图缓存目录
--thumbnails / --no-thumbnails开缺封面时是否用 ffmpeg 自动抽帧
--thumb-prewarm / --no-thumb-prewarm开是否后台把整个库补齐
--thumb-width640缩略图宽度,高度等比
--thumb-seek1.0从第几秒抽帧
--thumb-prewarm-delay15启动后多久开始后台补齐(秒)
--ffmpeg自动查找指定 ffmpeg 可执行文件
--poweroff-command/sbin/shutdown -h now网页「关机」执行的命令

⁠标签与架构

标签说明
latest最新构建,多架构(amd64 + arm64)
2026-10-07固定日期版本,多架构
amd64 / arm64单架构镜像
docker pull luohaonan/recovery-gallery:latest

⁠自己构建

cd <源码目录>
docker build -t luohaonan/recovery-gallery:latest .

基础镜像默认 python:3.13-slim,拉取慢时可以换国内源:

docker build \
  --build-arg BASE_IMAGE=docker.1ms.run/library/python:3.13-slim \
  -t luohaonan/recovery-gallery:latest .

⁠常见问题

启动就退出,日志说 video directory does not exist 视频目录没挂到 /data/recovery/mp4(这个容器路径是固定的,不能改)。

端口 8080 被占用 改 compose 左边的宿主机端口,或先停掉占用 8080 的进程。

收藏重启后就没了 /var/lib/recovery-gallery 没挂出来,likes.json 落在容器可写层里了。

右上角功耗一直显示 -- 没读到 Intel RAPL。虚拟机 / 部分新平台没有该传感器,属正常。

点了关机没反应 / 报 500 见上文「网页关机(可选)」,容器默认没权限关宿主机。

子目录里的视频看不到 确认文件扩展名是 .mp4(大小写都行),且路径中没有以 . 开头的目录。

封面图要等一会儿才出来 第一次访问某个视频时才会抽帧;后台补齐线程也会慢慢把整库补上。 库很大时可以先让它跑一阵,或把缩略图目录挂出来复用。

有些视频一直没有封面图 多半是文件本身损坏(日志里会打印 thumbnail: 生成失败 <名字>: ...,比如 moov atom not found)。 这类文件会跳过,页面显示动态预览。

Tag summary

Content type

Image

Digest

sha256:c44e8134f…

Size

95.2 MB

Last updated

1 day ago

docker pull luohaonan/recovery-gallery