安装步骤对齐 Owncast 官方的容器镜像文档。稳定版镜像是 Docker Hub 上的 owncast/owncast:latest。插件等 0.3.0 才有的功能在 nightly:ghcr.io/owncast/owncast:nightly。下面用稳定版做推流测试。
FFmpeg 本身的参数说明见 FFmpeg 完全指南。这一篇只把 Owncast 跑通,并给出各分辨率可直接替换文件名的推流命令。
端口和数据
| 端口 | 用途 |
|---|---|
8080/tcp | 观看页和管理后台。http://宿主机:8080 看直播,/admin 进后台 |
1935/tcp | RTMP 收流。推流软件连这个端口 |
数据库、配置和录像都在容器里的 /app/data。把它挂到宿主机,换机器时把这个目录拷走即可。示例里宿主机地址是 192.168.101.57,换成你的 Owncast 机器地址。
用容器跑起来
在准备放数据的目录里执行。先拉镜像,再后台启动,并给容器起名,方便以后看日志和停止。
mkdir -p owncast && cd owncast
docker pull owncast/owncast:latest
docker run -d \
--name owncast \
--restart unless-stopped \
-v "$(pwd)/data:/app/data" \
-p 8080:8080 \
-p 1935:1935 \
owncast/owncast:latest
同一件事也可以写成 Compose,升级时少敲一长串参数:
services:
owncast:
image: owncast/owncast:latest
container_name: owncast
restart: unless-stopped
ports:
- "8080:8080"
- "1935:1935"
volumes:
- ./data:/app/data
docker compose up -d
docker ps --filter name=owncast
docker ps 里状态是 Up,两个端口都映射出来,服务就在听。容器马上退出时,用 docker logs owncast 看原因,常见是 8080 或 1935 已被占用,或 data 目录没有写权限。
从别的机器访问时,宿主机防火墙要放行这两个端口。只在本机测,用 127.0.0.1 即可。
登录后台
浏览器打开 http://192.168.101.57:8080/admin。
| 项目 | 默认值 |
|---|---|
| 管理员用户名 | admin |
| 管理员密码 | abc123 |
| 流密钥 | abc123 |
中文文档的默认凭据表把用户名写成了「管理员」,同一页后文写的登录名是 admin。登录框里填 admin。密码和流密钥出厂都是 abc123,但是两套独立设置:流密钥只给推流软件用,登不进后台。
第一次登录后立刻改掉管理员密码和流密钥。改完密钥,下面命令末尾的 abc123 换成新值。观看页是 http://192.168.101.57:8080。
推流地址
Owncast 的 RTMP 应用名是 live。FFmpeg 把流密钥直接接在路径后面:
rtmp://192.168.101.57:1935/live/abc123
OBS 一类软件如果单独有「串流密钥」输入框,服务器填 rtmp://192.168.101.57:1935/live,密钥填 abc123。没有单独密钥框时,用上面这一整条。
命令里的参数
下面这条是 144p 片源上已经跑通的推流命令。文件按原速读完,视频用 x264 压到 3000k,音频转成 AAC,封装成 FLV 推到 Owncast。
ffmpeg -re -i 大明1566_144p.mp4 \
-c:v libx264 -preset veryfast -b:v 3000k -maxrate 3000k -bufsize 6000k -g 60 \
-c:a aac -b:a 128k -ar 44100 -f flv rtmp://192.168.101.57:1935/live/abc123
| 参数 | 作用 |
|---|---|
-re | 按实时速度读文件。文件推流要加,否则会以解码最快速度把整段推完 |
-c:v libx264 -preset veryfast | 软件编码 H.264,veryfast 优先保证实时,适合边看边推 |
-b:v / -maxrate | 目标码率和峰值码率。直播把两者写成一样,避免突发把缓冲打满 |
-bufsize | 码率控制窗口,这里取 -maxrate 的 2 倍 |
-g 60 | 关键帧间隔。30fps 片源用 60,大约 2 秒一个关键帧,拖动和切片都跟得上。先用 ffprobe 看帧率,25fps 改成 -g 50,60fps 改成 -g 120 |
-c:a aac -b:a 128k -ar 44100 | 音频转 AAC、128kbps、44.1kHz。Owncast 收的是这套 |
-f flv | RTMP 走 FLV 封装 |
3000k 用来打通 144p 这条链路是够的,相对 256×144 的画面偏高,带宽大部分花在了压不满的分辨率上。要按画质分档对比时,用下一节的建议码率:分辨率升高,-b:v 和 -maxrate 一起加大,-bufsize 保持 2 倍。同一台 Owncast 一次收一路,换分辨率前先在推流终端按 Ctrl+C 停掉上一条。
推之前可以看一眼片源的宽高和帧率:
ffprobe -v error -select_streams v:0 \
-show_entries stream=width,height,r_frame_rate,codec_name \
-of default=nw=1 大明1566_144p.mp4
各分辨率命令
文件已经是目标分辨率(文件名带档位)时,不加 scale,只重编码再推。地址、预设、GOP、音频和上面那条相同。多加了 -pix_fmt yuv420p,避免源是 yuv444 时网页端黑屏。30fps 片源沿用 -g 60。
| 档位 | 画面 | 视频码率 | bufsize |
|---|---|---|---|
| 144p | 256×144 | 400k | 800k |
| 240p | 426×240 | 700k | 1400k |
| 360p | 640×360 | 1000k | 2000k |
| 480p | 854×480 | 1500k | 3000k |
| 720p | 1280×720 | 3000k | 6000k |
| 1080p | 1920×1080 | 6000k | 12000k |
| 1440p | 2560×1440 | 12000k | 24000k |
| 2160p | 3840×2160 | 20000k | 40000k |
720p 的 3000k / 6000k 和实测那条的码率数字相同,放在 1280×720 上更合适。2160p 要机器实时压得动,也要上行带宽撑住 20Mbps。
144p · 256×144 · 400k
ffmpeg -re -i 大明1566_144p.mp4 \
-c:v libx264 -preset veryfast -b:v 400k -maxrate 400k -bufsize 800k -g 60 -pix_fmt yuv420p \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://192.168.101.57:1935/live/abc123
240p · 426×240 · 700k
ffmpeg -re -i 大明1566_240p.mp4 \
-c:v libx264 -preset veryfast -b:v 700k -maxrate 700k -bufsize 1400k -g 60 -pix_fmt yuv420p \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://192.168.101.57:1935/live/abc123
360p · 640×360 · 1000k
ffmpeg -re -i 大明1566_360p.mp4 \
-c:v libx264 -preset veryfast -b:v 1000k -maxrate 1000k -bufsize 2000k -g 60 -pix_fmt yuv420p \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://192.168.101.57:1935/live/abc123
480p · 854×480 · 1500k
ffmpeg -re -i 大明1566_480p.mp4 \
-c:v libx264 -preset veryfast -b:v 1500k -maxrate 1500k -bufsize 3000k -g 60 -pix_fmt yuv420p \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://192.168.101.57:1935/live/abc123
720p · 1280×720 · 3000k
ffmpeg -re -i 大明1566_720p.mp4 \
-c:v libx264 -preset veryfast -b:v 3000k -maxrate 3000k -bufsize 6000k -g 60 -pix_fmt yuv420p \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://192.168.101.57:1935/live/abc123
1080p · 1920×1080 · 6000k
ffmpeg -re -i 大明1566_1080p.mp4 \
-c:v libx264 -preset veryfast -b:v 6000k -maxrate 6000k -bufsize 12000k -g 60 -pix_fmt yuv420p \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://192.168.101.57:1935/live/abc123
1440p · 2560×1440 · 12000k
ffmpeg -re -i 大明1566_1440p.mp4 \
-c:v libx264 -preset veryfast -b:v 12000k -maxrate 12000k -bufsize 24000k -g 60 -pix_fmt yuv420p \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://192.168.101.57:1935/live/abc123
2160p · 3840×2160 · 20000k
ffmpeg -re -i 大明1566_2160p.mp4 \
-c:v libx264 -preset veryfast -b:v 20000k -maxrate 20000k -bufsize 40000k -g 60 -pix_fmt yuv420p \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://192.168.101.57:1935/live/abc123
要让测试流循环不中断,在 -i 前面加 -stream_loop -1。CPU 压不动 1080p 以上时,把 libx264 换成本机有的硬件编码器(h264_nvenc、h264_videotoolbox 等),先用 ffmpeg -encoders 确认名字存在。硬件编码的写法见 FFmpeg 完全指南的硬件加速一节。
只有一个片源
手里只有一份成片时,用 scale 缩到目标分辨率再推。把宽高和码率换成上表对应的一档。偶数边才能进 yuv420p,854×480、426×240 已经是偶数。
ffmpeg -re -i 大明1566.mp4 \
-vf scale=1280:720 \
-c:v libx264 -preset veryfast -b:v 3000k -maxrate 3000k -bufsize 6000k -g 60 -pix_fmt yuv420p \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://192.168.101.57:1935/live/abc123
| 档位 | scale |
|---|---|
| 144p | scale=256:144 |
| 240p | scale=426:240 |
| 360p | scale=640:360 |
| 480p | scale=854:480 |
| 720p | scale=1280:720 |
| 1080p | scale=1920:1080 |
| 1440p | scale=2560:1440 |
| 2160p | scale=3840:2160 |
怎么确认推上去了
- FFmpeg 持续打印
frame=,speed接近1.0x。明显大于 1,多半是忘了-re。 - 浏览器打开
http://192.168.101.57:8080,播放器进入直播中。 - 后台能看到当前有输入、有观众。
推不上去时按这几条对:
Connection refused:容器没在跑,或防火墙没放行1935。本机先docker ps,再在推流那台机器上确认能连到192.168.101.57:1935。- 认证失败、立刻断开:流密钥和路径不对。完整地址是
rtmp://IP:1935/live/密钥,密钥改过就要一起改。 Protocol not found:这份 FFmpeg 没编译 RTMP。换带该协议的构建。- 网页有声音没画面,或黑屏:加上
-pix_fmt yuv420p再推一次。 speed长期低于0.9x,画面一卡一卡:编码跟不上实时。降低分辨率或码率,或改用硬件编码器。
升级和停掉
升级时拉新镜像再重建容器。挂出来的 data 还在,配置和流密钥不会丢。
docker pull owncast/owncast:latest
docker compose up -d
用的是 docker run 时,先停掉旧容器,再用原来的参数(同一个 data 挂载)重新 docker run。
docker stop owncast
docker rm owncast
停容器只是停进程。data 目录还在宿主机上,下次用同一条挂载启动,后台配置还在。