1. 程式人生 > >Qt編寫的RTSP播放器+視訊監控(ffmpeg版本)

Qt編寫的RTSP播放器+視訊監控(ffmpeg版本)

記得四年前就寫了個簡易版本的,當時寫得非常粗糙,程式碼實在慘不忍睹,時隔多年後,重新寫了個版本,同時還解決了以前不支援6畫面8畫面切換等異形佈局的問題
1:可以用過目錄下的rtsp.txt設定要顯示的視訊流地址。
2:支援4畫面+6畫面+8畫面+9畫面+16畫面切換。
3:支援雙擊最大化當前畫面。
4:支援右鍵截圖。
5:支援各種視訊流和本地檔案播放。
6:可設定OSD標籤。
7:在所有可能測試的作業系統和平臺上均編譯通過並完美執行。
8:XP執行報錯的話請執行目錄下的fixff.cmd即可。

/**
* ffmpeg視訊播放類 作者:feiyangqingyun(QQ:517216493) 2018-5-1
* 1:多執行緒實時播放rtsp視訊流


* 2:支援X86和嵌入式linux
* 3:多執行緒顯示影象,不卡主介面
* 4:自動重連網路攝像頭
* 5:可設定邊框大小即偏移量和邊框顏色
* 6:可設定是否繪製OSD標籤即標籤文字和標籤位置
* 7:可設定兩種OSD位置和風格
* 8:可設定是否儲存到檔案以及檔名
* 9:可播放本地視訊檔案,支援設定幀率
* 10:支援h265視訊流+rtmp等常見視訊流
*/

/**
* USB攝像機採集類 作者:feiyangqingyun(QQ:517216493) 2018-5-1
* 1:可獲取攝像機實時視訊
* 2:支援X86和嵌入式linux
* 3:多執行緒顯示影象,不卡主介面
* 4:自動重連USB攝像頭
* 5:可設定邊框大小即偏移量和邊框顏色

* 6:可設定是否繪製OSD標籤即標籤文字和標籤位置
* 7:可設定兩種OSD位置和風格
* 8:可設定是否顯示實時人臉框
* 9:可設定查詢當前圖片內的最大相似人臉
*/

執行截圖:

標頭檔案:

#ifndef FFMPEG_H
#define FFMPEG_H

/**
 * ffmpeg視訊播放類 作者:feiyangqingyun(QQ:517216493) 2018-5-1
 * 1:多執行緒實時播放rtsp視訊流
 * 2:支援X86和嵌入式linux
 * 3:多執行緒顯示影象,不卡主介面
 * 4:自動重連網路攝像頭
 * 5:可設定邊框大小即偏移量和邊框顏色
 * 6:可設定是否繪製OSD標籤即標籤文字或圖片和標籤位置
 * 7:可設定兩種OSD位置和風格
 * 8:可設定是否儲存到檔案以及檔名
 * 9:可播放本地視訊檔案,支援設定幀率
 * 10:支援h265視訊流+rtmp等常見視訊流
 * 11:可暫停播放和繼續播放
 */

#include <QtGui>
#include <QtNetwork>
#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
#include <QtWidgets>
#endif

#include "libffmpeg_head.h"

class FFmpegWidget;

class FFmpegThread : public QThread
{
    Q_OBJECT
public:
    explicit FFmpegThread(QObject *parent = 0);
    static void initlib();

protected:
    void run();

private:
    volatile bool stopped;              //執行緒停止標誌位
    volatile bool isPlay;               //播放視訊標誌位
    volatile bool isPause;              //暫停播放標誌位
    volatile bool isRtsp;               //是否是視訊流

    QMutex mutex;                       //鎖物件
    QDateTime lastTime;                 //最後的訊息時間
    int frameCount;                     //幀數統計
    int frameFinish;                    //一幀完成
    int videoWidth;                     //視訊寬度
    int videoHeight;                    //視訊高度
    int oldWidth;                       //上一次視訊寬度
    int oldHeight;                      //上一次視訊高度
    int videoStreamIndex;               //視訊流索引
    int videoFps;                       //視訊流幀率

