基于Live555实现数据流的推送

这篇具有很好参考价值的文章主要介绍了基于Live555实现数据流的推送。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

总述

Live555是使用c++编写的RTSP开源库,以文件为载体进行推流,其中实现了多种类型的音频以及视频的流化。

简述RTSP

RTSP是一种媒体传输协议,基于TCP协议,主要功能为媒体播放的控制以及开始连接时的握手操作。时间流传输走的时RTP协议,流传输控制协议走的是RTCP,RTP和RTCP具体使用TCP还是UDP,有RTSP SETUP阶段根据客户端选择而定。

实现自定义数据流传输

首先实现一个比较通用的MediaSubsession,继承OnDemandServerMediaSubsession

class ComMediaSubsession:public OnDemandServerMediaSubsession 
{
	public:
		static ComMediaSubsession* createNew(UsageEnvironment& env, int streamType, int videoType, int channelNO, 
				bool reuseFirstSource, portNumBits initalNumPort = 6970);
	protected:
		ComMediaSubsession(UsageEnvironment& env, int streamType, int videoType, int channelNO, 
				bool reuseFirstSource, portNumBits initalNumPort);
		~ComMediaSubsession();
		
	protected:
		// virtual function  new source and rtplink
		FramedSource* createNewStreamSource(unsigned clientsessionId, unsigned& estBitrate);
		RTPSink* createNewRTPSink(Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource* inputSource);
	
	public:
		int fStreamType;
		int fVideoType;
		int fChannelNO;
		
};
#include "ComMediaSubsession.h"
#include "ComFrameSource.h"
#include "H264VideoStreamFramer.hh"
#include "H264VideoRTPSink.hh"
#include "MP3ADURTPSink.hh"
#include "MPEG1or2AudioRTPSink.hh"


ComMediaSubsession::ComMediaSubsession(UsageEnvironment& env, int streamType, int videoType, int channelNO, bool reuseFirstSource, portNumBits initalNumPort)
	:OnDemandServerMediaSubsession(env, reuseFirstSource), fStreamType(streamType), fVideoType(videoType), fChannelNO(channelNO)
{
}

ComMediaSubsession::~ComMediaSubsession()
{

}


ComMediaSubsession* DemoH264MediaSubsession::createNew(UsageEnvironment& env, int streamType, int videoType, int channelNO, 
		bool reuseFirstSource, portNumBits initalNumPort)
{
	ComMediaSubsession* sms = new ComMediaSubsession(env, streamType, videoType, channelNO, reuseFirstSource, initalNumPort);
	return sms;
}


FramedSource* ComMediaSubsession::createNewStreamSource(unsigned clientsessionId, unsigned& estBitrate)
{
	if(fVideoType == 0x01)
	{ 
	    // H264 video 
		estBitrate = 2000; // kbps 
		ComFrameSource * source = ComFrameSource::createNew(envir(), fStreamType, fChannelNO, 0);
		if ( source == NULL )
		{
			DBG_LIVE555_PRINT("create source failed videoType:%d!\n", fVideoType );
			return NULL;
		}
		return H264VideoStreamFramer::createNew(envir(), source);
	}
	else if ( fVideoType == 0x2) 
	{   
	    // Mpeg-4 video  
	    estBitrate = 128; // kbps 
		ComFrameSource * source = ComFrameSource::createNew(envir(), fStreamType, fChannelNO, 1);
		if ( source == NULL )
		{
			DBG_LIVE555_PRINT("create source failed videoType:%d!\n", fVideoType );
			return NULL;
		}
		return source;
	}
	return NULL;	
}


RTPSink* ComMediaSubsession::createNewRTPSink(Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource* inputSource)
{
	if( fVideoType == 0x01)
	{
	    // H264 video
		return H264VideoRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic);
		
	}
	else if( fVideoType == 0x02)
	{ 
	    //  Mpeg-4
		return MP3ADURTPSink::createNew(envir(), rtpGroupsock,rtpPayloadTypeIfDynamic);
	}
    return NULL;
}

接着实现数据获取类文章来源地址https://www.toymoban.com/news/detail-523330.html

#include "FramedSource.hh"

class ComFrameSource:public FramedSource 
{
	public:
		static ComFrameSource* createNew(UsageEnvironment& env, int streamtype, int channelno, int sourceType); 
	protected:
		ComFrameSource(UsageEnvironment& env, long sourceHandle, int sourceType);
		~ComFrameSource();
	private:
		virtual void doGetNextFrame();
	public:
		void doStopGetFrame();
	public:
		unsigned fLastBufSize;
		unsigned fLeftDataSize;
		int fSourceType;
		int fFirstFrame;
		
};


#include "ComFrameSource.h"

ComFrameSource::ComFrameSource(UsageEnvironment& env,  int sourceType):
	FramedSource(env), fLastBufSize(0), fLeftDataSize(0), fSourceType(sourceType), fFirstFrame(1)
{
 
}


ComFrameSource::~ComFrameSource()
{ 

}


ComFrameSource* ComFrameSource::createNew(UsageEnvironment& env, int streamType, int channelNO, int sourceType)
{
	
	return new ComFrameSource(env, sourceType);
	
}



