如何通过JavaScript将摄像头视频流推送至YouTube直播频道
嘿,这个问题我之前碰过不少次,其实浏览器原生没法直接把摄像头的MediaStream推去YouTube直播——因为YouTube直播用的是RTMP/RTMPS协议,而浏览器没有原生支持这个协议的API。不过咱们有几种可行的方案,我给你一步步拆解清楚:
核心前提:先拿到YouTube直播的推流信息
首先你得去YouTube创作者工作室的直播后台,创建一个直播流,拿到两个关键内容:
- RTMP推流地址(比如
rtmp://a.rtmp.youtube.com/live2) - 推流密钥(比如
xxxx-xxxx-xxxx-xxxx-xxxx)
把这俩拼起来就是完整的推流URL:rtmp://a.rtmp.youtube.com/live2/xxxx-xxxx-xxxx-xxxx-xxxx
方案一:前端+Node.js后端+FFmpeg(最常用且稳定的方案)
这个方案的逻辑是:前端把摄像头的流通过WebSocket传给后端,后端用FFmpeg把收到的流转成RTMP格式,再推送到YouTube。
第一步:修改你的前端代码,添加流传输逻辑
在你现有代码的基础上,加上WebSocket和MediaRecorder的逻辑,把摄像头流传给后端:
var start = function(){ var video = document.getElementById('video'), vendorUrl = window.URL || window.webkitURL; if (navigator.mediaDevices.getUserMedia) { // 记得加上audio: true,不然直播只有画面没声音 navigator.mediaDevices.getUserMedia({ video: true, audio: true }) .then(function (stream) { video.srcObject = stream; // 连接到你的后端WebSocket服务 const ws = new WebSocket('ws://你的后端IP:8080'); // 创建MediaRecorder,把流转成WebM格式的Blob块发送 const mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/webm; codecs=vp9,opus' }); // 每100ms发送一次数据块 mediaRecorder.ondataavailable = (e) => { if (e.data.size > 0 && ws.readyState === WebSocket.OPEN) { ws.send(e.data); } }; mediaRecorder.start(100); // 断开连接时停止录制 ws.onclose = () => mediaRecorder.stop(); }).catch(function (error) { console.log("Something went wrong!", error); }); } }
第二步:写Node.js后端代码,用FFmpeg转推到YouTube
先安装依赖:
npm install ws fluent-ffmpeg
然后写后端服务代码:
const WebSocket = require('ws'); const ffmpeg = require('fluent-ffmpeg'); const wss = new WebSocket.Server({ port: 8080 }); // 和前端的端口对应 // 替换成你自己的YouTube完整推流URL const YOUTUBE_RTMP_URL = 'rtmp://a.rtmp.youtube.com/live2/你的推流密钥'; wss.on('connection', (ws) => { console.log('前端已连接,开始准备推流'); // 创建FFmpeg进程,把WebSocket收到的WebM流转成RTMP推去YouTube const ffmpegProcess = ffmpeg() .input('-') // 从标准输入读取前端传来的流 .inputFormat('webm') .output(YOUTUBE_RTMP_URL) .outputFormat('flv') // RTMP协议对应FLV格式 .on('start', () => console.log('已开始推流到YouTube')) .on('error', (err) => console.error('FFmpeg出错:', err)) .on('end', () => console.log('推流结束')); // 把前端传来的数据传给FFmpeg的标准输入 ws.on('message', (data) => { ffmpegProcess.stdin.write(data); }); // 前端断开连接时停止FFmpeg进程 ws.on('close', () => { ffmpegProcess.stdin.end(); console.log('前端已断开连接'); }); });
方案二:纯前端尝试(性能要求高,适合测试)
如果你不想搭后端,可以试试ffmpeg.wasm在前端直接把MediaStream转成适合推流的格式,但最终还是需要通过WebSocket/HTTP把数据传给一个支持转RTMP的中转服务(因为浏览器还是没法直接发RTMP)。这个方案对浏览器性能要求较高,不建议在生产环境用。
几个重要注意事项
- 一定要在
getUserMedia里加上audio: true,不然直播只有画面没有声音 - 后端服务器必须安装FFmpeg,否则
fluent-ffmpeg无法正常工作 - 如果你的前端页面是HTTPS协议,WebSocket要改成
wss://,避免混合内容报错 - YouTube直播有10-30秒的延迟,推流后需要等一会儿才能在直播间看到画面
内容的提问来源于stack exchange,提问作者Mohan Terri
相关产品推荐
相关产品推荐

