使用FFmpeg转推YouTube直播流失败求助
使用FFmpeg转推YouTube直播流失败求助
我写了一个简单的PHP页面,想实现输入YouTube直播URL后,自动提取直播流地址,再用FFmpeg转推到自己的RTMP服务器,但目前完全没效果,有没有大佬能帮忙排查下问题?
我的代码如下:
<!DOCTYPE html> <html> <head> <title>YouTube Live Stream Restream</title> </head> <body> <h1>YouTube Live Stream Restream</h1> <form method="post"> <label for="youtube-url">YouTube URL:</label><br> <input type="text" id="youtube-url" name="youtube-url" size="50" placeholder="Enter a YouTube URL here"><br> <input type="submit" value="Submit"> </form> <?php if ($_SERVER['REQUEST_METHOD'] === 'POST') { $url = $_POST['youtube-url']; $rtmp_url = shell_exec("youtube-dl --skip-download --write-info-json --print-json --all-subs $url | grep 'rtmp' | head -n 1 | cut -d ':' -f 2"); $command = "ffmpeg -i $rtmp_url -c:v copy -c:a aac -strict -2 -f flv rtmp://YOUR_SERVER_URL/live/STREAM_KEY"; $output = shell_exec($command); echo "<h2>Console output:</h2>"; echo "<pre>$output</pre>"; } ?> </body> </html>
可能的问题点&排查步骤:
- youtube-dl已经过时:现在youtube-dl基本停止维护,很多YouTube新流格式它识别不了,建议换成
yt-dlp(youtube-dl的活跃维护分支),这大概率是核心问题。 - 流地址提取逻辑错误:你用
grep 'rtmp'提取地址,但现在YouTube直播大多采用HLS(m3u8)格式,根本没有RTMP字段,所以提取到的$rtmp_url可能是空值或无效地址。 - 命令执行权限不足:PHP运行的用户(比如
www-data)可能没有执行youtube-dl/yt-dlp、FFmpeg的权限,或者这些工具不在PHP的环境变量PATH里,需要写绝对路径(比如/usr/local/bin/yt-dlp)。 - 目标RTMP配置错误:代码里的
rtmp://YOUR_SERVER_URL/live/STREAM_KEY要替换成你自己的实际服务器地址和流密钥,这个没改对肯定推流失败。 - 命令注入风险:直接把用户输入的
$url放到shell命令里非常危险,容易被攻击,一定要用escapeshellarg()转义输入内容。
修正后的代码示例(用yt-dlp处理HLS流):
<!DOCTYPE html> <html> <head> <title>YouTube Live Stream Restream</title> </head> <body> <h1>YouTube Live Stream Restream</h1> <form method="post"> <label for="youtube-url">YouTube URL:</label><br> <input type="text" id="youtube-url" name="youtube-url" size="50" placeholder="Enter a YouTube URL here"><br> <input type="submit" value="Submit"> </form> <?php if ($_SERVER['REQUEST_METHOD'] === 'POST') { $url = $_POST['youtube-url']; // 转义用户输入,避免命令注入风险 $safeUrl = escapeshellarg($url); // 使用yt-dlp获取直播流的JSON信息 $streamInfo = shell_exec("/usr/local/bin/yt-dlp --skip-download --print-json $safeUrl"); $streamData = json_decode($streamInfo, true); if ($streamData && isset($streamData['url'])) { $streamUrl = escapeshellarg($streamData['url']); // 替换成你自己的目标RTMP地址 $targetRtmp = "rtmp://你的服务器地址/live/你的流密钥"; // 同时捕获命令的标准输出和错误输出 $command = "ffmpeg -i $streamUrl -c:v copy -c:a aac -strict -2 -f flv $targetRtmp 2>&1"; $output = shell_exec($command); echo "<h2>Console output:</h2>"; echo "<pre>$output</pre>"; } else { echo "<h2>Error:</h2>"; echo "<p>无法提取有效的直播流地址,请检查URL是否正确,或者更新yt-dlp到最新版本。</p>"; if (!$streamData) { echo "<p>yt-dlp执行输出:<pre>$streamInfo</pre></p>"; } } } ?> </body> </html>
额外注意事项:
- 安装必要工具:
- 安装FFmpeg:
sudo apt install ffmpeg(Debian/Ubuntu系统) - 安装yt-dlp:
sudo wget https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -O /usr/local/bin/yt-dlp && sudo chmod a+rx /usr/local/bin/yt-dlp
- 安装FFmpeg:
- 先手动测试命令:在服务器终端里先手动运行yt-dlp和FFmpeg的命令,确认能成功提取流并推流,再放到PHP里运行,更容易排查问题。
- 查看PHP错误日志:如果还是失败,去服务器的PHP错误日志里找具体报错信息,比如权限问题、命令不存在等。
备注:内容来源于stack exchange,提问作者Nikhil Verma
相关产品推荐
相关产品推荐

