【USB网络摄像头】基于mjpeg-streamer的视频采集与播放【QT上位机软件】
前言
最近一直在嘗試制作一個(gè),網(wǎng)絡(luò)攝像頭,先后分別嘗試了使用QT包裝的UDP類TCP類,和LINUX中的socket編程等方式,但是非常遺憾,都沒有取得非常好的播放效果。以為只要一幀一幀的傳輸視頻數(shù)據(jù)就沒有問題了,但是非常遺憾的是效果都不是非常好。因?yàn)閷τ跀?shù)據(jù)的處理方法太過簡單,不會(huì)寫一些對于數(shù)據(jù)預(yù)先處理來減少數(shù)據(jù)的丟包,倒是播放出來的視頻出現(xiàn)了如下的現(xiàn)象。
非常明顯應(yīng)為每一幀的圖像之間出現(xiàn)了嚴(yán)重的粘連現(xiàn)象。搞了很久都沒有找到解決問題的方法。最后還是選擇了使用現(xiàn)成的開源框架mjpeg-streamer,并修改一些源碼來實(shí)現(xiàn)自己功能。
網(wǎng)上很多的方法都是在瀏覽器中直接播放視頻。但是項(xiàng)目需要一個(gè)上位機(jī)軟件,然后我嘗試了官方源碼包中的那個(gè)QT上位機(jī)程序,但是好像應(yīng)為版本的原因?qū)е虏荒苷5木幾g。后來又在網(wǎng)上找了一些,拼拼湊湊總算搞定了。
軟件部分
工程文件:
mjpeg-clint.pro
#------------------------------------------------- # # Project created by QtCreator 2020-03-08T18:33:52 # #-------------------------------------------------QT += core gui networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = mjpeg-clint TEMPLATE = app# The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \mainwindow.cppHEADERS += \mainwindow.hFORMS += \mainwindow.ui頭文件:
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QUrl> #include <QPixmap> #include <QFile> #include <QPicture> #include <QMessageBox> #include <QMainWindow> #include <QNetworkReply> #include <QNetworkAccessManager> #include <QNetworkRequest> #include<QTimer>namespace Ui { class MainWindow; }class MainWindow : public QMainWindow {Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();void PicConnect(QString p);void SetWindow();void ShowPic();void StopPic();private slots:void on_buttonstart_clicked();void on_buttonsnapshot_clicked();void on_buttonclose_clicked();public slots:void slot_replyFinished(QNetworkReply* reply);private:Ui::MainWindow *ui;//connect to pictureQNetworkAccessManager *manager;bool isPicOnLabel;QImage* img=new QImage,* scaledimg=new QImage;QNetworkRequest request;QString ip;qint16 port;QString PU;};#endif // MAINWINDOW_H源文件:
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h"/* 構(gòu)造和析構(gòu) */ MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow) {ui->setupUi(this);setWindowTitle("客戶端");PU="http://192.168.0.18:8080/?action=snapshot";manager = new QNetworkAccessManager(this);connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slot_replyFinished(QNetworkReply*))); }MainWindow::~MainWindow() {delete ui; }void MainWindow::PicConnect(QString PicUrl) {request.setUrl(QUrl(PicUrl));manager->get(request); }void MainWindow::slot_replyFinished(QNetworkReply* reply) {QByteArray data = reply->readAll();img->loadFromData(data, "JPG"); }void MainWindow::on_buttonstart_clicked() {if(isPicOnLabel==false){//獲取服務(wù)器ip=ui->lineEditIP->text();port=ui->lineEditPORT->text().toInt();PU=QString("http://"+ip+":"+tr("%1").arg(port)+"/?action=snapshot");ShowPic();}else{StopPic();} }void MainWindow::ShowPic() {isPicOnLabel=true;QString name="暫停";while(1){if(isPicOnLabel==false)break;PicConnect(PU);//用作延時(shí)QEventLoop eventloop;QTimer::singleShot(10, &eventloop, SLOT(quit()));eventloop.exec();*scaledimg=img->scaled(640,480,Qt::KeepAspectRatio);ui->label->setPixmap(QPixmap::fromImage(*scaledimg));} }void MainWindow::StopPic() {QString name="開始";isPicOnLabel=false; }void MainWindow::on_buttonsnapshot_clicked() {QDate date;QTime time;/* 取到當(dāng)前顯示的pixmap指針 */const QPixmap *pixmap = ui->label->pixmap();if(pixmap){/* 保存為jpg文件,并保證名字不相同 */pixmap->save("./"+date.currentDate().toString("yyyy,MM,dd")+"-"+time.currentTime().toString("hh;mm;ss")+".jpg");QMessageBox::about(this, " ", "Save Successed!");} }void MainWindow::on_buttonclose_clicked() {this->close(); }運(yùn)行效果:
LINUX下:
Windows下
總結(jié):
到目前為止視頻的采集與播放基本已經(jīng)搞定,下面我需要研究一些圖像的編碼與解碼,包括使用ARM自身的硬編解碼來對于圖片快速的處理。同時(shí)還要進(jìn)一步熟悉mjpeg-streamer源碼。
工程源碼:
mjpeg-clint
總結(jié)
以上是生活随笔為你收集整理的【USB网络摄像头】基于mjpeg-streamer的视频采集与播放【QT上位机软件】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA微信公众号开发之公众号内H5调微
- 下一篇: s3c2440移植MQTT