跳转至

36 推拉流、串流码与控制器:实现录制与停止直播流

你好,我是Barry。

上节课,我们通过Nginx-rtmp-module搭建流媒体服务器,还通过RTMP协议实现了HLS协议直播的相关配置。

这节课,我们就来学习如何实现直播的推拉流。推流和拉流的主要作用是实现直播音视频数据的传输,这是直播中最核心的操作。之后,我还会带你利用record命令实现直播录制功能,让我们的直播系统更加强大。

推流

我们先从推流开始学习。在直播系统中,推流是指将音视频数据由主播端发送到流媒体服务器端,供用户端接收、观看。

直播过程中,主播端会使用编码器编码音视频数据,然后通过RTMP协议将编码后的数据推送到服务器端。服务器端接收到数据后,可以对数据进行存储、转码、分发等处理,然后提供给用户端接收观看。

接下来我们一起梳理一下推流的过程,推流的实现步骤分为三步。

第一步,我们需要在 Nginx-rtmp-module中配置推流地址,即指定服务端将音视频数据推送到哪个服务器地址。我们可以在Nginx的配置文件中设置推流地址,在上节课我们已经完成了配置,配置代码如下所示。

rtmp {
    server {
        listen 1935;
        #应用程序块
        application live {
            live on; #开启直播
            hls on;  #开启hls直播
            hls_path /usr/share/nginx/m3u8_files; #配置指定了m3u8文件存储位置
        }
    }
}

第二步,服务端需要使用编码器将音视频数据进行编码,并将编码后的数据封装为RTMP消息。常用的编码器和封装工具包括FFmpeg、OBS Studio等。在编码和封装过程中,我们需要选择合适的编码格式、分辨率、帧率等参数,以确保推流的音视频质量。这节课里,我们选择FFmpeg这种方式,至于OBS的实现方式我们之后的课程里再展开。

第三步,将主播端封装好的RTMP消息,通过RTMP协议推送到指定的服务器地址。这一步我们可以使用命令行工具或编程语言库来实现推流。比方说,使用命令行工具FFmpeg来推流,后面这个推流命令我们在直播系统中就会经常使用。

ffmpeg -i /ss.mp4 -vcodec libx264 -acodec aac -f flv rtmp://10.20.36.136:1935/live/44

这条命令使用FFmpeg工具,对指定路径下的ss.mp4文件进行转码,并将其推送到指定的RTMP服务器上。具体参数的含义你可以参考后面的表格。

那么这里提到的串流码是什么意思呢?

串流码(Stream Key)是一个唯一的字符串,用于在服务器上标识直播流。有了串流码标识,就能让同一个应用的直播流互不影响。

搞定了前面配置以后,就宣告了直播推流成功。我把直播推流成功的效果图给你放在了下面,你可以参考一下效果。

推流成功之后,我们就可以在m3u8_files目录下查看到M3U8及ts文件,实现对直播文件的存储,具体的效果截图是后面这样。

第四步,服务器端接收到推流的音视频数据后,可以进行存储、转码、分发等处理。Nginx-rtmp-module提供了一些功能和配置选项来实现这些处理。例如,我们可以使用record指令录制视频。

到这里,我们就完成了推流的过程。接下来,我们就要考虑如何实现拉流了。

拉流

拉流是指客户端从服务器端获取音视频数据的过程。在直播过程中,客户端通过RTMP协议向服务器端请求获取音视频数据,服务器端接收到请求后,将存储或转码后的音视频数据通过RTMP协议传输给用户端,供用户观看。

不难发现,拉流是一个非常重要的过程,它直接决定了用户观看直播的体验。拉流过程中我们也需要考虑网络带宽、延迟等因素,这样才能确保直播流畅、无卡顿。

拉流的实现我们会采用VideoJS,在第15节课第16节课我们详细讲过。我们通过播放器直接完成了拉流和播放操作。

不过,如果我们想快速实现拉流测试,反复修改VideoJS的配置来测试的话,操作流程太过繁琐,所以这里我还想给你推荐一个工具,它就是VLC,它能帮我们在日常开发中快速进行拉流测试,无需通过前端代码的配置来完成。

VLC应用

VLC是一个跨平台的多媒体播放器和流媒体服务器,支持多种流媒体协议和格式,包括RTMP、HLS、HDS和MP4等。在直播系统中,VLC可以用于拉取和播放直播流。

使用VLC需要下载它的客户端,这是VLC的官网地址。你可以根据你的系统类型直接下载应用。

下载之后,如果你使用的是Windows系统,你根据安装向导来操作即可。如果你使用macOS系统,直接点击安装就可以。

安装成功之后,需要选择上方导航栏中的file,然后选择 open network,在输入框内输入RTMP的地址,再选择open即可。你可以参考后面的示意图来操作。

这时候你就可以直接实现拉流,并且能够播放视频了。

当然,VLC主要还是用于测试拉流的。如果从直播系统完整实现角度考虑,在我们项目当中你就使用VideoJS,对应src就是返回对应服务器m3u8的地址,这样用户就可以直接观看直播了。直播成功播放的效果图是后面这样。

record详解

恭喜你成功完成了直播的推拉流操作,也认识了串流码的作用。接下来,我们需要再来学习一个直播系统配置的常用命令,它就是record命令。这个命令是用来录制直播的,这样可以方便创作者完成直播录制后,再把视频文件投放到平台多次使用。

