gstreamer的rtsp转rtmp

简介: gstreamer的rtsp转rtmp

VideoPusher.h

#pragma once
#include <iostream>
#include <gst/gst.h>
#include <gst/app/gstappsink.h>
#include <glib.h>
#include <boost/shared_ptr.hpp>
#include <mutex>
#ifndef INT64_C 
#define INT64_C(c) (c ## LL) 
#define UINT64_C(c) (c ## ULL) 
#endif 
class VideoPusher
{
    struct Exception : std::exception{};
    template<typename T>
    T* chk(T* pointer) {
        if (pointer == nullptr) {
            throw Exception();
        }
        return pointer;
    }
    template<typename T>
    void delptr(T* pointer)
    {
        if (pointer != nullptr)
        {
            delete pointer;
            pointer = nullptr;
        }
    }
public:
    VideoPusher();
    VideoPusher(std::string strlocation, std::string strCode);
    virtual ~VideoPusher();
    bool Run(std::string strlocation, std::string strCode, std::string strrequest);
protected:
    static void _onPadAdded(GstElement *src, GstPad *src_pad, gpointer user_data);
    void SetElesNull();
protected:
    GMainLoop  *_loop;
    GstBus*     _bus;
    GstElement* _pipeline;
    GstElement* _source;
    GstElement* _depay;
    GstElement* _parse;
    GstElement* _capsfilter;
    GstElement* _queue1;
    GstElement* _rtmpsink;
    GstElement* _flvmux;
    std::mutex _mutex;
  bool _bStopPush;
};
typedef boost::shared_ptr<VideoPusher> VideoPusherPtr;

VideoPusher.cpp

void VideoPusher::_onPadAdded(GstElement *src, GstPad *src_pad, gpointer user_data)
{
    GstPad* sink_pad = (GstPad*)user_data;
    gst_pad_link(src_pad, sink_pad);
}
void VideoPusher::SetElesNull()
{
    _loop = nullptr;
    _bus = nullptr;
    _pipeline = nullptr;
    _source = nullptr;
    _depay = nullptr;
    _parse = nullptr;
    _capsfilter = nullptr;
    _queue1 = nullptr;
    _rtmpsink = nullptr;
    _flvmux = nullptr;
}
bool VideoPusher::Run(std::string strLocation,
    std::string strCode, std::string strrequest)
{
  _bStopPush = false;
  while (!_bStopPush)
  {
    SetElesNull();
    gboolean terminate = FALSE;
    gst_init(nullptr, nullptr);
    std::stringstream stream;
    stream << "pipeline" << g_pipelinenum++;
    std::string strname;
    strname = stream.str();
    _pipeline = chk(gst_pipeline_new(strname.c_str()));
    _source = chk(gst_element_factory_make("rtspsrc", "src"));
    _depay = chk(gst_element_factory_make(("rtp" + strCode + "depay").c_str(), "depay"));
    _parse = chk(gst_element_factory_make((strCode + "parse").c_str(), "parse"));
    _flvmux = chk(gst_element_factory_make("flvmux", "flvmux"));
    _queue1 = chk(gst_element_factory_make("queue", "queue"));
    _capsfilter = chk(gst_element_factory_make("capsfilter", "filter"));
    _rtmpsink = chk(gst_element_factory_make("rtmpsink", "sink"));
    //g_object_set(_source, "protocols", 0x00000004, NULL);
    g_object_set(_source, "latency", 0, NULL);
    g_object_set(_capsfilter, "caps-change-mode", 1, NULL);
    g_object_set(_rtmpsink, "location", strLocation.c_str(), NULL);
    gst_bin_add_many(GST_BIN(_pipeline), _source, _depay, _parse, _flvmux, _capsfilter, _queue1, _rtmpsink, NULL);
    g_signal_connect(_source, "pad-added", G_CALLBACK(&_onPadAdded), gst_element_get_static_pad(_depay, "sink"));
    gboolean bsuccess = gst_element_link_many(_depay, _parse, _flvmux, _capsfilter, _queue1, _rtmpsink, NULL);
    if (!bsuccess) {
      g_print("Failed to link one or more elements!\n");
      gst_element_unlink_many(_depay, _parse, _flvmux, _capsfilter, _queue1, _rtmpsink, NULL);
      Sleep(1000);
      continue;
    }
    g_object_set(_source, "location", strrequest.c_str(), NULL);
    GstCaps* caps = gst_caps_new_simple(
      "video/x-raw",
      "format", G_TYPE_STRING, "rgb",
      "width", G_TYPE_INT, 426,
      "height", G_TYPE_INT, 240,
      "framerate", GST_TYPE_FRACTION, 25, 1,
      NULL);
    g_object_set(_capsfilter, "caps", caps, NULL);
    gst_caps_unref(caps);
    GstStateChangeReturn res = gst_element_set_state(_pipeline, GST_STATE_PLAYING);
    if (res == GST_STATE_CHANGE_FAILURE)
    {
      g_printerr("Unable to set the pipeline to the playing state.\n");
      gst_object_unref(_pipeline);
      Sleep(1000);
      continue;
    }
    GstMessage *msg;
    /* Listen to the bus */
    //_bus = gst_element_get_bus(_pipeline);
    _bus = gst_pipeline_get_bus(GST_PIPELINE(_pipeline));
    do
    {
      msg = gst_bus_timed_pop_filtered(_bus, GST_CLOCK_TIME_NONE,
        GstMessageType(GST_MESSAGE_STATE_CHANGED |
        GST_MESSAGE_ERROR | GST_MESSAGE_EOS));
      /* Parse message */
      if (msg != NULL)
      {
        GError *err;
        gchar *debug_info;
        switch (GST_MESSAGE_TYPE(msg))
        {
        case GST_MESSAGE_ERROR:
        {
          gst_message_parse_error(msg, &err, &debug_info);
          g_printerr("Error received from element %s: %s\n", GST_OBJECT_NAME(msg->src), err->message);
          g_printerr("Debugging information: %s\n", debug_info ? debug_info : "none");
          g_clear_error(&err);
          g_free(debug_info);
          terminate = TRUE;
        }
        break;
        case GST_MESSAGE_EOS:
        {
          g_print("End-Of-Streamreached.\n");
          terminate = TRUE;
        }
        break;
        case GST_MESSAGE_STATE_CHANGED:
        {
          /* We are onlyinterested in state-changed messages from the pipeline */
          if (GST_MESSAGE_SRC(msg) == GST_OBJECT(_pipeline))
          {
            GstState old_state, new_state, pending_state;
            gst_message_parse_state_changed(msg,
              &old_state,
              &new_state,
              &pending_state);
            g_print("Pipeline state changed from %s to %s:\n",
              gst_element_state_get_name(old_state),
              gst_element_state_get_name(new_state));
            if (pending_state == GST_STATE_NULL)
            {
              terminate = TRUE;
            }
          }
        }
        break;
        default:
        {
          /* We shouldnot reach here */
          g_printerr("Unexpected message received.\n");
          break;
        }
        }
        gst_message_unref(msg);
        //  std::this_thread::sleep_for(std::chrono::milliseconds(200));
      }
    } while (!terminate);
    /* Free resources */
    try
    {
      std::lock_guard<std::mutex> lock(_mutex);
      gst_object_unref(_bus);
      gst_element_set_state(_pipeline, GST_STATE_PAUSED);
      gst_element_set_state(_pipeline, GST_STATE_READY);
      gst_element_set_state(_pipeline, GST_STATE_NULL);
      gst_object_unref(_pipeline);
    }
    catch (std::exception &e)
    {
      cout << e.what();
      return true;
    }
    catch (...)
    {
      return true;
    }
  }
    return true;
}