    QFile file;                         //儲存檔案物件
    uint8_t *buffer;                    //儲存解碼後圖片buffer
    AVPacket pAVPacket;                 //包物件
    AVFrame *pAVFrame, *pAVFrame2;      //幀物件
    AVFormatContext *pAVFormatContext;  //格式物件
    AVCodecContext *pAVCodecContext;    //解碼物件
    SwsContext *pSwsContext;            //處理圖片資料物件

    int interval;                       //採集間隔
    int sleepTime;                      //休眠時間
    int checkTime;                      //檢測超時時間
    bool checkConn;                     //檢測視訊流連線
    bool saveFile;                      //是否儲存檔案
    QString fileName;                   //儲存檔名稱
    QString url;                        //視訊流地址

public:
    //獲取最後的活動時間
    QDateTime getLastTime();
    //獲取url地址
    QString getUrl();

signals:
    //播放成功
    void receivePlayOk();
    //播放失敗
    void receivePlayError();
    //播放結束
    void receivePlayFinsh();

    //收到圖片訊號
    void receiveImage(const QImage &image);

public slots:
    //設定顯示間隔
    void setInterval(int interval);

    //設定休眠時間
    void setSleepTime(int sleepTime);

    //設定檢測連線超時
    void setCheckTime(int checkTime);
    //設定是否檢測連線
    void setCheckConn(bool checkConn);

    //設定是否儲存檔案
    void setSaveFile(bool saveFile);
    //設定儲存檔名稱
    void setFileName(const QString &fileName);

    //設定視訊流地址
    void setUrl(const QString &url);

    //校驗url
    bool checkUrl();

    //初始化視訊物件
    bool init();

    //釋放物件
    void free();

    //播放視訊物件
    void play();

    //暫停播放
    void pause();

    //繼續播放
    void next();

    //停止採集執行緒
    void stop();

};

//實時視訊顯示窗體類
class FFmpegWidget : public QWidget
{
    Q_OBJECT
    Q_ENUMS(OSDFormat)
    Q_ENUMS(OSDPosition)

    Q_PROPERTY(bool copyImage READ getCopyImage WRITE setCopyImage)
    Q_PROPERTY(bool checkLive READ getCheckLive WRITE setCheckLive)
    Q_PROPERTY(bool drawImage READ getDrawImage WRITE setDrawImage)
    Q_PROPERTY(bool fillImage READ getFillImage WRITE setFillImage)
    Q_PROPERTY(int timeout READ getTimeout WRITE setTimeout)
    Q_PROPERTY(int borderWidth READ getBorderWidth WRITE setBorderWidth)
    Q_PROPERTY(QColor borderColor READ getBorderColor WRITE setBorderColor)
    Q_PROPERTY(QColor focusColor READ getFocusColor WRITE setFocusColor)
    Q_PROPERTY(QString bgText READ getBgText WRITE setBgText)
    Q_PROPERTY(QImage bgImage READ getBgImage WRITE setBgImage)

    Q_PROPERTY(bool osd1Visible READ getOSD1Visible WRITE setOSD1Visible)
    Q_PROPERTY(int osd1FontSize READ getOSD1FontSize WRITE setOSD1FontSize)
    Q_PROPERTY(QString osd1Text READ getOSD1Text WRITE setOSD1Text)
    Q_PROPERTY(QColor osd1Color READ getOSD1Color WRITE setOSD1Color)
    Q_PROPERTY(QImage osd1Image READ getOSD1Image WRITE setOSD1Image)
    Q_PROPERTY(OSDFormat osd1Format READ getOSD1Format WRITE setOSD1Format)
    Q_PROPERTY(OSDPosition osd1Position READ getOSD1Position WRITE setOSD1Position)

