国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

live555推送實時視頻流

這篇具有很好參考價值的文章主要介紹了live555推送實時視頻流。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1,linux 環(huán)境:
官網上下載,下載地址:http://www.live555.com/liveMedia/public/
live555 版本:“2018.12.14”
參考:http://www.live555.com/liveMedia/faq.html 這個FAQ要仔細閱讀。
2,編譯
根據不同的平臺來配置,并生成對應的Makefile
2.1 ARM平臺:
修改交叉編譯工具
cp config.armlinux config.arm
vi config.arm
CROSS_COMPILE?= arm-buildroot-linux-uclibcgnueabi-
生成Makefile: ./genMakefiles arm
2.2 Linux 64位平臺(x86-64 ):
./genMakefiles linux-64bit
2.3 Linux 32位平臺(x86):
./genMakefiles linux
make

生成mediaServer/live555MediaServer

3,測試
3.1,mediaServer下 會生成 live555MediaServer。
live555MediaServer test.264
如果出現Correct this by increasing “OutPacketBuffer::maxSize” to at least 186818, before creating this ‘RTPSink’. (Current value is 100000.)
在DynamicRTSPServer.cpp文件ServerMediaSession* createNewSMS()
里修改OutPacketBuffer::maxSize

if (strcmp(extension, ".264") == 0) {
? ? // Assumed to be a H.264 Video Elementary Stream file:
? ? NEW_SMS("H.264 Video");
? ? OutPacketBuffer::maxSize = 300000; //100000;// allow for some possibly large H.264 frames
? ? sms->addSubsession(H264VideoFileServerMediaSubsession::createNew(env, fileName, reuseSource));
? }


createNewSMS是在RTSP setup時調用的。
3.2,testProgs
testProgs 目錄下各種測試文件,每個文件的作用和用法,官網上有詳細的介紹。這些測試用例目前基本上都是以文件的形式作為輸入源,下面重點介紹以實時流的形式作為輸入源的2種方法。
主要是參考testH264VideoStreamer 和testOnDemandRTSPServer來修改。

4.不用讀文件,使用實時視頻流作為輸入源

最簡單的方法:將實時視頻流推送到一個FIFO管道(或stdin),將文件名改為這個管道的文件名,這里不做詳細介紹了。管道一次寫數據4096。

4.1 ?方法1,rtsp_server_main.cpp

#include <liveMedia.hh>
#include <BasicUsageEnvironment.hh>
#include <GroupsockHelper.hh>
#include <rtsp_stream.h>

#include "LiveServerMediaSubsession.h"

#include <pthread.h>
#include "rtsp_server.h"


using namespace KHJ;

UsageEnvironment* env;

#ifdef RTSP_H265_SUPPORT
H265VideoStreamFramer* videoSource = NULL;
#else
H264VideoStreamFramer* videoSource = NULL;
#endif

RTPSink* videoSink;

pthread_t rtsp_server_thread_id;

void play(); // forward

void * rtsp_server_thread(void *) 
{
	// Begin by setting up our usage environment:
	TaskScheduler* scheduler = BasicTaskScheduler::createNew();
	env = BasicUsageEnvironment::createNew(*scheduler);

	OutPacketBuffer::maxSize = 512 * 1024;
	RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554);
	if (rtspServer == NULL) {
		*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
		exit(1);
	}
	
	
	ServerMediaSession* sms = ServerMediaSession::createNew(*env, "stream", "", 
												"Session streamed by \"testVideoStreamer\"", True);
												
	sms->addSubsession(KHJ::LiveServerMediaSubsession::createNew(*env));
	rtspServer->addServerMediaSession(sms);

	char* url = rtspServer->rtspURL(sms);
	*env << "Play this stream using the URL \"" << url << "\"\n";
	delete[] url;

	*env << "Beginning streaming...\n";
	//play();
	
	if (rtspServer->setUpTunnelingOverHTTP(80) || rtspServer->setUpTunnelingOverHTTP(8000) || rtspServer->setUpTunnelingOverHTTP(8080)) {
		*env << "(We use port " << rtspServer->httpServerPortNum() << " for optional RTSP-over-HTTP tunneling, or for HTTP live streaming (for indexed Transport Stream files only).)\n";
	} else {
		*env << "(RTSP-over-HTTP tunneling is not available.)\n";
	}

	env->taskScheduler().doEventLoop(); 


}

