方案一:
·mjpg-streamer,它运行在ARM板上
·在手机上使用浏览器直接观看视频
方案二:
推流端(Fmpeg)---->Nginx(RTMP流媒体服务器)--rtmp/httpflv/hls-->浏览器、播放器
此篇文章记录方案二的具体细节
一、FFmpeg
FFmpeg是一款开源软件,是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。
1、音视频数据处理流程
2、FFmpeg的组成
组成部分
相关概念:
常用参数:
有关利用Buildroot安装ffmpeg并编译生成开发板上的镜像文件的配置可参考imx6ull开发板 ffmpeg nginx buildroot 摄像头推流实验_韦东山 200万免驱摄像头-CSDN博客
linux之buildroot(2)配置toolchain_使用buildroot创建自己的交叉编译工具链-CSDN博客
基于恩智浦imx6ull处理器的buildroot详细使用步骤 - 嵌入式技术 - 电子发烧友网
推流命令:
ffmpeg -f alsa -ac 1 -ar 11025 -i hw:0,0 -acodec aac -f v4l2 -framerate 10 -i /dev/video1 -q 10 -f flv rtmp://127.0.0.1:1935/live/wei
这条命令实际上是在将 V4L2 视频数据和 ALSA 音频数据捕获后,编码成 FLV 格式,并通过 RTMP 协议推送到服务器。
参数解释
-
-f alsa:
- 指定音频输入格式为 ALSA (Advanced Linux Sound Architecture)。
-
-ac 1:
- 设置音频通道数为 1,即单声道。
-
-ar 11025:
- 设置音频采样率为 11025 Hz。
-
-i hw:0,0:
- 指定音频输入设备为 ALSA 设备
hw:0,0
,通常代表第一个 ALSA 音频设备的第一个混音器。
- 指定音频输入设备为 ALSA 设备
-
-acodec aac:
- 设置音频编码器为 AAC (Advanced Audio Coding)。
-
-f v4l2:
- 指定视频输入格式为 V4L2 (Video for Linux 2)。
-
-framerate 10:
- 设置视频帧率为 10 fps (frames per second)。
-
-i /dev/video1:
- 指定视频输入设备为
/dev/video1
,通常代表第二个 V4L2 视频设备。
- 指定视频输入设备为
-
-q 10:
- 设置视频质量等级为 10。数值越小,质量越高,但文件大小也越大。
-
-f flv:
- 设置输出格式为 FLV (Flash Video)。
-
rtmp://127.0.0.1:1935/live/wei:
- 指定 RTMP 推送的目标 URL。这里推送到本地 RTMP 服务器的
live/wei
流(此处IP可以自己的实际情况修改)。
- 指定 RTMP 推送的目标 URL。这里推送到本地 RTMP 服务器的
二、Ubuntu中Nginx搭建流媒体服务器
1、搭建
选择Ubuntu为流媒体服务器,所以在Ubuntu中利用Nginx搭建服务器。参考文章:
Ubuntu系统使用Nginx搭建RTMP服务器实现推流_ubuntu nginx rtmp-CSDN博客
在ubuntu 上搭建Nginx-RTMP 直播服务器_ubuntu nginx rtmp-CSDN博客
Linux下使用Nginx搭建Rtmp流媒体服务器,实现视频直播功能_linux rtmp服务器播放卡-CSDN博客
2、遇到的问题
问题一:在执行$ git clone https://github.com/nginx/nginx.git命令时出现问题:
fatal: unable to access 'https://github.com/nginx/nginx.git/': Failed to connect to github.com port 443: Connection refused
fatal: unable to access 'https://github.com/nginx/nginx.git/': Failed to connect to github.com port 443: Connection refused
参考https://zhuanlan.zhihu.com/p/620860502这篇文章解决,将https更改为http,两者的区别为前者加密后者不加密,s代表着SSL协议,依靠证书来验证身份。
问题二:在执行make j4 && make install语句时出错,因为显示了Permission denied的错我,所以在命令前加了sudo,但显示结果还是不对
解决:是因为在命令 sudo make -j4 && make install
中,make -j4
部分是在以超级用户权限运行,而 make install
部分是在当前用户权限下运行。这是因为 &&
运算符将两个命令连接起来,但不会自动继承前一个命令的权限。正确语句:
sudo make -j4 && sudo make install
问题三:启动nginx时出现
nginx: [alert] could not open error log file: open() "/usr/local/nginx/logs/error.log" failed (13: Permission denied)
2024/06/20 07:42:49 [emerg] 46729#0: mkdir() "/usr/local/nginx/client_body_temp" failed (13: Permission denied)
解决:根据信息Permission denied权限不够就sudo chmod,文件不存在就根据错我信息提示在该路径下创建文件,目录不存在也是一样。最后sudo nginx启动成功。
启动成功后就可以将数据流推送到服务器中。推流端要注意封装格式、编码器的选择、IP地址和端口设置
-
FFmpeg 捕获和编码:
- FFmpeg 从摄像头捕获原始视频数据。
- 使用
-f v4l2
指定视频源。 - 使用
-c:v h264
或-c:v libvpx
等参数指定编码器。 - 编码后的数据以 H.264 或 VP8 格式存储。
-
FFmpeg 封装和推送:
- FFmpeg 将编码后的数据封装成适合传输的格式,如 RTSP 或 RTMP。
- 使用
-f flv
或-f rtsp
等参数指定输出格式。 - 使用
-rtmp_url
或-rtsp_transport
等参数指定目标 URL 和传输方式。 - 将封装好的数据推送到 Nginx 服务器。
-
Nginx 接收和转发:
- Nginx 作为服务器接收 FFmpeg 推送的数据。
- Nginx 使用 RTMP 或 RTSP 模块接收数据。
- Nginx 将接收到的数据解封装,提取出编码后的视频数据。
- Nginx 将解封装后的数据转发给客户端。
-
客户端接收和解码:
- 客户端从 Nginx 接收编码后的视频数据。
- 使用播放器软件(如 VLC 或 HTML5 视频标签)进行解码。
- 解码后的数据被播放器渲染并在屏幕上显示。
三、内网穿透
1、内网穿透简介
因为在之前的设置中,ARM板用 ffmpeg 向局域网中的 Ubuntu 内 nginx 以 rtmp 协议推流,而Windows中VLC播放器通过读取rtmp URL(uniform resource locator资源定位符)来拉流实现摄像头监控,
所以就会有一个问题,不在这一局域网中的设备就没法通过URL播放,所以需要用到内网穿透。
在此补充局域网和路由器的相关知识:
局域网中的主机要和公网中的设备通信,就要确定通信信息的源、目的、端口,主机将数据交给路由器,那么路由器会将主机信息的源和端口替换,目的不变发送出去,并将这一通信映射过程记录在册,之后有信息从目的返回路由器确认有这一回事儿会将信息在转给对应的主机,这样一来将少了公网ip的申请,也保证了局域网内主机的安全,但这样一来,不同局域网内的设备就乜就办法直接进行数据交换。
也就是说要打破内网公网间的隔阂,使得公网中的设备也能向内网中设备发送接收数据。这样一来就可以让不在局域网中的设备也能通过播放URL来实现功能。
2、实现方案
1)通过设置路由器
在路由器中安装内网穿透的软件,如果有80端口的数据访问路由器公网IP,就将请求转发给对应的主机。
2)通过现有的软件完成内网穿透
比如用花生壳软件,
在这里花生壳将一个公网ip映射到了局域网的主机内,其实也就是代替了路由器的功能。
补充:rtmp协议
RTMP(Real-Time Messaging Protocol,实时消息传输协议) 是一种用于音频、视频和数据在互联网或局域网上的流式传输协议,最初由 Macromedia(现为 Adobe)开发,主要用于与 Adobe Flash Player 通信。RTMP 常用于视频点播、直播以及实时交互式内容的传输。
RTMP 的工作原理
RTMP 是基于 TCP 的长连接协议,提供高效的双向通信。它将音视频数据和其他类型的数据包打包,通过固定格式和流媒体服务器进行传输。RTMP 本质上是一种多路复用协议,能够同时传输音频、视频和数据流。
RTMP 协议栈通常可以分为三层:
- Lower Layer:底层协议,用于分割数据包,处理数据帧的分发和顺序,类似于 TCP 的功能。
- Higher Layer:高级层,负责处理音视频和数据流的管理,定义了音视频流的同步、控制和消息传输。
- Application Layer:应用层,负责具体的流媒体内容和其他消息数据的封装和传输
RTMP 协议的特点
-
低延迟:
- RTMP 非常适合需要低延迟的直播场景,典型延迟在 1-3 秒之间,相对于 HTTP 流媒体(如 HLS),延迟较低。
-
长连接:
- RTMP 基于 TCP 的长连接通信,确保流媒体传输的可靠性。
-
分段传输:
- RTMP 将数据流分成较小的区块(chunks),然后逐步发送,以确保数据传输的连续性和流畅性。块的大小可以动态调整,默认大小为 128 字节。
-
多路复用:
- RTMP 支持多路音视频和数据流的复用,这意味着可以同时传输视频、音频、元数据等内容。
-
灵活性:
- RTMP 支持点播(VOD)和直播(Live)两种模式,适用于多种流媒体应用场景。
RTMP 的优点
-
低延迟:
- RTMP 延迟通常在 1-3 秒之间,特别适合需要低延迟的场景,如直播、视频通话和互动直播。它相比基于 HTTP 的流媒体协议(如 HLS、DASH)的延迟要低得多。
-
支持多路复用:
- RTMP 可以在单一连接上传输多个数据流(音频、视频和控制信号等),这使得它非常适合需要同步音视频和其他数据的实时应用。
-
实时性强:
- RTMP 设计为推送式协议,发布者会持续不断地将音视频数据推送到服务器,订阅者可以立即接收到数据进行播放。这种实时性对于需要及时响应的应用非常重要。
-
灵活的控制帧:
- RTMP 支持传输控制信号,如暂停、停止、切换流、调整带宽等操作。这种灵活性使得 RTMP 在流媒体直播和互动视频等场景中有很大的优势。
-
动态自适应:
- RTMP 支持动态调整流的带宽,可以根据网络条件来选择合适的码率。这对于在网络条件波动较大的情况下保持流畅的播放体验非常重要。
-
较早的应用:
- RTMP 是较早的流媒体协议,拥有广泛的历史应用基础,尤其是在 Flash 视频时代,大量的平台和播放器支持 RTMP,因此它在一些直播和点播平台中仍然具有应用场景。
RTMP 的缺点
-
基于 TCP 的缺陷:
- 虽然 TCP 保证了数据传输的可靠性(丢包重传),但在弱网络或高延迟网络下,TCP 的流量控制和丢包重传机制可能导致带宽抖动,影响流畅度。相比之下,基于 UDP 的协议(如 WebRTC、SRT 等)在丢包时表现更好,延迟更低。
-
穿透性差:
- RTMP 基于 TCP 的长连接,常常被防火墙或 NAT 设备阻挡。因此,RTMP 在某些网络环境下可能无法正常工作,需要借助额外的技术(如 RTMPT over HTTP)来绕过防火墙。
-
不支持 H.265/HEVC:
- RTMP 最初是为 Flash 视频服务的,主要支持 H.264 编码。尽管可以扩展支持其他编解码器,但对现代高效编解码器(如 H.265/HEVC 或 AV1)的支持较差。
-
依赖 Flash Player:
- RTMP 最初设计为配合 Adobe Flash Player 使用,但 Flash Player 在近年来被逐渐淘汰,导致 RTMP 在浏览器中的直接支持几乎消失。因此,在现代网络应用中,RTMP 需要转换为其他协议(如 HLS 或 DASH)才能与 HTML5 播放器配合使用。
-
对大规模分发支持不足:
- RTMP 的点对点通信特性使其在大规模直播或点播场景下扩展性较差。相比之下,基于 HTTP 的协议(如 HLS 和 DASH)更适合大规模流媒体分发,能够利用现有的 CDN(内容分发网络)架构。
-
过时的加密和安全机制:
- 尽管 RTMP 支持 RTMPS 和 RTMPE 等加密协议,但这些加密技术已经逐渐过时,安全性不如现代基于 HTTPS 的流媒体传输协议。RTMP 在现代安全性要求较高的场景下,可能无法满足要求。
-
大多数浏览器的原生支持逐渐消失:
- 由于 Flash 的逐渐淘汰和 HTML5 的普及,现代浏览器不再原生支持 RTMP,这使得 RTMP 在网页应用中不再是首选协议。开发者需要使用服务器端进行协议转换(如 RTMP 转 HLS 或 DASH)才能在浏览器中播放。