静看光阴荏苒
不管不顾不问不说也不念

开源一个弹幕视频播放站点,支持BT / URL导入视频

MoeVideo是一个开源弹幕视频播放站点,支持通过BT / yt-dlp + curl-cffi / rebrowser-playwright + chromium导入视频。最近一直在vibe coding这个程序,感觉功能都完善的差不多了,能够满足自己的需求了,索性开源出来分享给大伙一起用,反馈bug或者提需求都可以开issue,如果喜欢的话可以点个小星星支持一下。

技术栈:

  • 前端:Next.js App Router + Tailwind CSS
  • 后端:Go + Fiber

当前已实现的功能:

  • 视频上传
  • BT导入视频:支持自动解析种子文件内的媒体文件。
  • URL导入视频:yt-dlp + curl-cffi
  • 自定义yt-dlp cookies(cookies采用加密存储并支持配置多个站点)
  • 回落支持:yt-dlp不支持的站点自动回落到rebrowser-playwright + chromium
  • 强制回落:通过环境变量配置指定域名直接走rebrowser-playwright + chromium
  • HLS多码率转码:360p 480p 720p 1080p
  • 用户中心:可设置头像,签名,个人信息隐私策略等
  • 多用户支持:可选开启或关闭注册
  • 互动系统:点赞 评论 收藏 粉丝关注
  • 视频弹幕支持 (WebSocket)
  • 站内搜索:搜索您想看的视频
  • 标签页面:支持添加视频标签,按标签排列视频,单独的标签页面
  • 排行榜系统:独立的热度算法支持,智能排序热度最高的视频
  • ArtPlayer 雪碧图 + VTT
  • 跨设备同步播放记录,记忆上次播放位置。
  • 完善的管理面板:站点设置 用户管理 视频管理 转码任务管理 分类设置 yt-dlp设置 等
  • 本地存储 / S3存储支持

文档还没有全部写好,还有一些细节也没有到位,这篇文章先记录一下Docker的部署步骤。

安装Docker / NGINX / Certbot:

apt -y update
apt -y install curl git nginx python3-certbot-nginx
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

克隆项目存储库并准备数据目录:

git clone https://github.com/xiya233/MoeVideo.git
cd MoeVideo
mkdir -p data/db data/storage data/temp data/redis

编辑.env.docker:

nano .env.docker

假设您使用的域名是:app.example.com (前端)/ api.example.com (后端)至少需要修改下面的内容:

# 前端连接后端的API地址
NEXT_PUBLIC_API_BASE_URL=https://api.example.com/api/v1
# 与NEXT_PUBLIC_API_BASE_URL保持一致
API_BASE_URL=https://api.example.com/api/v1
# 建议至少 32 位高强度随机字符串
JWT_SECRET=replace-this-with-a-very-strong-secret
# 后端API地址
PUBLIC_BASE_URL=https://api.example.com
# HTTPS必须启用
AUTH_COOKIE_SECURE=true
# 留空
AUTH_COOKIE_DOMAIN=
# SameSite建议lax, 兼顾安全和常规站内跳转
AUTH_COOKIE_SAMESITE=lax
AUTH_COOKIE_PATH=/
# 设置前端域名
CORS_ALLOWED_ORIGINS=https://app.example.com
# 改大一点防止因下载速度慢导致超时重试
IMPORT_URL_TIMEOUT_SEC=18000
# 改大一点防止因网速慢导致页面解析超时
IMPORT_PAGE_RESOLVER_TIMEOUT_SEC=90
# 强制走 fallback 的域名列表, 逗号分隔,如不需要可留空
IMPORT_FORCE_FALLBACK_DOMAINS=missav.ai,24av.net

使用GHCR预构建镜像启动:

docker compose --env-file .env.docker -f docker-compose.yml -f docker-compose.ghcr.yml pull
docker compose --env-file .env.docker -f docker-compose.yml -f docker-compose.ghcr.yml up -d --no-build

创建管理员账号:

docker compose --env-file .env.docker run --rm backend \
  /app/moevideo-admin bootstrap \
  --email admin@example.com \
  --username admin \
  --password 'ChangeMe-StrongPassw0rd!' \
  --db /data/db/moevideo.db

新建NGINX站点配置文件:

nano /etc/nginx/sites-available/moevideo.conf

写入如下内容:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

upstream moevideo_frontend {
    server 127.0.0.1:3000;
}

upstream moevideo_backend {
    server 127.0.0.1:8080;
}

server {
    listen 80;
    listen [::]:80;
    server_name app.example.com;
    client_max_body_size 2048m;

    location / {
        proxy_pass http://moevideo_frontend;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}

server {
    listen 80;
    listen [::]:80;
    server_name api.example.com;
    client_max_body_size 2048m;

    location /api/ {
        proxy_pass http://moevideo_backend;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    location /media/ {
        proxy_pass http://moevideo_backend;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /healthz {
        proxy_pass http://moevideo_backend/healthz;
    }
}

启用站点:

ln -s /etc/nginx/sites-available/moevideo.conf /etc/nginx/sites-enabled/moevideo.conf

申请证书:

certbot --nginx -d app.example.com -d api.example.com

登录后访问/admin即可打开管理员面板,建议修改一下yt-dlp的配置,提升下载速度:

--concurrent-fragments 8 --fragment-retries 10 --retries 10 --socket-timeout 30 --force-ipv4 --impersonate Chrome-136

如图所示:

项目截图:

目前s3存储还没有测试,不知道有没有什么bug,建议直接用本地存储。

然后是回落抓取网页媒体链接的功能,逻辑是这样的:yt-dlp支持的站点直接走yt-dlp下载,yt-dlp如提示不支持的url(unsupported url),则走rebrowser-playwright + chromium探测页面的媒体链接,用户手动选择抓取出来的链接再喂给yt-dlp下载。但是目前只对yt-dlp不支持的url(unsupported url)这一退出行为执行回落操作,其他报错退出不做回落操作,比如被cf拦截了,或者页面报403,等等这些都是不会自动回落的。

所以这里有个问题就是要让yt-dlp识别目标网站支不支持得先能够让它成功访问到目标页面,如果本身就被cf拦截或者其他莫名其妙的原因导致无法访问目标页面,yt-dlp退出的行为可能有很多种,只要不是不支持的url(unsupported url)退出的就不会回落,所以我增加了一个功能就是强制(指定)回落:用户可以设置指定域名直接走rebrowser-playwright + chromium。这个功能我测试了下载missav,24av等x站都是没问题的,或者说我就是专门为了下这几个站的视频特地做的= =

赞(0)
未经允许不得转载:荒岛 » 开源一个弹幕视频播放站点,支持BT / URL导入视频
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

分享创造快乐

广告合作资源投稿