void afterPlaying(void* /*clientData*/) {
	*env << "...done reading from file\n";
	videoSink->stopPlaying();
	if (videoSource)
	Medium::close(videoSource);
	play();
}

void play() 
{
	H265Source *fileSource = H265Source::createNew(*env);

	FramedSource* videoES = fileSource;

	#ifdef RTSP_H265_SUPPORT
	videoSource = H265VideoStreamFramer::createNew(*env, videoES);
	#else
	videoSource = H264VideoStreamFramer::createNew(*env, videoES);
	#endif

	// Finally, start playing:
	*env << "Beginning to read from file...\n";
	videoSink->startPlaying(*videoSource, afterPlaying, videoSink);
}


int rtsp_server_start()
{
    int ret = 0;

    if((ret = pthread_create(&rtsp_server_thread_id, NULL, rtsp_server_thread, NULL)) <0 )
    {
        printf("create rtsp_server_thread fail\n");
    }

    return ret;
}

int rtsp_server_stop()
{
//    delete env;
//    delete videoSource;
    return 0;
}

#if 0
int main()
{
    rtsp_server_start();
    getchar();
}
#endif



4.2 方法2,參考testOnDemandRTSPServer
1)set the variable “reuseFirstSource” to “True”
2)根據類H264VideoFileServerMediaSubsession,新建一個新類H264LiveVideoServerMediaSubsession, implementation of the two pure virtual functions “createNewStreamSource()” and “createNewRTPSink()”
在createNewStreamSource()里用上面的H264LiveVideoSource代替ByteStreamFileSource。

H264VideoRTPSink繼承關系:
H264VideoRTPSink->H264or5VideoRTPSink->VideoRTPSink->MultiFramedRTPSink->RTPSink->MediaSink->Medium。
H264VideoRTPSource繼承關系:
H264VideoRTPSource->MultiFramedRTPSource->RTPSource->FramedSource->MediaSource->Medium.
H264VideoStreamFramer繼承關系:
H264VideoStreamFramer->H264or5VideoStreamFramer->MPEGVideoStreamFramer->FramedFilter->FramedSource ->MediaSource->Medium.

下面列出具體實現


h265source.h

#ifndef MESAI_H265_SOURCE_HH
#define MESAI_H265_SOURCE_HH

#include <FramedSource.hh>
#include <UsageEnvironment.hh>
#include <Groupsock.hh>

namespace RTSP_DEMO
{
    
  class H265Source : public FramedSource {
  public:
    static H265Source* createNew(UsageEnvironment& env);
    ~H265Source();

  private:
    H265Source(UsageEnvironment& env);
    virtual void doGetNextFrame();
    virtual void doStopGettingFrames();
    
  private:
    int fp;

  };

}

#endif



h265source.cpp文件如下:

static int sfp[MAX_CLIENT_NUM] = {-1, -1, -1, -1};

namespace RTSP_DEMO
{
    H265Source * H265Source::createNew(UsageEnvironment& env) {
		return new H265Source(env);
	}

	H265Source::H265Source(UsageEnvironment& env) : FramedSource(env)
	{
        printf("%s--->%d\n", __FUNCTION__, __LINE__);

        int i=0;

        fp = -1;
        for(i=0; i<MAX_CLIENT_NUM; i++)
        {
            if(sfp[i] == -1)
            {
                fp = i;
                sfp[i] = fp;
                break;
            }
        }

        if(fp<0)
        {
            return;
        }

        memset(&client_frame_info[fp], 0, sizeof(client_frame_info[fp]));

        printf("%s--->%d, fp is %d\n", __FUNCTION__, __LINE__, fp);
	}

