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

基于Live555實(shí)現(xiàn)RTSP服務(wù)器來推送H264實(shí)時(shí)碼流

這篇具有很好參考價(jià)值的文章主要介紹了基于Live555實(shí)現(xiàn)RTSP服務(wù)器來推送H264實(shí)時(shí)碼流。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

實(shí)現(xiàn)了一個單播的rtsp服務(wù)器來推送實(shí)時(shí)的h264碼流,參考了官方的testProgs目錄下的testOnDemandRTSPServer例程和liveMedia目錄下的DeviceSource.cpp文件。我這邊是把編碼出來的h264碼流放入了一個緩沖隊(duì)列,然后從緩沖隊(duì)列里取出來進(jìn)行推流。

rtsp.h:

#ifndef _RTSP_H_
#define _RTSP_H_

#include "liveMedia.hh"
#include "BasicUsageEnvironment.hh"

void create_rtsp_server(void);

class H264LiveServerMediaSession : public OnDemandServerMediaSubsession
{
public:
    static H264LiveServerMediaSession *createNew(UsageEnvironment &env, Boolean reuseFirstSource);
    void checkForAuxSDPLine1();
    void afterPlayingDummy1();

protected:
    H264LiveServerMediaSession(UsageEnvironment &env, Boolean reuseFirstSource);
    virtual ~H264LiveServerMediaSession(void);
    void setDoneFlag() { fDoneFlag = ~0; }

protected:
    virtual char const *getAuxSDPLine(RTPSink *rtpSink, FramedSource *inputSource);
    virtual FramedSource *createNewStreamSource(unsigned clientSessionId, unsigned &estBitrate);
    virtual RTPSink *createNewRTPSink(Groupsock *rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource *inputSource);

private:
    char *fAuxSDPLine;
    char fDoneFlag;
    RTPSink *fDummyRTPSink;
};

// 創(chuàng)建一個自定義的實(shí)時(shí)碼流數(shù)據(jù)源類
class H264VideoStreamSource : public FramedSource
{
public:
    static H264VideoStreamSource *createNew(UsageEnvironment &env);
    unsigned maxFrameSize() const;

protected:
    H264VideoStreamSource(UsageEnvironment &env);
    virtual ~H264VideoStreamSource();

private:
    virtual void doGetNextFrame();
    virtual void doStopGettingFrames();
};

#endif // _RTSP_H_

rtsp.cpp:
?文章來源地址http://www.zghlxwxcb.cn/news/detail-743881.html

#include <iostream>
#include "rtsp.h"
#include "ringQueue.h"

extern ringQueue *rQueue;

void create_rtsp_server(void)
{
    TaskScheduler *scheduler;
    UsageEnvironment *env;
    RTSPServer *rtspServer;

    scheduler = BasicTaskScheduler::createNew();
    env = BasicUsageEnvironment::createNew(*scheduler);
    rtspServer = RTSPServer::createNew(*env, 8554);
    if (rtspServer == NULL)
    {
        *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
        return;
    }

    ServerMediaSession *sms = ServerMediaSession::createNew(*env);
    sms->addSubsession(H264LiveServerMediaSession::createNew(*env, true));
    rtspServer->addServerMediaSession(sms);
    char *url = rtspServer->rtspURL(sms);
    *env << "Play the stream using url " << url << "\n";
    delete[] url;
    env->taskScheduler().doEventLoop(); // 進(jìn)入事件循環(huán)
}

// H264LiveServerMediaSession 實(shí)現(xiàn):
H264LiveServerMediaSession *H264LiveServerMediaSession::createNew(UsageEnvironment &env, Boolean reuseFirstSource)
{
    return new H264LiveServerMediaSession(env, reuseFirstSource);
}

H264LiveServerMediaSession::H264LiveServerMediaSession(UsageEnvironment &env, Boolean reuseFirstSource) : OnDemandServerMediaSubsession(env, reuseFirstSource)
{
    fAuxSDPLine = NULL;
    fDoneFlag = 0;
    fDummyRTPSink = NULL;
}