record命令是Nginx-rtmp-module提供的一个功能,用于录制RTMP直播流媒体。它可以用于记录直播流媒体的内容,并将其保存为文件,以便在需要时进行回放或处理。

record命令的作用和使用场景,我都给你整理成了表格,你可以看一下。

说完了record的作用和应用场景,我们不难发现record可以帮我们解决很多实际业务需求。为了让你更好地应用record命令,我们再详细了解一下具体命令都实现了哪些功能。

record应用

接下来,我们再看看如何在项目中配置并使用record命令。

首先你需要创建一个文件夹,用来存储录制的视频,因为在后面的配置当中我们也需要创建对应的存储地址。这一步操作也比较简单,直接使用mkdir命令在对应路径下完成创建。

创建了存储文件夹之后,接下来我们看看如何在Nginx中进行配置。还是我们之前做RTMP配置的位置,只需要在application应用中完成后面的配置。

rtmp {
    server {
        listen 1935;
        #应用程序块
        application live {  
            live on; #开启直播  
            hls on; #开启HLS直播  
            hls_path /usr/share/nginx/m3u8_files; #指定HLS文件的存储位置  
            rtmp_auto_record on; #启用自动录制模式  
            record_suffix _.flv; #设置录制文件的后缀名为_.flv  
            record_path /usr/share/nginx/record_files; #设置录制文件的保存路径  
        }
    }
}

对照代码,我来带你梳理一下上面的配置项都做了什么。rtmp_auto_record on表示启用自动录制模式,当有新的直播流推流时,自动开始录制,并在直播结束后自动停止录制。

接下来。我们再来看看第10行代码,record_suffix _.flv;表示录制文件的后缀名为 .flv。这意味着录制的文件将保存为 .flv格式。第11行的record_path 表示录制文件的保存路径为/usr/share/nginx/record_files。当然,这两处我们都可以结合实际需要灵活修改。

我们使用record录制直播时,通常是在发起推流后自动开始录制,你也要时刻关注直播存储的内存空间,以免内存不足影响直播录制。

到这里,我们就实现了直播视频录制的功能。

总结

又到了课程的尾声,我们来做个总结。

推流和拉流的主要作用是实现直播的音视频数据传输。推流将音视频数据推送到服务器端,用于存储、转码、分发等处理。而拉流则从服务器端获取音视频数据,供用户端接收观看。

推流这部分,我们选择用FFmpeg来实现,这一部分的重点还是扎实掌握各个配置项,理解我们每一步的操作有什么作用。

拉流部分,我们在前面的课程已经详细讲解过VideoJS,你如果记不太清,可以回顾前面学过的内容。另外,我们还学习了如何用VLC实现拉流测试,课后你自己下载下来测试一下。它用起来还是很方便的,这样我们就不需要反复更改前端来测试了。

推流和拉流配合使用,我们就可以实现直播的实时传输和观看,提高直播的品质和用户体验。除了直播推拉流,直播录制也是一项重要功能。

为此我们学习了record命令,除了录制RTMP直播流媒体,它还有很多其他适用场景。这节课record的命令部分,我们重点要把握具体命令含义,还有如何在RTMP中配置。

下节课我还会带你进一步完善直播系统的功能,敬请期待。

思考题

这节课我们学习了拉流的工具VLC,你还知道还有哪些工具可以做拉流测试么?

欢迎你在留言区和我交流互动,也推荐你把这节课分享给身边更多的朋友。

精选留言(3)
  • peter 👍(0) 💬(1)

    请教老师几个问题: Q1:“使用编码器解码”中的“解码”是笔误吗? 文章开始的“推流”部分有一段话“直播过程中,主播端会使用编码器解码音视频数据”,其中的“解码”应该是“编码”吧。 Q2:服务端要“转码”,根据什么判断需要转码?要转成什么? Q3:推流的第三步中,“将主播端封装好的RTMP消息”,从这句话看,假设主播用手机,则主播的音视频数据在手机上已经封装为RTMP消息了;但是,推流的第二步,“服务端将XXX数据封装为RTMP消息”,从这句话看,是在服务端才将数据封装为RTMP消息。不矛盾吗? 进一步地,假设主播通过手机发送数据,发送出来的是RTMP数据吗?主播手机 –》Nginx---》后端服务器, 这三个节点的数据分别是什么样? Q4:推流命令”ffmpeg –I …”这个命令是在哪里执行的?手机上执行?Nginx上执行?还是后端服务器上执行? Q5:NRM中配置的服务端地址为什么不包含IP地址? 现在的配置是 hls /usr/…., 没什么没有IP? 服务器难道不需要一个IP地址吗?

    2023-07-16

  • Geek_c08ce7 👍(0) 💬(1)

    请问老师这个项目完整的代码在哪里啊

    2023-07-16

  • 果粒橙 👍(0) 💬(0)

    请问下老师,主播端推流之后,视频流在服务器上是直接由nginx转发给后端服务器,实时将视频流通过ffmpeg转码后,再实时发送给拉流的客户端,这样理解正确吗?请问ffmpeg转码这一块流程的代码在代码仓库的哪个文件里实现的,目前还没找到对应的地方?谢谢老师解答问题了

    2025-02-13