	H265Source::~H265Source()
	{
        printf("%s--->%d, fp is %d\n", __FUNCTION__, __LINE__, fp);

        int i=0;

        for(i=0; i<MAX_CLIENT_NUM; i++)
        {
            if(sfp[i] == fp)
            {
                fp = -1;
                sfp[i] = fp;
                break;
            }
        }

        printf("%s--->%d, fp is %d\n", __FUNCTION__, __LINE__, fp);
	}

	void H265Source::doStopGettingFrames()
	{
        printf("%s--->%d\n", __FUNCTION__, __LINE__);

        return ;
	}


	void H265Source::doGetNextFrame()
	{
		if (!isCurrentlyAwaitingData()) return;
		
		int ret = 0;
		int len = 10 * 1024;

//        printf("fMaxSize is %d\n", fMaxSize);
		
		if (len > fMaxSize)
			len = fMaxSize;
		
		gettimeofday(&fPresentationTime, NULL);
		
		
		fNumTruncatedBytes = 0;
	agin:

         if((ret = read_packet(fp, fTo, len)) > 0){
             fFrameSize = ret;
         }else{
            fFrameSize = 0;
         }
		
		if(fFrameSize>0)
			FramedSource::afterGetting(this);
		
	}
	
}


linve555常用修改點:

1, 輸入的一幀數據最大值
StreamParser.cpp
#define BANK_SIZE 1500000 //幀越大,這個值就要越大

2, rtp buffer最大值
(1)Source端使用 MultiFramedRTPSource.cpp
BufferedPacket::BufferedPacket()
定義輸入Buffer的上限值,即BufferedPacket的最大值
#define MAX_PACKET_SIZE 65536
(2)Sink端使用 MultiFramedRTPSink.cpp
#define RTP_PAYLOAD_MAX_SIZE 1456 //(1500-14-20-8)/4 *4 //ethernet=14,IP=20, UDP=8, a multiple of 4 bytes
MediaSink.cpp
靜態(tài)變量OutPacketBuffer::maxSize = 600000; // allow for some possibly large H.265 frames,2000000 is by default
最好是RTP_PAYLOAD_MAX_SIZE的整數倍
值小了,會不斷打印信息: Correct this by increasing “OutPacketBuffer::maxSize” to at least

,3,獲取IP地址失敗
RTSPServer::rtspURLPrefix(){
ourIPAddress(envir())
}

GroupsockHelper.cpp