H264LiveServerMediaSession::~H264LiveServerMediaSession()
{
    delete[] fAuxSDPLine;
}

static void afterPlayingDummy(void *clientData)
{
    H264LiveServerMediaSession *subsess = (H264LiveServerMediaSession *)clientData;
    subsess->afterPlayingDummy1();
}

void H264LiveServerMediaSession::afterPlayingDummy1()
{
    envir().taskScheduler().unscheduleDelayedTask(nextTask());
    setDoneFlag();
}

static void checkForAuxSDPLine(void *clientData)
{
    H264LiveServerMediaSession *subsess = (H264LiveServerMediaSession *)clientData;
    subsess->checkForAuxSDPLine1();
}

void H264LiveServerMediaSession::checkForAuxSDPLine1()
{
    nextTask() = NULL;

    char const *dasl;
    if (fAuxSDPLine != NULL)
    {
        setDoneFlag();
    }
    else if (fDummyRTPSink != NULL && (dasl = fDummyRTPSink->auxSDPLine()) != NULL)
    {
        fAuxSDPLine = strDup(dasl);
        fDummyRTPSink = NULL;
        setDoneFlag();
    }
    else if (!fDoneFlag)
    {
        // try again after a brief delay:
        int uSecsToDelay = 100000; // 100 ms
        nextTask() = envir().taskScheduler().scheduleDelayedTask(uSecsToDelay,
                                                                 (TaskFunc *)checkForAuxSDPLine, this);
    }
}

char const *H264LiveServerMediaSession::getAuxSDPLine(RTPSink *rtpSink, FramedSource *inputSource)
{
    if (fAuxSDPLine != NULL)
    {
        return fAuxSDPLine;
    }

    if (fDummyRTPSink == NULL)
    {
        fDummyRTPSink = rtpSink;
        fDummyRTPSink->startPlaying(*inputSource, afterPlayingDummy, this);
        checkForAuxSDPLine(this);
    }
    envir().taskScheduler().doEventLoop(&fDoneFlag);

    return fAuxSDPLine;
}

FramedSource *H264LiveServerMediaSession::createNewStreamSource(unsigned clientSessionId, unsigned &estBitrate)
{
    estBitrate = 5000; // kbps, estimate

    H264VideoStreamSource *videoSource = H264VideoStreamSource::createNew(envir());
    if (videoSource == NULL)
    {
        return NULL;
    }

    return H264VideoStreamFramer::createNew(envir(), videoSource);
}

RTPSink *H264LiveServerMediaSession ::createNewRTPSink(Groupsock *rtpGroupsock,
                                                       unsigned char rtpPayloadTypeIfDynamic,
                                                       FramedSource *inputSource)
{
    // OutPacketBuffer::maxSize = 2000000;
    return H264VideoRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic);
}

// H264VideoStreamSource 實(shí)現(xiàn):
H264VideoStreamSource *H264VideoStreamSource::createNew(UsageEnvironment &env)
{
    return new H264VideoStreamSource(env);
}

H264VideoStreamSource::H264VideoStreamSource(UsageEnvironment &env) : FramedSource(env)
{
}

H264VideoStreamSource::~H264VideoStreamSource()
{
}

unsigned  int H264VideoStreamSource::maxFrameSize() const
{
    return 100000; // 設(shè)置fMaxSize的值
}

void H264VideoStreamSource::doGetNextFrame()
{
    rQueue_data e;
    uint32_t timestamp = 0;
    static uint8_t buffer_data[1024 * 512] = {0};

    // 還沒準(zhǔn)備好要數(shù)據(jù)
    if (!isCurrentlyAwaitingData())
    {
        std::cout << "isCurrentlyAwaitingData" << std::endl;
        return;
    }

    // 從隊(duì)列中取出數(shù)據(jù)
    e.buffer = buffer_data;
    e.len = sizeof(buffer_data);
    if(rQueue_de(rQueue, &e) == -1)
    {
        FramedSource::afterGetting(this);
        return;
    }

    if (e.len > fMaxSize)
    {
        fFrameSize = fMaxSize;
        fNumTruncatedBytes = e.len - fMaxSize;
    }
    else
    {
        fFrameSize = e.len;
    }
    gettimeofday(&fPresentationTime, NULL);
    memcpy(fTo, buffer_data, fFrameSize);
    FramedSource::afterGetting(this);
}