    Q_PROPERTY(bool osd2Visible READ getOSD2Visible WRITE setOSD2Visible)
    Q_PROPERTY(int osd2FontSize READ getOSD2FontSize WRITE setOSD2FontSize)
    Q_PROPERTY(QString osd2Text READ getOSD2Text WRITE setOSD2Text)
    Q_PROPERTY(QColor osd2Color READ getOSD2Color WRITE setOSD2Color)
    Q_PROPERTY(QImage osd2Image READ getOSD2Image WRITE setOSD2Image)
    Q_PROPERTY(OSDFormat osd2Format READ getOSD2Format WRITE setOSD2Format)
    Q_PROPERTY(OSDPosition osd2Position READ getOSD2Position WRITE setOSD2Position)

public:
    //標籤格式
    enum OSDFormat {
        OSDFormat_Text = 0,             //文字
        OSDFormat_Date = 1,             //日期
        OSDFormat_Time = 2,             //時間
        OSDFormat_DateTime = 3,         //日期時間
        OSDFormat_Image = 4             //圖片
    };

    //標籤位置
    enum OSDPosition {
        OSDPosition_Left_Top = 0,       //左上角
        OSDPosition_Left_Bottom = 1,    //左下角
        OSDPosition_Right_Top = 2,      //右上角
        OSDPosition_Right_Bottom = 3    //右下角
    };

    explicit FFmpegWidget(QWidget *parent = 0);
    ~FFmpegWidget();

protected:
    void paintEvent(QPaintEvent *);
    void drawBorder(QPainter *painter);
    void drawBg(QPainter *painter);
    void drawImg(QPainter *painter, QImage img);
    void drawOSD(QPainter *painter,
                 int osdFontSize,
                 const QString &osdText,
                 const QColor &osdColor,
                 const QImage &osdImage,
                 const OSDFormat &osdFormat,
                 const OSDPosition &osdPosition);

private:
    FFmpegThread *ffmpeg;           //實時視訊採集物件
    QTimer *timerCheck;             //定時器檢查裝置是否線上
    QImage image;                   //要顯示的圖片

    bool copyImage;                 //是否拷貝圖片
    bool checkLive;                 //檢測是否活著
    bool drawImage;                 //是否繪製圖片
    bool fillImage;                 //自動拉伸填充
    int timeout;                    //超時時間
    int borderWidth;                //邊框寬度
    QColor borderColor;             //邊框顏色
    QColor focusColor;              //有焦點邊框顏色
    QString bgText;                 //預設無影象顯示文字
    QImage bgImage;                 //預設無影象背景圖片

    bool osd1Visible;               //顯示標籤1
    int osd1FontSize;               //標籤1字號
    QString osd1Text;               //標籤1文字
    QColor osd1Color;               //標籤1顏色
    QImage osd1Image;               //標籤1圖片
    OSDFormat osd1Format;           //標籤1文字格式
    OSDPosition osd1Position;       //標籤1位置

    bool osd2Visible;               //顯示標籤2
    int osd2FontSize;               //標籤2字號
    QString osd2Text;               //標籤2文字
    QColor osd2Color;               //標籤2顏色
    QImage osd2Image;               //標籤2圖片
    OSDFormat osd2Format;           //標籤2文字格式
    OSDPosition osd2Position;       //標籤2位置

public:
    QImage getImage()               const;
    QDateTime getLastTime()         const;
    QString getUrl()                const;

    bool getCopyImage()             const;
    bool getCheckLive()             const;
    bool getDrawImage()             const;
    bool getFillImage()             const;
    int getTimeout()                const;
    int getBorderWidth()            const;
    QColor getBorderColor()         const;
    QColor getFocusColor()          const;
    QString getBgText()             const;
    QImage getBgImage()             const;

    bool getOSD1Visible()           const;
    int getOSD1FontSize()           const;
    QString getOSD1Text()           const;
    QColor getOSD1Color()           const;
    QImage getOSD1Image()           const;
    OSDFormat getOSD1Format()       const;
    OSDPosition getOSD1Position()   const;

