在前端领域,实现视频聊天已经不再是什么新鲜事儿了。然而,随着视频通话的流行,用户对于音画质量的要求也越来越高。而在视频质量的保证的背后,则有转码技术发挥了重要的作用。本文将介绍 Socket.io 如何实现视频聊天的转码。
Socket.io 简介
Socket.io 是 Node.js 平台上实现实时通讯的库。它为实时、双向、事件驱动的通讯提供了完整的解决方案,不仅支持传统的HTTP通信,同时也支持WebSocket协议的应用,也可以向低版本的IE提供对实时API的支持。
视频转码在 Socket.io 中的应用
Socket.io在音视频传输的过程中非常适合用来实现接收端的视频解码、降噪、颜色空间转换、缩放等处理,但是插入像素值之类的操作则较为麻烦。因此,如果需要在传输视频过程中进行编解码、压缩、封装,只能借助于外部推流、转码工具来实现。在这里,我们将使用 Open Broadcast Software(简称 OBS) 来实现推流,使用 ffmpeg 来进行转码。
OBS 的配置
OBS 是一款开源且跨平台的视频录制和直播软件。我们需要将电脑内的摄像头视频推送到服务器上。下面是 OBS 的自定义流命令配置。
视频配置
在 Settings - Output - Streaming 中,选择推流协议 RTMP,流地址设为服务器地址,流密钥可以自定义。
在 Settings - Video 中,将分辨率设为 720p,帧率为 30 FPS。
在 Sources 中选择一个外部模块,选择摄像头作为输入源。
音频配置
在 Settings - Audio 中,选择麦克风作为输入源。
ffmpeg 的配置
ffmpeg 可以根据自己的需求来选择具体的功能,持久性地设置某些命令参数。这是非常方便的,因为我们的命令参数一般不会发生变化。我们可以先在终端输入ffmpeg -version,如果能够正确输出版本号,说明 ffmpeg 安装成功。
安装完 ffmpeg 后,通过以下命令推流。
ffmpeg -re -i /dev/video0 -c:v libx264 -preset veryfast -tune zerolatency -b:v 1200k -minrate 1200k -maxrate 1200k -bufsize 3000k -pix_fmt yuv420p -g 60 -c:a aac -b:a 128k -f flv rtmp://server/live/streamkey
其中,/dev/video0 是本地 macOS 中的 video 设备。通过 -i 参数来指定推流的源,这里是指我们本地的摄像头。通过 -c:v 文件来指定视屏的编码方式,这里是 H264 编码器。通过 -pix_fmt 来指定颜色空间格式, 这里使用了 yuv420p,是指 chroma sub-sampling 为 4:2:0。通过 -c:a 来指定音频编码器,这里是 aac编码方式。-f 参数来指定推流的格式。
Socket.io 如何处理推流
要实现视频聊天的转码,我们需要考虑视频的流转换。一般情况下,传输过程中不宜传输原始视频流,而应该将其进行压缩。我们需要在 Push Stream 流 <-> Decode Stream 流 之间插入一个转码流,来进行压缩、解压缩、以及其他的视频处理等操作。
我们可以通过 ffmpeg -i 指令来读取远程的 RTMP 格式的流文件。ffmpeg 在读取视频流的时候会根据视频内容来生成 PTS、DTS 帧标记和时间戳。在每个接收到的视频帧上,我们可以选择压缩,然后请求 HTTP(或者是其他一些基于 Web Socket 的API) 协议获取相应的视频数据信息。
-- -------------------- ---- ------- ----- ------ - ----- -------------- ------ ----- ------ ---- --- ----- ----- - -------------------------------- ----- ------ - ----- ----- ------------ - --- ------------------------------- ----- ------------ - --- ------------------------------- -- ---- -------------------------- ----- ---------- ---------- - ----- ---- ------ ------- ------- ------ ---- ------ -------- ----- ------ ---- -- --- ----- ------------ - ------------------------------------------- -------------------------- -- -- - --- ------------- - --- --------------------------------------------------- ------------------------ ---- -- - -------------------------- ----- -------- ---- --- --- ---------------------- - ----- -- - --- ----- -- ----------- -- --------------- --- ------- - ---- - --- ------------------------------ - ----- ------------ --- --------------------------------- ------ - -- --- -- ---- -------------------------- ----- ---------- ---------- - ----- ---- ------- -------- ------- ---------- ---------- ------------ ----- ----- -------- -------------- ----- ------ ---- -- --- ----- ------------ - ------------------------------------------- -------------------------- -- -- - --- ------------- - --- --------------------------------------------------- ------------------------ ---- -- - -------------------------- ----- -------- ---- --- --- ---------------------- - ----- -- - --- ----- -- ----------- -- --------------- --- ------- - ---- - --- ------------------------------ - ----- ----------- --- --------- - -------------------------- --------------------------------- ------ - -- ---
上述代码中,我们使用 getUserMedia 获取网页端的多媒体流,并将获取到的音频与视频单独的通道传输给服务器。我们将音频/视频数据通过 ffmpeg 进行转码操作,并将转码后的数据与 Socket.io 进行关联,就能将音视频以指定的格式推送到服务端去了。
总结
通过 Socket.io,我们可以轻松地将视频转码并实现视频聊天的过程。而具体的转码方式则可以使用 ffmpeg 在不同平台上完成,在这里,我们以 OBS 为例记录了整个转码流程。同时, 可以个性化定制一些额外的功能, 比如: 异步式多任务处理、效果特效插件等。
文章中演示的示例代码可以在 Github 上查看: https://github.com/socketio/socket.io-streaming-example。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/647fea7f48841e9894f6b766