ardupilot开发 --- RTSP视频流 篇

我年轻时很穷,努力了几年,终于不再年轻了

  • [0. 一些概念](#0. 一些概念)
  • [1. Ubuntu搭建RTSP服务器的方式](#1. Ubuntu搭建RTSP服务器的方式)
  • [2. 在Ubuntu上搭建RTSP服务器](#2. 在Ubuntu上搭建RTSP服务器)
  • [3. 推流](#3. 推流)
  • [4. 拉流、播放](#4. 拉流、播放)
  • [5. 借鉴的一些例子](#5. 借鉴的一些例子)
  • [6. 其他](#6. 其他)
  • 参考文献

0. 一些概念

  • RTSP服务、RTSP推流、RTSP拉流,缺一不可,尤其是RTSP服务。

  • RTSP服务器、RTSP客户端。推流和拉流都是由客户端发起,向服务器发起对应的请求。RTSP推流一般由RTSP相机或app发起,RTSP拉流一般由上位机的app发起。

  • RTSP服务器默认端⼝是554,在客户端SETUP的时候会把⾃身的RTP和RTCP端⼝告知服务器。在RTSP的session建⽴后,会使⽤RTP/RTCP在约定好的端⼝上传输数据。

  • 向服务端推流

  • 从服务端拉流

1. Ubuntu搭建RTSP服务器的方式

  • live555

    live555 Media Server

  • gstreamer

    gst-rtsp-server包

    c++编写

    注意:安装gstreamer-1.0时并不会自动安装gst-rtsp-server,gst-rtsp-server需要另行通过make方式安装,如下:

    bash 复制代码
    git clone  -b 1.8 https://github.com/GStreamer/gst-rtsp-server.git  //下载源码
    cd gst-rtsp-server      
    git submodule update --init --recursive
    ./autogen.sh
    sudo make
    sudo make install
  • FFmpeg

    搭建不了服务,只能推流或拉流!

  • rtsp-simple-server

    go语言编写

  • EasyDarwin

    easy-darwin

  • ZLMediaKit
    推荐使用!!

    使用文档:https://github.com/ZLMediaKit/ZLMediaKit/wiki/快速开始

2. 在Ubuntu上搭建RTSP服务器

推荐使用ZLMediaKit,以Ubuntu为例:

ZLMediaKit使用文档:https://github.com/ZLMediaKit/ZLMediaKit/wiki/快速开始

  • 下载

    bash 复制代码
    git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit
    cd ZLMediaKit
    git submodule update --init
    # 安装依赖,可选。参考文档
  • 编译

    bash 复制代码
    cd ZLMediaKit
    mkdir build
    cd build
    cmake ..
    make -j4
  • 运行

    bash 复制代码
    cd ZLMediaKit/release/linux/Debug
    #通过-h可以了解启动参数
    ./MediaServer -h
    # 以守护进程模式启动:主进程关闭自动重启。需要加sudo,因为544端口需要管理员权限!!!!
    sudo ./MediaServer -d &
    # 设置log打印等级:0~4,等级越高越简洁,下图是等级0
    sudo ./MediaServer -d -l 0 &
  • 关闭服务

    bash 复制代码
    sudo killall -2 MediaServer
  • log
    log保存在ZLMediaKit/release/linux/Debug/log中。

  • 推流测试
    要先开启RTSP服务再推流不然会报类似下面的错误:

    用ffmpeg 推:

    bash 复制代码
    # ZLMediaKit的RTSP服务默认端口是554,可缺省!/live是参数之一,不能少!!!
    ffmpeg -re -i "/path/to/test.mp4" -vcodec h264 -acodec aac -f rtsp -rtsp_transport tcp rtsp://127.0.0.1/live/test

    推流成功后查看ZLMediaKit的log可以得到更多有用的信息:

  • 拉流播放测试

    bash 复制代码
    ffplay -rtsp_transport tcp -i rtsp://127.0.0.1:554/live/test

    注意:rtsp地址要与推流地址保持一致,不然无法拉取和播放!!注意live是参数不能漏!!

3. 推流

要先开启RTSP服务再推流不然会报类似下面的错误:

  • ffmpeg

    bash 复制代码
    # ZLMediaKit的RTSP服务默认端口是554,可缺省!/live是参数之一,不能少!!!
    ffmpeg -re -i "/path/to/test.mp4" -vcodec h264 -acodec aac -f rtsp -rtsp_transport tcp rtsp://127.0.0.1/live/test

    推流成功后查看ZLMediaKit的log可以得到更多有用的信息:

  • opencv + ffmpeg

    cpp 复制代码
    int main(int argc, char **argv)
    {
    	//rtsp
    	std::string rtsp_server_url = "rtsp://127.0.0.1:554/live/0";
    	std::stringstream command;
    	command << "ffmpeg ";
    	// inputfile options
    	command << "-y "  // overwrite output files
    	<< "-an " // disable audio
    	<< "-f rawvideo " // force format to rawvideo
    	<< "-vcodec rawvideo "  // force video rawvideo ('copy' to copy stream)
    	<< "-pix_fmt bgr24 "  // set pixel format to bgr24
    	<< "-s 640x480 "  // set frame size (WxH or abbreviation)
    	<< "-r 30 "; // set frame rate (Hz value, fraction or abbreviation)
    	command << "-i - ";
    	// outputfile options
    	command 
    	<< "-c:v libx264 "  // Hyper fast Audio and Video encoder
    	<< "-pix_fmt yuv420p "  // set pixel format to yuv420p
    	<< "-tune:v zerolatency "
    	<< "-preset ultrafast " // set the libx264 encoding preset to ultrafast
    	<< "-f rtsp " // force format to flv for rtmp, rtsp for rtsp
    	<< rtsp_server_url;
    
    	FILE *fp = nullptr;
    	try {
    		cv::Mat frame;
    		vpRealSense2 rs2;
    		std::string product_line2 = rs2.getProductLine();//获取相机信息
    		std::cout << "Product line: " << product_line2 << std::endl;
    		rs2::config config2;
    		config2.enable_stream(RS2_STREAM_COLOR, 640, 480, RS2_FORMAT_RGBA8, 30);//配置相机
    		config2.enable_stream(RS2_STREAM_DEPTH, 640, 480, RS2_FORMAT_Z16, 30);
    		config2.enable_stream(RS2_STREAM_INFRARED, 640, 480, RS2_FORMAT_Y8, 30);
    		rs2.open(config2);//启动相机
    		vpCameraParameters cam2 = rs2.getCameraParameters(RS2_STREAM_COLOR);//获取相机 内参
    		vpImage<vpRGBa> I2(rs2.getIntrinsics(RS2_STREAM_COLOR).height, rs2.getIntrinsics(RS2_STREAM_COLOR).width);//定义用于二维码检测的 灰度图
    		
    		vpDisplayX display2;
    		display2.init(I2, 100, 100, "DRONE VIEW");
    		vpDisplay::display(I2);
    		vpDisplay::flush(I2);
    		// 在子进程中调用 ffmpeg 进行推流
    		fp = popen(command.str().c_str(), "w");
    		// 将 cv 读到的每一帧传入子进程
    		if (fp != nullptr)
    		{
    			std::cout << "fp != nullptr" << std::endl;
    			while (1)
    			{
    			rs2.acquire(I2);//获取当前图像
    			//rtsp
    			vpImageConvert::convert(I2, frame);
    			if(frame.empty()) continue;
    			fwrite(frame.data, sizeof(char), frame.total() * frame.elemSize(), fp);
    			vpDisplay::display(I2);
    			vpDisplay::flush(I2);
    			}
    			pclose(fp);
    			return 0;
    		}
    		else
    		{
    			pclose(fp);
    			std::cout << "fp == nullptr" << std::endl;
    			return -1;
    		}
    	}
    	catch (const vpException &e) {
    		pclose(fp);
    		std::cout << "Caught an exception: " << e << std::endl;
    		return -1;
    	}
    }

4. 拉流、播放

  • gstreamer

    bash 复制代码
    gst-launch-1.0 playbin uri=rtsp://127.0.0.1:554/live/test
    gst-launch-1.0 playbin uri=rtsp://admin:WANGfengtu12@10.0.20.190:554/client0x
    gst-launch-1.0 playbin uri=rtsp://admin:WANGfengtu12@10.0.20.61:554/client1x
    gst-launch-1.0 rtspsrc location=rtsp://admin:WANGfengtu12@10.0.20.70:554/client0x ! rtph264depay ! h264parse ! decodebin ! autovideosink
    gst-launch-1.0 rtspsrc location=rtsp://admin:WANGfengtu12@10.0.20.61:554/client1x ! rtph264depay ! h264parse ! decodebin ! autovideosink
  • vlc

    bash 复制代码
    vlc rtsp://127.0.0.1:554/live/test
  • ffmpeg

    bash 复制代码
    ffplay -rtsp_transport tcp -i rtsp://127.0.0.1:554/live/test
  • opencv拉取RTSP视频流

    cpp 复制代码
    cv::VideoCapture cap;
    cap.open("rtsp://admin:WANGfengtu12@10.0.20.61:554/client1x",cv::CAP_GSTREAMER);
    cv::Mat frame;
    while(cv::waitKey(1) < 0) // Press any key to exit
    {
        if (!cap.read(frame))
        {
            cerr << "No frames grabbed!\n";
            break;
        }
    }
    }

    待续...

5. 借鉴的一些例子

使用ZLMediaKit搭建RTSP服务,使用ffmpeg推流
https://blog.csdn.net/jaket5219999/article/details/135228010

使用gst-rtsp-server搭建RTSP服务,使用gstreamer推流和拉流:
https://blog.csdn.net/Aidam_Bo/article/details/114398506
https://blog.csdn.net/zhngyue123/article/details/126362312

6. 其他

参考文献

https://www.avdancedu.com/e5aee947/
https://blog.csdn.net/weixin_37210821/article/details/131406193

相关推荐
EmotionFlying10 天前
(11)(2.1.6) Hobbywing DroneCAN ESC(一)
copter·ardupilot·1024程序员节·电调和电机
EmotionFlying14 天前
(11)(2.1.7) FETtec OneWire ESCs(一)
copter·ardupilot·电调和电机
EmotionFlying1 个月前
(11)(2.1.4) DroneCAN ESCs
外设硬件·copter·ardupilot
EmotionFlying1 个月前
(11)(2.1.3) KDE CAN ESCs(二)
外设硬件·copter·ardupilot
EmotionFlying1 个月前
(11)(2.1.2) DShot ESCs(四)
外设硬件·copter·ardupilot
EmotionFlying2 个月前
(11)(2.1.2) DShot ESCs(一)
外设硬件·copter·ardupilot
干了这碗汤3 个月前
ardupilot开发 --- C嘎嘎 篇
ardupilot
EmotionFlying3 个月前
(24)(24.2) Minim OSD快速安装指南(二)
外设硬件·copter·ardupilot
干了这碗汤3 个月前
ardupilot开发 --- 网络技术综述 篇
ardupilot
干了这碗汤3 个月前
ardupilot开发 --- Rpanion-server 篇
ardupilot