• ardupilot开发 --- RTSP视频流 篇


    在这里插入图片描述

    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方式安装,如下:

      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/快速开始

    • 下载
      git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit
      cd ZLMediaKit
      git submodule update --init
      # 安装依赖,可选。参考文档
      
    • 编译
      cd ZLMediaKit
      mkdir build
      cd build
      cmake ..
      make -j4
      
    • 运行
      cd ZLMediaKit/release/linux/Debug
      #通过-h可以了解启动参数
      ./MediaServer -h
      # 以守护进程模式启动:主进程关闭自动重启。需要加sudo,因为544端口需要管理员权限!!!!
      sudo ./MediaServer -d &
      # 设置log打印等级:0~4,等级越高越简洁,下图是等级0
      sudo ./MediaServer -d -l 0 &
      
      在这里插入图片描述
    • 关闭服务
      sudo killall -2 MediaServer
      
    • log
      log保存在ZLMediaKit/release/linux/Debug/log中。
    • 推流测试
      要先开启RTSP服务再推流不然会报类似下面的错误:
      在这里插入图片描述
      用ffmpeg 推:
      # 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可以得到更多有用的信息:
      在这里插入图片描述
    • 拉流播放测试
      ffplay -rtsp_transport tcp -i rtsp://127.0.0.1:554/live/test
      
      注意:rtsp地址要与推流地址保持一致,不然无法拉取和播放!!注意live是参数不能漏!!

    3. 推流

    要先开启RTSP服务再推流不然会报类似下面的错误:
    在这里插入图片描述

    • ffmpeg
      # 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
      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
      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
      vlc rtsp://127.0.0.1:554/live/test
      
    • ffmpeg
      ffplay -rtsp_transport tcp -i rtsp://127.0.0.1:554/live/test
      
    • opencv拉取RTSP视频流
      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

  • 相关阅读:
    Python之爬虫之BeautifulSoup学习
    Android 8.1 MTK root权限版本
    Python作业【简单算法题】
    【精讲】vue中的集成动画及配置代理
    Mysql整理-主从复制
    Tomcat Arbitrary Write-file Vulnerability through PUT Method (CVE-2017-12615)
    avue的操作,搜索,table列的自定义配置
    【WPF系列】- Window详解
    三大对象的常用属性和方法【常更新】
    Python爬虫xpath语法及案例使用
  • 原文地址:https://blog.csdn.net/weixin_43321489/article/details/139802045