?ourIPAddress()
?{
?? ?if (badAddressForUs(from)) {
?? ? ?#if 0
? ? ? char tmp[100];
? ? ? sprintf(tmp, "This computer has an invalid IP address: %s", AddressString(from).val());
? ? ? env.setResultMsg(tmp);
? ? ? from = 0;
?? ? ?#endif
?? ? ?struct ifreq req;
?? ? ?int ret = 0;
?? ? ?char szIpBuf[32];

?? ? ?sock = socket(AF_INET, SOCK_DGRAM, 0);
?? ? ?if (-1 != sock)
?? ? ?{
?? ??? ? ?memset(&req, 0, sizeof(req));
?? ??? ? ?strncpy(req.ifr_name, "eth0", sizeof(req.ifr_name));
?? ??? ? ?ret = ioctl(sock, SIOCGIFADDR, &req);
?? ??? ? ?if (-1 == ret)
?? ??? ? ?{
?? ??? ??? ?close(sock);
?? ??? ? ?}
?? ??? ? ?else
?? ??? ? ??? ?{
?? ??? ? ??? ? memset(&szIpBuf, 0, sizeof(szIpBuf));
?? ??? ? ? ? strcpy(szIpBuf, inet_ntoa(((struct sockaddr_in *)&req.ifr_addr)->sin_addr));
?? ??? ? ? ?close(sock);
?? ??? ? ? ?fromAddr.sin_addr.s_addr=our_inet_addr(szIpBuf);
?? ??? ??? ?from = fromAddr.sin_addr.s_addr;
?? ??? ? ??? ?}
?? ? ?}
?? ? ?else
? ?? ? ?{
? ?? ? ??? ? char tmp[100];
? ? ? ? ?sprintf(tmp, "This computer has an invalid IP address: %s", AddressString(from).val());
? ? ? ? ?env.setResultMsg(tmp);
? ? ? ? ?from = 0;
? ?? ? ?}
?}


3,內存泄漏點
RTCPInstance::processIncomingReport
if(NULL != reason)
{
delete[] reason;
reason = NULL;
}
在申請內存時加上上面釋放語句
reason = new char[reasonLength + 1];
4,fill sei data DeltaTfiDivisor

H264or5VideoStreamParser::H264or5VideoStreamParser()
{
    //according to H264 and H265 spec, if not fill sei data, then         
frame_field_info_present_flag is zero. so need to set DeltaTfiDivisor to 2.0 in H264 and                         1.0 in H265
    if(fHNumber == 264) {
    DeltaTfiDivisor = 2.0;
    } else {
    DeltaTfiDivisor = 1.0;
    }
}


5,長時間拉取拉取RTSP流
報錯誤"Hit limit when reading incoming packet over TCP"
可考慮提高maxRTCPPacketSize的值
RTCP.CPP
static unsigned const maxRTCPPacketSize = 1456;

6,如播放越久延時越大
MultiFramedRTPSink.cpp->MultiFramedRTPSink::sendPacketIfNecessary() 最后延時列隊uSecondsToGo 每幀都有延時時間。將uSecondsToGo 值賦為0。

7, 裁剪

只需留下這些目錄(BasicUsageEnvironment、groupsock、liveMedia、mediaServer、UsageEnvironment),其它可刪除掉。
其中l(wèi)iveMedia目錄下有很多類型的文件,不需要的也可刪除,同時修改
MediaSubsession::createSourceObjects()把相關類型的createNew也刪除掉,否則編譯失敗。文章來源地址http://www.zghlxwxcb.cn/news/detail-401971.html

到了這里,關于live555推送實時視頻流的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • OpenCV獲取網絡攝像頭實時視頻流

    參考文章: [常用工具] OpenCV獲取網絡攝像頭實時視頻流_opencv網絡攝像頭 [常用工具] OpenCV獲取網絡攝像頭實時視頻流_opencv網絡攝像頭_落痕的寒假的博客-CSDN博客 在使用OpenCv處理視頻時,無論是視頻文件還是攝像頭畫面,都要使用VideoCapture類來進行每一幀圖像的處理。當我們

    2024年02月01日
    瀏覽(101)
  • 設計一個像ESPN一樣的實時視頻流系統(tǒng)

    設計一個像ESPN一樣的實時視頻流系統(tǒng)

    功能需求 ?直播事件與流之間的最大延遲不超過1分鐘?系統(tǒng)應能夠適應大量用戶(異構交付)?系統(tǒng)應能將視頻轉換為不同的分辨率和編解碼器?系統(tǒng)應具備容錯性 視頻轉換和接收 由于我們正在實時直播整個事件,因此我們不能等待整個視頻結束后再開始將其轉換為不同的

    2024年02月07日
    瀏覽(15)
  • 安防監(jiān)控項目---mjpeg-streamer視頻圖像顯示(實時視頻流實現)

    安防監(jiān)控項目---mjpeg-streamer視頻圖像顯示(實時視頻流實現)

    書接上期,我們已經實現了許多功能了,但是對于視頻流的實時上傳還未實現,本期主要分享的就是如何具體實現網頁實時顯示攝像頭采集到的視頻,從而實現安防中監(jiān)控的功能,這個功能完成后呢,就只剩下一個功能需求了,那就是GPRS模塊,能夠實現危險報警的功能,也能

    2024年02月06日
    瀏覽(26)
  • 【精選】基于OpenCV的實時視頻流車牌識別(源碼&教程)

    【精選】基于OpenCV的實時視頻流車牌識別(源碼&教程)

    近年來,智能交通系統(tǒng)(ITS)在我國應用日益廣泛。作為ITS重要組成部分的自動車牌識別系統(tǒng)在交通流量檢測、交通誘導控制、違章車輛監(jiān)控等方面有著廣泛的應用,是確保道路安全暢通的重要手段,也為統(tǒng)計有關資料,為管理者決策提供有效數字依據的重要途徑。由于一般的識別系

    2024年01月23日
    瀏覽(94)
  • FFmpeg+SDL實時解碼和渲染H264視頻流

    之前實現了Android手機攝像頭數據的TCP實時傳輸,今天接著聊聊,如何在PC端把接收到的H264視頻流實時解碼并渲染出來。這次使用的語言是C++,框架有FFmpeg和SDL2。 解碼部分使用FFmpeg,首先,需要初始化H264解碼器: 然后,使用創(chuàng)建TCP連接到我們的Android端,讀取數據包: 再把每

    2024年02月13日
    瀏覽(28)
  • Qt推流程序自動生成網頁遠程查看實時視頻流(視頻文件/視頻流/攝像頭/桌面轉成流媒體rtmp+hls+webrtc)

    Qt推流程序自動生成網頁遠程查看實時視頻流(視頻文件/視頻流/攝像頭/桌面轉成流媒體rtmp+hls+webrtc)

    推流程序將視頻流推送到流媒體服務器后,此時就等待驗證拉流播放,一般可以選擇ffplay命令行播放或者vlc等播放器打開播放,也可以選擇網頁直接打開拉流地址播放,一般主流的瀏覽器都支持網頁直接播放hls/m3u8/webrtc類型的視頻流,而且推流的主要目的可能就是為了能夠在

    2024年02月05日
    瀏覽(104)
  • [chatGPT] 如何通過JNI在Android上顯示實時視頻流

    [chatGPT] 如何通過JNI在Android上顯示實時視頻流

    相機拍攝的畫面通過local socket 獲取,所以C++的代碼可以輕易的獲取到每一幀視頻數據,需要通過JNI 讓 Android顯示出來,方法有兩種,一種是在Android內創(chuàng)建回調函數使用Bitmap 和ImageView 進行賦值顯示,另一種也就是ChatGPT完成的,Android將surface 傳遞到JNI層內,C++來完成賦值和渲

    2023年04月26日
    瀏覽(19)
  • 基于OpenCv+Django的網絡實時視頻流傳輸(前后端分離)

    基于OpenCv+Django的網絡實時視頻流傳輸(前后端分離)

    秋風閣——北溪入江流:https://focus-wind.com/ 秋風閣——基于OpenCv+Django的網絡實時視頻流傳輸(前后端分離) 使用OpenCv捕獲攝像機畫面后,我們有時候需要將畫面顯示在界面上。本博客基于Django的前后端分離模式,將視頻流從后端讀取,傳送給前端顯示。 在使用Django進行視頻

    2024年02月08日
    瀏覽(93)
  • VUE3 播放RTSP實時、回放(NVR錄像機)視頻流(使用WebRTC)

    VUE3 播放RTSP實時、回放(NVR錄像機)視頻流(使用WebRTC)

    1、下載webrtc-streamer,下載的最新window版本 Releases · mpromonet/webrtc-streamer · GitHub ?2、解壓下載包 ?3、webrtc-streamer.exe啟動服務 (注意:這里可以通過當前文件夾下用cmd命令webrtc-streamer.exe -o這樣占用cpu會很少,直接雙擊exe文件會占用cpu) cmd? webrtc-streamer.exe -o 啟動如下圖所示,

    2024年04月12日
    瀏覽(23)
  • Docker RTMP服務器搭建與視頻流推送示例(流媒體服務器tiangolo/nginx-rtmp,推流客戶端ffmpeg)

    Docker RTMP服務器搭建與視頻流推送示例(流媒體服務器tiangolo/nginx-rtmp,推流客戶端ffmpeg)

    在這篇文章中,我將詳述如何搭建一個RTMP(Real-Time Messaging Protocol)服務器,并使用ffmpeg技術進行本地視頻的推流。最后,我們將使用VLC播放器來播放這個RTMP流。 首先,我們需要搭建一個RTMP服務器。為了方便起見,我們將選擇Docker作為服務器的環(huán)境。Docker的輕量化和可移植

    2024年01月17日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包