    bool getOSD2Visible()           const;
    int getOSD2FontSize()           const;
    QString getOSD2Text()           const;
    QColor getOSD2Color()           const;
    QImage getOSD2Image()           const;
    OSDFormat getOSD2Format()       const;
    OSDPosition getOSD2Position()   const;

private slots:
    //接收影象並繪製
    void updateImage(const QImage &image);
    //校驗裝置
    void checkVideo();

signals:
    //播放成功
    void receivePlayOk();
    //播放失敗
    void receivePlayError();
    //播放結束
    void receivePlayFinsh();

    //收到圖片訊號
    void receiveImage(const QImage &image);

public slots:
    //設定顯示間隔
    void setInterval(int interval);
    //設定休眠時間
    void setSleepTime(int sleepTime);
    //設定檢測連線超時
    void setCheckTime(int checkTime);
    //設定是否檢測連線
    void setCheckConn(bool checkConn);
    //設定是否儲存檔案
    void setSaveFile(bool saveFile);
    //設定儲存檔名稱
    void setFileName(const QString &fileName);
    //設定視訊流地址
    void setUrl(const QString &url);

    //設定是否拷貝圖片
    void setCopyImage(bool copyImage);
    //設定是否檢測活著
    void setCheckLive(bool checkLive);
    //設定是否實時繪製圖片
    void setDrawImage(bool drawImage);
    //設定是否拉伸填充
    void setFillImage(bool fillImage);
    //設定超時時間
    void setTimeout(int timeout);
    //設定邊框寬度
    void setBorderWidth(int borderWidth);
    //設定邊框顏色
    void setBorderColor(const QColor &borderColor);
    //設定有焦點邊框顏色
    void setFocusColor(const QColor &focusColor);
    //設定無影象文字
    void setBgText(const QString &bgText);
    //設定無影象背景圖
    void setBgImage(const QImage &bgImage);

    //設定標籤1是否可見
    void setOSD1Visible(bool osdVisible);
    //設定標籤1文字字號
    void setOSD1FontSize(int osdFontSize);
    //設定標籤1文字
    void setOSD1Text(const QString &osdText);
    //設定標籤1文字顏色
    void setOSD1Color(const QColor &osdColor);
    //設定標籤1圖片
    void setOSD1Image(const QImage &osdImage);
    //設定標籤1格式
    void setOSD1Format(const OSDFormat &osdFormat);
    //設定標籤1位置
    void setOSD1Position(const OSDPosition &osdPosition);

    //設定標籤2是否可見
    void setOSD2Visible(bool osdVisible);
    //設定標籤2文字字號
    void setOSD2FontSize(int osdFontSize);
    //設定標籤2文字
    void setOSD2Text(const QString &osdText);
    //設定標籤2文字顏色
    void setOSD2Color(const QColor &osdColor);
    //設定標籤2圖片
    void setOSD2Image(const QImage &osdImage);
    //設定標籤2格式
    void setOSD2Format(const OSDFormat &osdFormat);
    //設定標籤2位置
    void setOSD2Position(const OSDPosition &osdPosition);

    //開啟裝置
    void open();
    //暫停
    void pause();
    //繼續
    void next();
    //關閉裝置
    void close();
    //重新載入
    void restart();
    //清空
    void clear();

};

#endif // FFMPEG_H

相關推薦

Qt編寫RTSP播放+視訊監控(ffmpeg版本)

記得四年前就寫了個簡易版本的,當時寫得非常粗糙,程式碼實在慘不忍睹,時隔多年後,重新寫了個版本,同時還解決了以前不支援6畫面8畫面切換等異形佈局的問題。1:可以用過目錄下的rtsp.txt設定要顯示的視訊流地址。2:支援4畫面+6畫面+8畫面+9畫面+16畫面切換。3:支援雙

