基于Qt和ffmpeg的抓屏rtsp服务(一)
生活随笔
收集整理的這篇文章主要介紹了
基于Qt和ffmpeg的抓屏rtsp服务(一)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
章節(jié)目錄
- 實(shí)現(xiàn)一個(gè)基于ffmpeg的rtsp抓屏服務(wù)
- 一、服務(wù)實(shí)現(xiàn)圖
- 1、整體圖
- 2、 采集圖
- 3、 編碼圖
- 4、 傳輸
- 二、各個(gè)模塊簡(jiǎn)要說(shuō)明
- 1、模塊講解
- ① 采集流程
- ② 編碼流程
- ③ 封裝
- ④ 傳輸
- 2、引用參考部分
- 3、總結(jié)
實(shí)現(xiàn)一個(gè)基于ffmpeg的rtsp抓屏服務(wù)
一、服務(wù)實(shí)現(xiàn)圖
1、整體圖
#mermaid-svg-5ePTgh9NEUZdFXwh {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-5ePTgh9NEUZdFXwh .error-icon{fill:#552222;}#mermaid-svg-5ePTgh9NEUZdFXwh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5ePTgh9NEUZdFXwh .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-5ePTgh9NEUZdFXwh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5ePTgh9NEUZdFXwh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5ePTgh9NEUZdFXwh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5ePTgh9NEUZdFXwh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5ePTgh9NEUZdFXwh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5ePTgh9NEUZdFXwh .marker.cross{stroke:#333333;}#mermaid-svg-5ePTgh9NEUZdFXwh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5ePTgh9NEUZdFXwh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5ePTgh9NEUZdFXwh .cluster-label text{fill:#333;}#mermaid-svg-5ePTgh9NEUZdFXwh .cluster-label span{color:#333;}#mermaid-svg-5ePTgh9NEUZdFXwh .label text,#mermaid-svg-5ePTgh9NEUZdFXwh span{fill:#333;color:#333;}#mermaid-svg-5ePTgh9NEUZdFXwh .node rect,#mermaid-svg-5ePTgh9NEUZdFXwh .node circle,#mermaid-svg-5ePTgh9NEUZdFXwh .node ellipse,#mermaid-svg-5ePTgh9NEUZdFXwh .node polygon,#mermaid-svg-5ePTgh9NEUZdFXwh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5ePTgh9NEUZdFXwh .node .label{text-align:center;}#mermaid-svg-5ePTgh9NEUZdFXwh .node.clickable{cursor:pointer;}#mermaid-svg-5ePTgh9NEUZdFXwh .arrowheadPath{fill:#333333;}#mermaid-svg-5ePTgh9NEUZdFXwh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5ePTgh9NEUZdFXwh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5ePTgh9NEUZdFXwh .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-5ePTgh9NEUZdFXwh .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-5ePTgh9NEUZdFXwh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5ePTgh9NEUZdFXwh .cluster text{fill:#333;}#mermaid-svg-5ePTgh9NEUZdFXwh .cluster span{color:#333;}#mermaid-svg-5ePTgh9NEUZdFXwh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5ePTgh9NEUZdFXwh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}YUV420pH264ES采集編碼封裝傳輸 圖12、 采集圖
#mermaid-svg-u7OKM03csDDSAtqR {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-u7OKM03csDDSAtqR .error-icon{fill:#552222;}#mermaid-svg-u7OKM03csDDSAtqR .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-u7OKM03csDDSAtqR .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-u7OKM03csDDSAtqR .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-u7OKM03csDDSAtqR .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-u7OKM03csDDSAtqR .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-u7OKM03csDDSAtqR .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-u7OKM03csDDSAtqR .marker{fill:#333333;stroke:#333333;}#mermaid-svg-u7OKM03csDDSAtqR .marker.cross{stroke:#333333;}#mermaid-svg-u7OKM03csDDSAtqR svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-u7OKM03csDDSAtqR .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-u7OKM03csDDSAtqR .cluster-label text{fill:#333;}#mermaid-svg-u7OKM03csDDSAtqR .cluster-label span{color:#333;}#mermaid-svg-u7OKM03csDDSAtqR .label text,#mermaid-svg-u7OKM03csDDSAtqR span{fill:#333;color:#333;}#mermaid-svg-u7OKM03csDDSAtqR .node rect,#mermaid-svg-u7OKM03csDDSAtqR .node circle,#mermaid-svg-u7OKM03csDDSAtqR .node ellipse,#mermaid-svg-u7OKM03csDDSAtqR .node polygon,#mermaid-svg-u7OKM03csDDSAtqR .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-u7OKM03csDDSAtqR .node .label{text-align:center;}#mermaid-svg-u7OKM03csDDSAtqR .node.clickable{cursor:pointer;}#mermaid-svg-u7OKM03csDDSAtqR .arrowheadPath{fill:#333333;}#mermaid-svg-u7OKM03csDDSAtqR .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-u7OKM03csDDSAtqR .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-u7OKM03csDDSAtqR .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-u7OKM03csDDSAtqR .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-u7OKM03csDDSAtqR .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-u7OKM03csDDSAtqR .cluster text{fill:#333;}#mermaid-svg-u7OKM03csDDSAtqR .cluster span{color:#333;}#mermaid-svg-u7OKM03csDDSAtqR div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-u7OKM03csDDSAtqR :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}yesnoyesnoyesnoyesnoyesyesno開始avdevice_register_allav_dict_set_intav_find_input_format?avformat_alloc_contextavformat_find_stream_info?avcodec_closeavcodec_find_decoder?avformat_parameters_to_contextavcodec_open2?av_read_frame?aavcodec_send_packetavcodec_receive_frameavformat_close_input結(jié)束 圖23、 編碼圖
#mermaid-svg-oLmwnWx9sxHIqSMe {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-oLmwnWx9sxHIqSMe .error-icon{fill:#552222;}#mermaid-svg-oLmwnWx9sxHIqSMe .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oLmwnWx9sxHIqSMe .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-oLmwnWx9sxHIqSMe .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oLmwnWx9sxHIqSMe .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oLmwnWx9sxHIqSMe .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oLmwnWx9sxHIqSMe .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oLmwnWx9sxHIqSMe .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oLmwnWx9sxHIqSMe .marker.cross{stroke:#333333;}#mermaid-svg-oLmwnWx9sxHIqSMe svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oLmwnWx9sxHIqSMe .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-oLmwnWx9sxHIqSMe .cluster-label text{fill:#333;}#mermaid-svg-oLmwnWx9sxHIqSMe .cluster-label span{color:#333;}#mermaid-svg-oLmwnWx9sxHIqSMe .label text,#mermaid-svg-oLmwnWx9sxHIqSMe span{fill:#333;color:#333;}#mermaid-svg-oLmwnWx9sxHIqSMe .node rect,#mermaid-svg-oLmwnWx9sxHIqSMe .node circle,#mermaid-svg-oLmwnWx9sxHIqSMe .node ellipse,#mermaid-svg-oLmwnWx9sxHIqSMe .node polygon,#mermaid-svg-oLmwnWx9sxHIqSMe .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oLmwnWx9sxHIqSMe .node .label{text-align:center;}#mermaid-svg-oLmwnWx9sxHIqSMe .node.clickable{cursor:pointer;}#mermaid-svg-oLmwnWx9sxHIqSMe .arrowheadPath{fill:#333333;}#mermaid-svg-oLmwnWx9sxHIqSMe .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-oLmwnWx9sxHIqSMe .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-oLmwnWx9sxHIqSMe .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-oLmwnWx9sxHIqSMe .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-oLmwnWx9sxHIqSMe .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oLmwnWx9sxHIqSMe .cluster text{fill:#333;}#mermaid-svg-oLmwnWx9sxHIqSMe .cluster span{color:#333;}#mermaid-svg-oLmwnWx9sxHIqSMe div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-oLmwnWx9sxHIqSMe :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}yesnoyes開始av_register_all /avcodec_register_allavcodec_find_encoder_by_name?avcodec_allo_context3sws_freeContextav_opt_setavcodec_open2?sws_scaleavcodec_send_frameavcodec_receive_packetavcodec_closeavcodec_free_context結(jié)束 圖34、 傳輸
#mermaid-svg-yh9qKSntFHQma26x {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-yh9qKSntFHQma26x .error-icon{fill:#552222;}#mermaid-svg-yh9qKSntFHQma26x .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yh9qKSntFHQma26x .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-yh9qKSntFHQma26x .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yh9qKSntFHQma26x .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yh9qKSntFHQma26x .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yh9qKSntFHQma26x .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yh9qKSntFHQma26x .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yh9qKSntFHQma26x .marker.cross{stroke:#333333;}#mermaid-svg-yh9qKSntFHQma26x svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yh9qKSntFHQma26x .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-yh9qKSntFHQma26x text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-yh9qKSntFHQma26x .actor-line{stroke:grey;}#mermaid-svg-yh9qKSntFHQma26x .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-yh9qKSntFHQma26x .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-yh9qKSntFHQma26x #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-yh9qKSntFHQma26x .sequenceNumber{fill:white;}#mermaid-svg-yh9qKSntFHQma26x #sequencenumber{fill:#333;}#mermaid-svg-yh9qKSntFHQma26x #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-yh9qKSntFHQma26x .messageText{fill:#333;stroke:#333;}#mermaid-svg-yh9qKSntFHQma26x .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-yh9qKSntFHQma26x .labelText,#mermaid-svg-yh9qKSntFHQma26x .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-yh9qKSntFHQma26x .loopText,#mermaid-svg-yh9qKSntFHQma26x .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-yh9qKSntFHQma26x .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-yh9qKSntFHQma26x .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-yh9qKSntFHQma26x .noteText,#mermaid-svg-yh9qKSntFHQma26x .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-yh9qKSntFHQma26x .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-yh9qKSntFHQma26x .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-yh9qKSntFHQma26x .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-yh9qKSntFHQma26x .actorPopupMenu{position:absolute;}#mermaid-svg-yh9qKSntFHQma26x .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-yh9qKSntFHQma26x .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-yh9qKSntFHQma26x .actor-man circle,#mermaid-svg-yh9qKSntFHQma26x line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-yh9qKSntFHQma26x :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}采集編碼ES流rtsp服務(wù)用戶③ 采集桌面數(shù)據(jù)④ 編碼,封裝(這里不做封裝,簡(jiǎn)單處理)⑤ 準(zhǔn)備傳輸① 用戶向rtsp服務(wù)請(qǐng)求rtsp流② 通知采集,開始采集,編碼與傳輸⑥ 開始視頻流傳輸采集編碼ES流rtsp服務(wù)用戶 圖4二、各個(gè)模塊簡(jiǎn)要說(shuō)明
1、模塊講解
上面圖1
在上面的1、中,主要是整個(gè)程序的主要流程走向,使用ffmpeg **gdigrab**進(jìn)行采集,ffmpeg中的libx264進(jìn)行編碼,由于直接使用ES流進(jìn)行傳輸。所以,封裝這層先不做過(guò)多的處理。傳輸,是網(wǎng)絡(luò)上找的一個(gè)rtsp服務(wù),最終會(huì)使用**vlc**進(jìn)行驗(yàn)證。上面圖2、
圖2中,有幾個(gè)函數(shù)avdevice_register_all,是需要使用到采集的gdi設(shè)備,所以需要該函數(shù)進(jìn)行注冊(cè)。使用av_dict_set_int來(lái)設(shè) 置編碼參數(shù),圖2中av_dict_set_int,設(shè)置抓屏參數(shù)
部分采集編碼:
部分編碼
AVCodec *codec = nullptr;//codec = avcodec_find_encoder(AV_CODEC_ID_H264);codec = avcodec_find_encoder_by_name("libx264");if (!codec) {std::cout << "H.264 Encoder not found.\n" << std::endl;return false;}codec_context_ = avcodec_alloc_context3(codec);if (!codec_context_) {std::cout << "avcodec_alloc_context3() failed." << std::endl;return false;}codec_context_->width = av_config_.video.width;codec_context_->height = av_config_.video.height;codec_context_->time_base = { 1, (int)av_config_.video.framerate };codec_context_->framerate = { (int)av_config_.video.framerate, 1 };codec_context_->gop_size = av_config_.video.gop;codec_context_->max_b_frames = 0;codec_context_->pix_fmt = AV_PIX_FMT_YUV420P;// rc control mode: abrcodec_context_->bit_rate = av_config_.video.bitrate;// cbr mode configcodec_context_->rc_min_rate = av_config_.video.bitrate;codec_context_->rc_max_rate = av_config_.video.bitrate;codec_context_->rc_buffer_size = (int)av_config_.video.bitrate;codec_context_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;if (codec->id == AV_CODEC_ID_H264) {av_opt_set(codec_context_->priv_data, "preset", "ultrafast", 0); //ultrafast }av_opt_set(codec_context_->priv_data, "tune", "zerolatency", 0);av_opt_set_int(codec_context_->priv_data, "forced-idr", 1, 0);av_opt_set_int(codec_context_->priv_data, "avcintra-class", -1, 0);if (avcodec_open2(codec_context_, codec, NULL) != 0) {std::cout << "avcodec_open2() failed." << std::endl;return false;}部分代碼如上
① 采集流程
上面主要是獲取設(shè)備信息,并打開解碼器
后面通過(guò)av_read_frame讀取流,avcodec_send_packet/avcodec_receive_frame來(lái)進(jìn)行解碼流
同時(shí),將獲取到的數(shù)據(jù)進(jìn)行編碼成h264,
② 編碼流程
編碼流程中需要注意,數(shù)據(jù)是通過(guò)采集中獲取到的數(shù)據(jù),AVframe,需要先將AVFrame轉(zhuǎn)為yuvAVFrame,然后通過(guò)接口avcodec_send_frame/avcodec_receive_packet,avcodec_receive_packet中的數(shù)據(jù),得到的是AVPacket的數(shù)據(jù),需要去掉其中h264中的起始碼,傳給rtsp服務(wù),rtsp服務(wù)就能將數(shù)據(jù)傳輸給用戶端。
③ 封裝
由于此處直接使用ES流,不做封裝,直接將編碼器中的數(shù)據(jù)進(jìn)行傳輸。
④ 傳輸
傳輸參考下面的3.rtsp服務(wù)
2、引用參考部分
3、總結(jié)
本章節(jié)只講述整個(gè)服務(wù)器相關(guān)的流程,實(shí)現(xiàn)代碼請(qǐng)關(guān)注后續(xù)章節(jié)!總結(jié)
以上是生活随笔為你收集整理的基于Qt和ffmpeg的抓屏rtsp服务(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 瑰雪黑阳rwby手游辅助材料 瑰雪黑阳
- 下一篇: ubuntu16.04耳机没有声音解决办