void H264VideoStreamSource::doStopGettingFrames()
{
    std::cout << "doStopGettingFrames" << std::endl;
}

到了這里,關(guān)于基于Live555實(shí)現(xiàn)RTSP服務(wù)器來推送H264實(shí)時(shí)碼流的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 從0-1一起學(xué)習(xí)live555設(shè)計(jì)思想之二 RTSP交互過程

    從0-1一起學(xué)習(xí)live555設(shè)計(jì)思想之二 RTSP交互過程

    本篇文章通過代碼去分析rtsp交互過程與工作原理。由于live555的繼承關(guān)系太過復(fù)雜,所以做了個圖簡單記錄一下與h264文件傳輸相關(guān)的類繼承關(guān)系。 OPTION比較簡單,就是客戶端向服務(wù)端請求可用的方法。服務(wù)端收到客戶端發(fā)來的OPTION指令后,調(diào)用函數(shù)handleCmd_OPTIONS

    2024年02月12日
    瀏覽(17)
  • Android平臺Unity下如何通過WebCamTexture采集攝像頭數(shù)據(jù)并推送至RTMP服務(wù)器或輕量級RTSP服務(wù)

    Android平臺Unity下如何通過WebCamTexture采集攝像頭數(shù)據(jù)并推送至RTMP服務(wù)器或輕量級RTSP服務(wù)

    我們在對接Unity下推送模塊的時(shí)候,遇到這樣的技術(shù)訴求,開發(fā)者希望在Android的Unity場景下,獲取到前后攝像頭的數(shù)據(jù),并投遞到RTMP服務(wù)器,實(shí)現(xiàn)低延遲的數(shù)據(jù)采集處理。 在此之前,我們已經(jīng)有了非常成熟的RTMP推送模塊,也實(shí)現(xiàn)了Android平臺Unity環(huán)境下的Camera場景采集,針對

    2024年01月21日
    瀏覽(87)
  • rk3588/rk356x/rv1109/rv1126 live555移植+mpp編譯 rtsp拉流

    rk3588/rk356x/rv1109/rv1126 live555移植+mpp編譯 rtsp拉流

    本文主要是為了記錄一下rk板子的踩坑日記。 項(xiàng)目主要是rk3588 rtsp拉流。 1.下載MPP源碼:https://github.com/rockchip-linux/mpp 2.rk3588/rk356x的板子進(jìn)入Mpp源碼目錄 mpp/build/linux/aarch64 (rk3588/rk356x是64位板子)中,修改 arm.linux.cross.cmake 文件中的配置 修改 make-Makefiles.bash 的配置,主要改

    2023年04月19日
    瀏覽(41)
  • zlmediakit實(shí)現(xiàn)rtsp流服務(wù)器

    zlmediakit實(shí)現(xiàn)rtsp流服務(wù)器

    本次實(shí)現(xiàn)是將內(nèi)存中的H264數(shù)據(jù)經(jīng)過zlmediakit實(shí)現(xiàn)為rtsp流。 我是用的是CAPI的方式,將zlmediakit作為一個sdk嵌入到自己的程序中而不是作為一個獨(dú)立的進(jìn)進(jìn)程服務(wù)。 1.編譯完成zkmedialit后會得到bin include lib三個文件夾如圖 其中bin中的MediaServer是作為獨(dú)立的進(jìn)程使用的zlmediakit服務(wù),

    2024年02月02日
    瀏覽(14)
  • 從零開始寫一個RTSP服務(wù)器(二)RTSP協(xié)議的實(shí)現(xiàn)

    此系列只追求精簡,旨在學(xué)習(xí)RTSP協(xié)議的實(shí)現(xiàn)過程,不追求復(fù)雜完美,所以這里要實(shí)現(xiàn)的RTSP服務(wù)器為了簡單,實(shí)現(xiàn)上同一時(shí)間只能有一個客戶端,下面開始介紹實(shí)現(xiàn)過程 在寫一個RTSP服務(wù)器之前,我們必須知道一個RTSP服務(wù)器最簡單的包含兩部分,一部分是RTSP的交互,一部分是

    2024年04月17日
    瀏覽(24)
  • RTSP 和 RTMP通過ffmpeg實(shí)現(xiàn)將本地?cái)z像頭推流到RTSP服務(wù)器

    RTSP 和 RTMP通過ffmpeg實(shí)現(xiàn)將本地?cái)z像頭推流到RTSP服務(wù)器

    一、流媒體:RTSP 和RTMP 1、RTSP 和 RTMP的工作原理 1)RTSP工作原理 用戶設(shè)備向視頻流平臺發(fā)送 RTSP 請求 視頻流平臺返回可以操作的請求列表,比如播放、暫停等 用戶設(shè)備向視頻流平臺發(fā)送具體的請求,比如播放 視頻流平臺解析請求并調(diào)用指定機(jī)制啟動視頻流處理 由于 RTSP 依

    2024年02月05日
    瀏覽(25)
  • RTSP 和 RTMP原理 & 通過ffmpeg實(shí)現(xiàn)將本地?cái)z像頭推流到RTSP服務(wù)器

    RTSP 和 RTMP原理 & 通過ffmpeg實(shí)現(xiàn)將本地?cái)z像頭推流到RTSP服務(wù)器

    0、參考資料 秒懂流媒體協(xié)議 RTMP 與 RTSP 什么是RTMP 和 RTSP?它們之間有什么區(qū)別? RTSP和RTMP的區(qū)別是什么? 1、RTSP 和 RTMP的工作原理 1)RTSP工作原理 用戶設(shè)備向視頻流平臺發(fā)送 RTSP 請求 視頻流平臺返回可以操作的請求列表,比如 播放、暫停 等 用戶設(shè)備向視頻流平臺發(fā)送具

    2024年02月08日
    瀏覽(26)
  • Android 內(nèi)置RTSP/RTMP服務(wù)器,實(shí)現(xiàn)局域網(wǎng)內(nèi)視頻推流與播放

    工作中有一個需求,在同一個局域網(wǎng)內(nèi), 需要將Android平板端(車機(jī))上的攝像頭上的畫面,實(shí)時(shí)傳輸?shù)绞謾C(jī)上進(jìn)行播放。 對于這個需求,我們想到了用 RTSP/RTMP 進(jìn)行推流,然后在手機(jī)端拉流進(jìn)行播放。 這個技術(shù)方案的主要技術(shù)點(diǎn)有 平板端內(nèi)置 RTSP/RTMP 服務(wù)器 平板端獲取攝像頭

    2023年04月27日
    瀏覽(80)
  • Monibucav4(開源流媒體服務(wù)器)在Windows上搭建rtmp服務(wù)器并實(shí)現(xiàn)拉取rtsp視頻流以及轉(zhuǎn)換flv播放

    Monibucav4(開源流媒體服務(wù)器)在Windows上搭建rtmp服務(wù)器并實(shí)現(xiàn)拉取rtsp視頻流以及轉(zhuǎn)換flv播放

    開源流媒體服務(wù)器ZLMediaKit在Windows上運(yùn)行、配置、按需拉流拉取攝像頭rtsp視頻流)并使用http-flv網(wǎng)頁播放: 開源流媒體服務(wù)器ZLMediaKit在Windows上運(yùn)行、配置、按需拉流拉取攝像頭rtsp視頻流)并使用http-flv網(wǎng)頁播放_srs按需拉流_霸道流氓氣質(zhì)的博客-CSDN博客 上面講了ZLMediaKit的使用流

    2024年02月11日
    瀏覽(32)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包