VLC和Qt結合編寫流媒體rtsp播放

      VLC播放器是一款功能強大且小巧的播放器,它支援多種多樣的音視訊格式,比如MPEG1,2以及mp3等等。並且通過Qt和VLC的結合能讓每個開發者寫出自己的視訊流媒體播放器。     Qt與VLC結合編寫流媒體播放器主要有兩種辦法:       一. 通過V

利用QT和libvlc寫RTSP播放

仗劍高歌2013-12-24 10:15:25 fuliangcheng:你說的視窗播放是不是說播放的視窗在播放器介面中,而不是另開一個單獨的視窗? 是的,就是 有一個主視窗 即播放器介面,播放就是在這裡播放。通過該介面的url選項,開啟一個新視窗,在這裡輸入url,開始播放,是在播放器介面播放。我一直沒有

人狠話不多,細說大牛直播SDK之RTMP播放RTSP播放

 Windows/Android/iOS平臺高穩定、超低延遲的跨平臺RTMP直播播放器;  Windows/Android/iOS平臺高穩定、超低延遲的跨平臺RTSP直播播放器;  Windows/Android/iOS平臺完美支援多例項播放(如同時播放多路rtmp/rtsp流);  Windows/A

使用JS與MediaPlayer編寫網頁播放

剛開始我使用的是新版本9.0以後的mediaplayer外掛,新版本的外掛有很多功能、屬性、方法和事件處理功能,並且最簡單的是使用它的playlist功能控制播放器的播放,不過由於有許可權的問題,這種方法在本機上可行,上傳到伺服器並且用其他的電腦訪問則播放不了,提示“沒有許可權”,錯誤在這方法上appe

基於QT的多執行緒視訊監控的實現(二)

二丶接著上一節,這節主要講,多屏分割,多屏相互切換   視訊監控很重要的一個環節就是多屏切換了,這裡主要實現的是 1,2,4,8,16,32,64 分屏的相互切換,最多是64分屏。(1)QT 常用到的佈

網頁IE輕鬆呼叫VLC播放實現監控(元件+方法大全)

公司突發奇想,要把剛買回來的網路監控機用自己內部網站線上監控。 作為網站的開發員,我接下了這個任務。 網路上有很多資料參與,但是都不全都不盡人意,最後經過多次的不同關鍵字的查詢和測試,總算讓我成功了。 轉入正題: 一、程式碼 <!DOCTYPE html PUBLIC

播放/視訊播放客戶端/程式原始碼/VS2010/VS2012/VC/MFC

兩年前有個想法到淘寶賣視訊,怎麼賣?去找一些高質量的考級,考研,計算機教學視訊,然後呢,找工廠定做一批U盤,把視訊放在U盤上,自已再寫一個特製的播放器客戶端,播放器會讀U盤的硬體序號,U盤其實當做一個鑰匙,相當於U盾,主要是為了防止視訊賣出去後被其它人免費傳播。當時對這個想法

仿迅雷播放教程 -- 基於ffmpeg的C++播放 (1)

  2011年12月份的時候發了這篇部落格 http://blog.csdn.net/qq316293804/article/details/7107049 ,博文最後說會開源一個播放器,沒想到快兩年了,才有時間發部落格。     兩年前的部落格和大部分部落格一樣,以結果為

EasyPlayer windows RTSP播放OCX外掛使用說明

鑑於大家對於EasyPlayer外掛的使用還不太熟悉,特此寫一篇外掛的使用文件,供大家參考;EasyPlayer外掛有兩種,一種是基於IE的ActiveX控制元件,一種是基於FireFox(也支援多瀏覽器)的npAPI外掛;兩種外掛均包含原始碼,由於FireBr

rtsp播放(畢業設計跟進)

美好的週末就這樣被畢業設計給糟蹋了,不過霧霾這麼厲害,還是不出去為妙。 先上心得。 先是準備用Vitamio萬能播放器進行二次開發的,不明覺厲。Vitamio裡有兩個android工程,,vitamio是library,有很多有用的庫,sample是例子,裡面有個Video

