javascript - 将标准输入输入更新到 ffmpeg 以进行 youtube 直播时如何防止屏幕撕裂
问题描述
我正在开发一个直播应用程序,该应用程序允许多个 Web 客户端通过 webrtc 将视频流式传输到“控制器”客户端,该客户端将添加他们的音轨,然后能够在这些视频源之间切换并将原始流数据输出到运行 ffmpeg 的服务器,然后将提要发送到 youtube live。
“控制器”客户端只需将一个对等视频源设置为按钮按下时的“活动”流,而将所有其他视频源设置为“非活动”。
然后将数据发送到 node.js 服务器,如下所示:
this.mediaSources.forEach((source, _) => {
source.recorder.ondataavailable = (e: BlobEvent) => {
if (source.active) {
this.socket.emit('binarystream', e.data)
}
}
节点服务器启动一个 ffmepg 进程,如下所示:
export class FfmpegService {
ffmpeg: ChildProcess
youtubeUrl = 'rtmp://a.rtmp.youtube.com/live2'
start(rtmpDestination: string) {
this.ffmpeg = spawn('ffmpeg', this.getFfmpegOptions(rtmpDestination),
{ shell: process.env.NODE_ENV !== 'production' }
)
}
stop() {
if (this.ffmpeg) {
this.ffmpeg.stdin.end()
this.ffmpeg.kill('SIGINT')
this.ffmpeg = null
}
}
feedStream(data: any) {
this.ffmpeg.stdin.write(data)
}
private getFfmpegOptions(streamKey: string): string[] {
const rtmpDestination = this.youtubeUrl + '/' + streamKey
return [
'-i','-',
'-c:v', 'libx264',
'-preset', 'fast', '-tune', 'zerolatency', // video codec config: low latency, adaptive bitrate
'-c:a', 'aac', '-ar', '44100', '-b:a', '64k', // audio codec config: sampling frequency (11025, 22050, 44100), bitrate 64 kbits
'-y', //force to overwrite
'-use_wallclock_as_timestamps', '1', // used for audio sync
'-async', '1', // used for audio sync
//'-filter_complex', 'aresample=44100', // resample audio to 44100Hz, needed if input is not 44100
//'-strict', 'experimental',
'-bufsize', '300k',
'-pix_fmt', 'yuv420p',
'-f', 'flv', rtmpDestination
];
}
在 youtube 现场会话中,一切都按预期工作。唯一的问题是在输入流之间切换时,在稳定下来之前大约有 5 秒的屏幕撕裂。从所有外观来看,切换是立即无缝地发生的。我觉得这可以通过调整 ffmpeg 选项来减弱/解决,但我对 ffmpeg 还是很陌生。我尝试增加/减少 -bufsize 和 -preset cli 选项,但到目前为止没有任何效果。
解决方案
推荐阅读
- azure - Azure ML Web 服务参数输入
- visual-studio-code - 如何在 Visual Code Studio 中为 pug lang 选择选项卡大小?
- javascript - Notepad++ 中的换行符
- firebase - 该方法在 null 上调用
- java - Java Spring 表不存在
- npm - 仅当文件不同时如何 cp 文件?
- arrays - 使用 IF 条件对多维 NumPy 数组进行切片
- python - 列值替换
- jmeter - Jmeter通过generate key进行授权测试——测试用例的思路
- reactjs - 如何使用 React Redux 实现 Firebase 身份验证?