void ComFrameSource::doGetNextFrame()
{
	int ret = 0;

    /*实现获取数据到fTo,最大fMaxSize*/
	ret = getStreamData(fSourceHandle, (char *)fTo, fMaxSize);
	if (ret <= 0)
	{
	    fFrameSize = 0;
		nextTask() = envir().taskScheduler().scheduleDelayedTask(10,
				  (TaskFunc*)FramedSource::afterGetting, this);
		return;
	}

	gettimeofday(&fPresentationTime, NULL);
	
	
	// Switch to another task, and inform the reader that he has data:
	nextTask() = envir().taskScheduler().scheduleDelayedTask(10,
				  (TaskFunc*)FramedSource::afterGetting, this);



}

void ComFrameSource::doStopGetFrame()
{

}


到了这里,关于基于Live555实现数据流的推送的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 实时流媒体传输开源库——Live555

    Live555(LiveMedia Libraries)是一个开源的多媒体流处理库,主要用于实现基于标准网络协议的实时流媒体传输。Live555提供了一套 C++ 类库,可以用于开发支持 RTP/RTCP、RTSP、SIP 等协议的流媒体服务器和客户端应用程序。它广泛用于视频监控、视频会议、音视频直播等流媒体传输领

    2024年01月22日
    浏览(47)
  • 探讨下live555用的编程设计模式

    这个应该放到这里 7.live555mediaserver-第1阶段小结(完整对象图和思维导图) https://blog.csdn.net/yhb1206/article/details/127330771 但是想想,还是拿出来吧。 从这第1阶段就能发现,它实质用到了reactor网络编程模式,具体点是 单Reactor服务器模型 。 该文章说的很不错。Reactor模式介绍ht

    2024年02月09日
    浏览(35)
  • Live555 C++ arm linux64 RTSP推流开发

    由于不能apt-get install,所以先官网下载源码。http://www.live555.com/liveMedia/ 解压 tar -zxvf live.2023.07.24.tar.gz 安装可以看这篇博文前部 live555server环境搭建 OpenSSL必须安装 安装时如果直接在arm板子上装,生成makefile时就直接写 不能写成armlinux 如果选成了armlinux,这样make的时候用的就是

    2024年02月03日
    浏览(47)
  • 从0-1一起学习live555设计思想之二 RTSP交互过程

    本篇文章通过代码去分析rtsp交互过程与工作原理。由于live555的继承关系太过复杂,所以做了个图简单记录一下与h264文件传输相关的类继承关系。 OPTION比较简单,就是客户端向服务端请求可用的方法。服务端收到客户端发来的OPTION指令后,调用函数handleCmd_OPTIONS

    2024年02月12日
    浏览(51)
  • 使用Flink实现Kafka到MySQL的数据流转换:一个基于Flink的实践指南

    在现代数据处理架构中,Kafka和MySQL是两种非常流行的技术。Kafka作为一个高吞吐量的分布式消息系统,常用于构建实时数据流管道。而MySQL则是广泛使用的关系型数据库,适用于存储和查询数据。在某些场景下,我们需要将Kafka中的数据实时地写入到MySQL数据库中,本文将介绍

    2024年04月15日
    浏览(53)
  • rk3588/rk356x/rv1109/rv1126 live555移植+mpp编译 rtsp拉流

    本文主要是为了记录一下rk板子的踩坑日记。 项目主要是rk3588 rtsp拉流。 1.下载MPP源码:https://github.com/rockchip-linux/mpp 2.rk3588/rk356x的板子进入Mpp源码目录 mpp/build/linux/aarch64 (rk3588/rk356x是64位板子)中,修改 arm.linux.cross.cmake 文件中的配置 修改 make-Makefiles.bash 的配置,主要改

    2023年04月19日
    浏览(44)
  • 【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割2(基础数据流篇)

    构建 pytorch 训练模型读取的数据,是有模版可以参考的,是有套路的,这点相信使用过的人都知道。我也会给出一个套路的模版,方便学习和查询。 同时,也可以先去参考学习之前的一篇较为简单的 3D 分类任务的数据构建方法,链接在这里:【3D图像分类】基于Pytorch的3D立体

    2024年02月05日
    浏览(54)
  • 软件工程:数据流图,智能汽车代码功能实现(Java)

    简介 开闭原则 软件实现应该对扩展开放,对修改关闭,其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化的 智能汽车中,确定汽车的加速/减速 速度接口 速度实现抽象为父类 速度控制,子类ControlRpm继承抽象父类 如果不使用开闭原则

    2023年04月23日
    浏览(50)
  • 全减器---Verilog实现(结构描述,数据流描述,行为描述,层次结构描述)

    全减器真值表—引用知乎:链接: 全减器真值表怎么理解 代码部分 原理图 代码部分 原理图 代码部分 原理图 代码部分 原理图

    2024年02月12日
    浏览(59)
  • 微信小程序-接入sse数据流并实现打字机效果( ChatGPT )

    从流中获取的数据格式如下 小程序调用SSE接口 我这边接收到的数据类型为Uint8Array,需要处理成text文本(如上图) 使对话有打字机效果 参考自:小程序实现 ChatGPT 聊天打字兼自动滚动效果 完整代码

    2024年04月09日
    浏览(90)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包