main.cpp

#include "VideoPusher.h"
int main()
{
    VideoPusher pusher;
    std::string strRtmp = "rtmp://localhost:1945/live/room";
    std::string strRtsp = "rtsp://admin:HuaWei123@59.51.115.31/LiveMedia/ch1/Media1";
    std::string strCode = "h264";
    bool bSuccess = pusher.Run(strRtmp, strCode, strRtsp);
    getchar();
    return 0;
}
相关文章
|
编解码 算法 Ubuntu
Gstreamer 硬解码Rtsp流及代码实现
Gstreamer 硬解码Rtsp流及代码实现
|
安全 网络协议 Shell
渗透测试工具用法技巧入门到进阶
零基础网盘 百度网盘-19****394的分享 新手入门过程 看完 后面有进阶过程 简单工具
491 0
|
缓存 JSON 安全
43 Swift中的一些第三方库
Swift中的一些第三方库
520 0
ffmpeg推流报错Failed to update header with correct duration.
ffmpeg推流报错Failed to update header with correct duration.
1457 0
|
监控 Java Linux
Jetson 学习笔记(十二):CSI摄像头实现rtsp流的传输并对动态获取多路流进行探索
本文是关于如何在Jetson设备上使用CSI摄像头实现RTSP流传输的详细教程,包括安装依赖、编译gst-rtsp-server、测试、源代码介绍以及如何动态获取多路流的RTSP服务器。
1227 2
Jetson 学习笔记(十二):CSI摄像头实现rtsp流的传输并对动态获取多路流进行探索
|
10月前
|
安全 网络安全 虚拟化
Hyper-V网络连接无响应解决方案
当Hyper-V虚拟机出现网络连接无响应时,可从以下方面排查:1) 检查物理网络连接,确保设备正常;2) 验证虚拟网络配置,包括虚拟交换机和网络适配器设置;3) 更新驱动程序以解决兼容性问题;4) 调整防火墙和安全软件设置;5) 重启相关服务和设备;6) 使用命令行工具诊断网络问题;7) 检查BIOS中虚拟化技术是否启用;8) 排查IP冲突和其他日志错误。综合以上步骤,可有效修复网络连接故障。
|
编解码 监控 网络协议
如何用魔法般的步骤实现RTSP推送H.264与H.265(HEVC),打造震撼视听盛宴,让每一帧都充满魔力!
【9月更文挑战第3天】实现RTSP流媒体服务推送H.264和H.265编码视频是现代视频监控及直播平台的关键技术。本文详细介绍环境搭建、编码配置及服务器与客户端实现方法。首先,通过FFmpeg捕获视频并编码成RTSP流,接着使用VLC等工具接收播放。此外,还提供了C++示例代码,演示如何利用libv4l2和FFmpeg自定义服务器端实现。希望本文能帮助读者成功搭建RTSP视频流系统。
2552 1
|
C++
深度解析roc曲线、AUC与排序损失
深度解析roc曲线、AUC与排序损失
541 0
|
消息中间件 Linux
centos7 yum快速安装rabbitmq服务
centos7 yum快速安装rabbitmq服务
456 0
|
编解码 算法 计算机视觉
轻松掌握FFmpeg编程:从架构到实践
轻松掌握FFmpeg编程:从架构到实践
2031 1