Android流媒體開發之路三:基於NDK開發Android平臺RTSP播放

基於NDK開發Android平臺RTSP播放器 最近做了不少android端的開發,有推流、播放、直播、對講等各種應用,做了RTMP、RTSP、HTTP-FLV、自定義等各種協議,還是有不少收穫和心得的。我這邊做,核心模組和核心程式碼部分,都是基於NDK,用C++開發的,然後將so動態庫,在Android

QtPlayer——基於FFmpegQt視訊播放

QtPlayer——基於FFmpeg的Qt音視訊播放器 本文主要講解一個基於Qt GUI的,使用FFmpeg音視訊庫解碼的音視訊播放器,同時也是記錄一點學習心得,本人也是多媒體初學者,也歡迎大家交流,程式執行圖如下: QtPlayer基於FFmpeg的Q

基於QtFFMpeg的音視訊播放設計二(封裝)

在上一篇中我們實現了視訊的解碼、格式轉換,但其基本是堆出來的程式碼,可複用性以及擴充套件性比較低,現在我們對它進行類的封裝。這裡我們把它分為四個小部分。 1、重構封裝FFMpeg類完成開啟和關閉視訊介面 2、重構讀取視訊幀介面 3、重構解碼介面 4、重構ToRGB介面

基於QtFFMpeg的音視訊播放設計四(視訊播放進度控制)

上面介紹瞭如何使用opengl繪製視訊和Qt的介面設計,也比較簡單,現在我們看下如何控制視訊播放及進度的控制,內容主要分為以下幾個部分 1、建立解碼執行緒控制播放速度 2、通過Qt開啟外部視訊 3、視訊總時間顯示和播放的當前時間顯示 4、進度條顯示播放進度、拖動進度條

從零開始學習音視訊程式設計技術(七) FFMPEG Qt視訊播放之SDL的使用

前面介紹了使用FFMPEG+Qt解碼視訊並顯示。 現在我們就著手給它加上聲音播放。 播放聲音有很多種方式: 以windows系統為例,可以使用如下方法播放音訊: 1.直接呼叫系統API的wavein、waveout等函式 2.使用directsound播放

(三) FFmpeg結合Qt實現視訊播放(一)

目錄 前言 (二) FFmpeg解碼視訊學習已經完成了Qt實現視訊播放器的一部分,但是沒有音訊,而且在播放大的視訊的時候,甚至會到導致我的Ubuntu卡死。繼續跟著大神們學習! SDL的使用 SDL概述 主流的音訊開源庫:OpenA

ffmpeg+sdl教程----編寫一個簡單的播放5(同步視訊到音訊)

    個人認為,這這部分教程的新增程式碼量雖然不是最多的,難度卻是最大的,重複看了多次才明白,因為有兩個問題的困擾,搞得還不清楚: 1.音訊和視訊既然都有各自的時間戳,各自按各自的時間戳來播放不就行了,為什麼還需要同步呢? 2.如果要把視訊同步到音訊,怎麼同步?或者說以什麼

Qt編寫視訊播放(vlc核心)

在研究qt+vlc的過程中,就想直接做個播放器用於獨立的專案,vlc還支援硬體加速,不過部分電腦硬體不支援除外。用vlc的核心寫播放器就是快,直接呼叫api就行,邏輯處理和ui展示基本上分分鐘的事情,最好加點美化那就更加完美了,市面上很多播放器是vlc核心寫的,或者ffmpe

從零開始學習音視訊程式設計技術(八)FFMPEG Qt視訊播放之音視訊同步

前面分別講解了: 現在我們就將視訊和音訊合併,並讓聲音和畫面同步。 加入音訊的部分就不做講解了,這裡主要講下聲音和視訊同步的步驟。 首先剛開始播放的時候通過av_gettime()獲取系統主時鐘,記錄下來。 以後便不斷呼叫av_gettime()獲取系統時鐘