From 951695d8663403b5e291f6af395c5721d7a7ec56 Mon Sep 17 00:00:00 2001 From: wl <3569324431@QQ.com> Date: 星期四, 20 二月 2025 12:15:32 +0800 Subject: [PATCH] Merge branch 'master' of ssh://115.28.86.8:29418/~admin/FaceX_AI_智能守卫 --- Client/董澎韬/code/main.cpp | 11 Client/董佳琦/log/日志_董佳琦_0218.doc | 0 Server/卢敏/log/日志_卢敏_2.18.doc | 0 Server/冉凯/log/日志_冉凯_20250219.doc | 0 Server/张敏丽/document/日志_姓名_日期.doc | 0 Client/郭文强/document/新需求功能规格说明书 - 郭文强.docx | 0 Client/解来鑫/log/日志_姓名_日期.doc | 0 Client/董澎韬/log/日志_董澎韬_0218.doc | 0 Client/王雨阳/log/王雨阳_250218.doc | 0 Client/董澎韬/code/rtspthread.h | 22 + Server/卢敏/log/日志_卢敏_2.19.doc | 0 Client/董澎韬/code/facexmainwindow.cpp | 204 +++++++++++++++++ Client/王雨阳/document/项目需求书2.0版.docx | 0 Client/董澎韬/code/qffmpeg.h | 63 +++++ Client/董澎韬/code/rtspthread.cpp | 13 + Client/郭文强/log/郭文强_20250218.doc | 0 ProjectInformation/1.2项目进度表.et | 0 Client/董澎韬/code/qffmpeg.cpp | 113 +++++++++ Client/董澎韬/log/日志_董澎韬_0219.doc | 0 Client/王雨阳/code/UI.html | 202 ++++++++++++++++ Client/王雨阳/log/日志_王雨阳_250218.doc | 0 Client/郭文强/log/郭文强_20250219.doc | 0 Server/冉凯/document/日志_冉凯_20250218.doc | 0 Client/董澎韬/code/facexmainwindow.h | 82 ++++++ 24 files changed, 710 insertions(+), 0 deletions(-) diff --git "a/Client/\347\216\213\351\233\250\351\230\263/code/UI.html" "b/Client/\347\216\213\351\233\250\351\230\263/code/UI.html" new file mode 100644 index 0000000..473c500 --- /dev/null +++ "b/Client/\347\216\213\351\233\250\351\230\263/code/UI.html" @@ -0,0 +1,202 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>浜鸿劯璇嗗埆鑰冨嫟 - 浜鸿劯褰曞叆妯″潡</title> + <style> + body { + font-family: Arial, sans-serif; + margin: 20px; + } + .container { + max-width: 600px; + margin: auto; + padding: 20px; + border: 1px solid #ccc; + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + } + h1 { + text-align: center; + color: #333; + } + .form-group { + margin-bottom: 15px; + } + label { + display: block; + margin-bottom: 5px; + font-weight: bold; + } + input[type="text"], button { + width: 100%; + padding: 10px; + font-size: 16px; + border: 1px solid #ccc; + border-radius: 4px; + } + button { + background-color: #007bff; + color: white; + cursor: pointer; + } + button:hover { + background-color: #0056b3; + } + .camera-preview { + margin-top: 20px; + text-align: center; + } + .camera-preview video { + max-width: 100%; + height: auto; + border: 1px solid #ccc; + border-radius: 4px; + } + .image-preview { + margin-top: 20px; + text-align: center; + } + .image-preview img { + max-width: 100%; + height: auto; + border: 1px solid #ccc; + border-radius: 4px; + } + .status-message { + margin-top: 15px; + text-align: center; + font-size: 14px; + color: #555; + } + </style> +</head> +<body> + <div class="container"> + <h1>浜鸿劯璇嗗埆鑰冨嫟 - 浜鸿劯褰曞叆妯″潡</h1> + + <!-- 宸ュ彿杈撳叆 --> + <div class="form-group"> + <label for="employee-id">杈撳叆宸ュ彿:</label> + <input type="text" id="employee-id" placeholder="璇疯緭鍏ュ伐鍙�"> + </div> + + <!-- 鏌ヨ淇℃伅鎸夐挳 --> + <button onclick="searchUserInfo()">鏌ヨ淇℃伅</button> + + <!-- 鐢ㄦ埛淇℃伅灞曠ず --> + <div class="form-group" id="user-info" style="display: none;"> + <label>鐢ㄦ埛淇℃伅:</label> + <p id="user-details"></p> + </div> + + <!-- 妯℃嫙鎽勫儚澶存姄鍙栧浘鐗� --> + <div class="camera-preview" id="camera-preview" style="display: none;"> + <video id="camera-video" autoplay playsinline></video> + <div> + <button onclick="captureImage('front')">鎶撳彇姝h劯</button> + <button onclick="captureImage('left')">鎶撳彇宸︿晶鑴�</button> + <button onclick="captureImage('right')">鎶撳彇鍙充晶鑴�</button> + </div> + </div> + + <!-- 鍥剧墖棰勮 --> + <div class="image-preview" id="image-preview" style="display: none;"> + <h3>鎶撳彇鐨勫浘鐗囬瑙�</h3> + <div id="captured-images"> + <img id="front-image" src="" alt="姝h劯鍥剧墖" style="display: none;"> + <img id="left-image" src="" alt="宸︿晶鑴稿浘鐗�" style="display: none;"> + <img id="right-image" src="" alt="鍙充晶鑴稿浘鐗�" style="display: none;"> + </div> + </div> + + <!-- 鎻愪氦鎸夐挳 --> + <button onclick="submitData()" style="display: none;" id="submit-btn">鎻愪氦</button> + + <!-- 鐘舵�佹秷鎭� --> + <div class="status-message" id="status-message"></div> + </div> + + <script> + let cameraStream = null; + + // 妯℃嫙鏌ヨ鐢ㄦ埛淇℃伅 + function searchUserInfo() { + const employeeId = document.getElementById('employee-id').value; + if (!employeeId) { + alert('璇疯緭鍏ュ伐鍙�'); + return; + } + + // 妯℃嫙鏌ヨ缁撴灉 + const userInfo = { + id: employeeId, + name: '寮犱笁', + department: '鎶�鏈儴' + }; + + // 鏄剧ず鐢ㄦ埛淇℃伅 + document.getElementById('user-details').innerText = `濮撳悕: ${userInfo.name}, 閮ㄩ棬: ${userInfo.department}`; + document.getElementById('user-info').style.display = 'block'; + + // 鏄剧ず鎽勫儚澶� + startCamera(); + } + + // 鎵撳紑鎽勫儚澶� + async function startCamera() { + try { + cameraStream = await navigator.mediaDevices.getUserMedia({ video: true }); + const videoElement = document.getElementById('camera-video'); + videoElement.srcObject = cameraStream; + document.getElementById('camera-preview').style.display = 'block'; + } catch (error) { + alert('鏃犳硶璁块棶鎽勫儚澶达紝璇锋鏌ユ潈闄愭垨璁惧鏄惁鍙敤銆�'); + console.error('鎽勫儚澶磋闂け璐�:', error); + } + } + + // 鎶撳彇鍥剧墖 + function captureImage(faceType) { + const videoElement = document.getElementById('camera-video'); + const canvas = document.createElement('canvas'); + canvas.width = videoElement.videoWidth; + canvas.height = videoElement.videoHeight; + const context = canvas.getContext('2d'); + context.drawImage(videoElement, 0, 0, canvas.width, canvas.height); + + // 灏嗘姄鍙栫殑鍥剧墖鏄剧ず鍦ㄩ〉闈腑 + const imageUrl = canvas.toDataURL('image/png'); + const imageElement = document.getElementById(`${faceType}-image`); + imageElement.src = imageUrl; + imageElement.style.display = 'block'; + + // 濡傛灉涓夊紶鍥剧墖閮藉凡鎶撳彇锛屾樉绀烘彁浜ゆ寜閽� + const frontImage = document.getElementById('front-image').src; + const leftImage = document.getElementById('left-image').src; + const rightImage = document.getElementById('right-image').src; + if (frontImage && leftImage && rightImage) { + document.getElementById('submit-btn').style.display = 'block'; + } + } + + // 妯℃嫙鎻愪氦鏁版嵁 + function submitData() { + const employeeId = document.getElementById('employee-id').value; + if (!employeeId) { + alert('璇峰厛杈撳叆宸ュ彿骞舵煡璇俊鎭�'); + return; + } + + // 妯℃嫙涓婁紶鍥剧墖鍜屾彁浜ゆ暟鎹� + const statusMessage = document.getElementById('status-message'); + statusMessage.innerText = '姝e湪涓婁紶鍥剧墖骞舵彁浜ゆ暟鎹�...'; + + setTimeout(() => { + statusMessage.innerText = '鎻愪氦鎴愬姛锛�'; + }, 2000); // 妯℃嫙涓婁紶寤惰繜 + } + </script> +</body> +</html> \ No newline at end of file diff --git "a/Client/\347\216\213\351\233\250\351\230\263/document/\351\241\271\347\233\256\351\234\200\346\261\202\344\271\2462.0\347\211\210.docx" "b/Client/\347\216\213\351\233\250\351\230\263/document/\351\241\271\347\233\256\351\234\200\346\261\202\344\271\2462.0\347\211\210.docx" new file mode 100644 index 0000000..20310c4 --- /dev/null +++ "b/Client/\347\216\213\351\233\250\351\230\263/document/\351\241\271\347\233\256\351\234\200\346\261\202\344\271\2462.0\347\211\210.docx" Binary files differ diff --git "a/Client/\347\216\213\351\233\250\351\230\263/log/\346\227\245\345\277\227_\347\216\213\351\233\250\351\230\263_250218.doc" "b/Client/\347\216\213\351\233\250\351\230\263/log/\346\227\245\345\277\227_\347\216\213\351\233\250\351\230\263_250218.doc" new file mode 100644 index 0000000..133097d --- /dev/null +++ "b/Client/\347\216\213\351\233\250\351\230\263/log/\346\227\245\345\277\227_\347\216\213\351\233\250\351\230\263_250218.doc" Binary files differ diff --git "a/Client/\347\216\213\351\233\250\351\230\263/log/\347\216\213\351\233\250\351\230\263_250218.doc" "b/Client/\347\216\213\351\233\250\351\230\263/log/\347\216\213\351\233\250\351\230\263_250218.doc" new file mode 100644 index 0000000..27a819f --- /dev/null +++ "b/Client/\347\216\213\351\233\250\351\230\263/log/\347\216\213\351\233\250\351\230\263_250218.doc" Binary files differ diff --git "a/Client/\350\221\243\344\275\263\347\220\246/log/\346\227\245\345\277\227_\350\221\243\344\275\263\347\220\246_0218.doc" "b/Client/\350\221\243\344\275\263\347\220\246/log/\346\227\245\345\277\227_\350\221\243\344\275\263\347\220\246_0218.doc" new file mode 100644 index 0000000..e193b75 --- /dev/null +++ "b/Client/\350\221\243\344\275\263\347\220\246/log/\346\227\245\345\277\227_\350\221\243\344\275\263\347\220\246_0218.doc" Binary files differ diff --git "a/Client/\350\221\243\346\276\216\351\237\254/code/facexmainwindow.cpp" "b/Client/\350\221\243\346\276\216\351\237\254/code/facexmainwindow.cpp" new file mode 100644 index 0000000..4d398d3 --- /dev/null +++ "b/Client/\350\221\243\346\276\216\351\237\254/code/facexmainwindow.cpp" @@ -0,0 +1,204 @@ +#include "facexmainwindow.h" +#include "ui_facexmainwindow.h" + +#include <QMessageBox> +#include <QStringList> +#include <QFileDialog> +#include <QGuiApplication> +#include <QScreen> +#include <QException> +#include <QThread> + +FaceXMainWindow::FaceXMainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::FaceXMainWindow), + m_player(new QMediaPlayer), + m_playerlist(new QMediaPlaylist), + m_videowidget(new QVideoWidget(this)), + m_ffmpeg(new QFFmpeg(this)), + m_rtspThread(nullptr) +{ + ui->setupUi(this); + //璁剧疆鍙Щ鍔ㄥ尯鍩� + dragArea = QRect(0, 0, width(), 40); + setWindowFlags(Qt::FramelessWindowHint);//闅愯棌杈规 + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + + // 璁剧疆鎾斁鎸夐挳鍥炬爣涓烘挱鏀惧浘鏍� + ui->btn_play->setStyleSheet("border-image: url(:/image/start.png)"); + + //璁剧疆鎾斁鍣ㄦ挱鏀鹃槦鍒� + m_player->setPlaylist(m_playerlist); + //璁剧疆鎾斁鍣ㄦ樉绀虹獥鍙� + m_player->setVideoOutput(m_videowidget); + // 璁剧疆鎾斁鍣ㄦ樉绀虹獥鍙� + m_videowidget->resize(ui->label_video->size()); + m_videowidget->move(ui->label_video->pos()); + m_videowidget->show(); + ui->label_video->show(); + + // 杩炴帴 QFFmpeg 鐨勪俊鍙� + connect(m_ffmpeg, &QFFmpeg::GetImage, this, &FaceXMainWindow::SetImage, Qt::QueuedConnection); + + // 杩炴帴鎾斁鍣ㄧ殑閿欒淇″彿 + connect(m_player, QOverload<QMediaPlayer::Error>::of(&QMediaPlayer::error), this, [this](QMediaPlayer::Error error) { + QMessageBox::critical(this, "鎾斁閿欒", m_player->errorString()); + }); + + +} + +FaceXMainWindow::~FaceXMainWindow() +{ + if (m_rtspThread && m_rtspThread->isRunning()) { + m_rtspThread->quit(); + m_rtspThread->wait(); + } + delete ui; +} + +void FaceXMainWindow::mousePressEvent(QMouseEvent *event) +{ + if (dragArea.contains(event->pos())) { + offset = event->globalPos() - pos(); + isDragging = true; + } +} + +void FaceXMainWindow::mouseMoveEvent(QMouseEvent *event) +{ + if (isDragging && dragArea.contains(event->pos())) { + move(event->globalPos() - offset); + } +} + +void FaceXMainWindow::mouseReleaseEvent(QMouseEvent *event) +{ + isDragging = false; +} + +//鏌ヨ鎸夐挳 +void FaceXMainWindow::on_btnSelect_clicked() +{ + QDate dateStart = ui->dateStart->date(); + QDate dateEnd = ui->dateEnd->date(); + + if (dateStart > dateEnd) { + QMessageBox::critical(nullptr, "閿欒", "寮�濮嬫椂闂翠笉鑳藉ぇ浜庣粨鏉熸椂闂�!"); + return; + } + + //灏嗘棩鏈熻浆鎹负鏃ユ湡鏃堕棿璁$畻鐩稿樊鐨勫ぉ鏁�,瓒呰繃60澶╁垯鎻愮ず涓嶇敤缁х画 + QDateTime dateTimeStart = ui->dateStart->dateTime(); + QDateTime dateTimeEnd = ui->dateEnd->dateTime(); + if (dateTimeStart.daysTo(dateTimeEnd) >= 60) { + QMessageBox::critical(nullptr, "閿欒", "姣忔鏈�澶у彧鑳芥煡璇�60澶╁唴!"); + return; + } + + QStringList fileNames = QFileDialog::getOpenFileNames(this, "閫夋嫨鏂囦欢", "D:/", "瑙嗛鏂囦欢 (*.mp4 *.avi *.mov);;鎵�鏈夋枃浠� (*.*)"); + if (!fileNames.isEmpty()) { + m_playerlist->clear(); + m_ffmpeg->SetUrl(fileNames.first()); + if (m_ffmpeg->Init()) { + if (m_rtspThread && m_rtspThread->isRunning()) { + m_rtspThread->quit(); + m_rtspThread->wait(); + } + m_rtspThread = new RtspThread(m_ffmpeg, this); + m_rtspThread->start(); + } + QMessageBox::information(this, "鎴愬姛", "鏂囦欢宸叉坊鍔犲埌鎾斁鍒楄〃"); + } else { + QMessageBox::information(this, "鎻愮ず", "鏈�夋嫨浠讳綍鏂囦欢"); + } +} + +//闅愯棌绐楀彛鎸夐挳 +void FaceXMainWindow::on_toolButton_clicked() +{ + hide(); +} + +//鏈�灏忓寲鎸夐挳 +void FaceXMainWindow::on_toolButton_3_clicked() +{ + showMinimized(); +} + +//鏈�澶у寲鎸夐挳 +void FaceXMainWindow::on_toolButton_2_clicked() +{ + if(windowState() != Qt::WindowMaximized) + { + this->showMaximized(); + } + else + { + this->showNormal(); + } +} + +//榧犳爣鍙屽嚮鏈�澶у寲 +void FaceXMainWindow::mouseDoubleClickEvent(QMouseEvent *event) +{ + if(windowState() != Qt::WindowMaximized) + { + this->showMaximized(); + } + else + { + this->showNormal(); + } +} + +void FaceXMainWindow::setPlayButtonIcon(bool isPlaying) +{ + if (isPlaying) { + ui->btn_play->setStyleSheet("border-image: url(:/image/pause.png)"); + } else { + ui->btn_play->setStyleSheet("border-image: url(:/image/start.png)"); + } +} + +//鎾斁鎸夐挳 +void FaceXMainWindow::on_btn_play_clicked() +{ + if (m_ffmpeg) { + if (!m_rtspThread || !m_rtspThread->isRunning()) { + if (m_ffmpeg->Init()) { + m_rtspThread = new RtspThread(m_ffmpeg, this); + m_rtspThread->start(); + } + } + } else { + QMessageBox::critical(this, "閿欒", "鎾斁鍣ㄦ湭鍒濆鍖�"); + } +} + +//鎴浘鎸夐挳 +void FaceXMainWindow::on_btn_cut_clicked() +{ + QScreen *screen = QGuiApplication::primaryScreen(); + if (screen) { + QPixmap screenshot = screen->grabWindow(this->winId()); + screenshot.save("screenshot.png"); + QMessageBox::information(this, "鎻愮ず", "鎴浘宸蹭繚瀛樹负 screenshot.png"); + } +} + +void FaceXMainWindow::SetImage(const QImage &image) +{ + qDebug() << "鍥惧儚灏哄: " << image.width() << "x" << image.height(); + qDebug() << "鍥惧儚鏍煎紡: " << image.format(); + qDebug() << "鎺ユ敹鍒板浘鍍忎俊鍙�"; + if (!image.isNull()) { + ui->label_video->setScaledContents(true); // 璁剧疆鍥惧儚鑷姩缂╂斁 + ui->label_video->setPixmap(QPixmap::fromImage(image)); + ui->label_video->adjustSize(); + ui->label_video->update(); + qDebug() << "鍥惧儚宸叉洿鏂�"; + } else { + qDebug() << "鎺ユ敹鍒扮殑鍥惧儚涓虹┖"; + } +} diff --git "a/Client/\350\221\243\346\276\216\351\237\254/code/facexmainwindow.h" "b/Client/\350\221\243\346\276\216\351\237\254/code/facexmainwindow.h" new file mode 100644 index 0000000..71a4542 --- /dev/null +++ "b/Client/\350\221\243\346\276\216\351\237\254/code/facexmainwindow.h" @@ -0,0 +1,82 @@ +#ifndef FACEXMAINWINDOW_H +#define FACEXMAINWINDOW_H + +#include <QMainWindow> +#include <QMouseEvent> +#include <QRect> +#include <QMediaPlayer> //鎾斁鍣� +#include <QMediaPlaylist> //鎾斁闃熷垪 +#include <QVideoWidget> //瑙嗛鏄剧ず绐楀彛 +#include "qffmpeg.h" +#include "rtspthread.h" + +//蹇呴』鍔犱互涓嬪唴瀹�,鍚﹀垯缂栬瘧涓嶈兘閫氳繃,涓轰簡鍏煎C鍜孋99鏍囧噯 +#ifndef INT64_C +#define INT64_C +#define UINT64_C +#endif + +//鍥犱负#include <libavcodec/avcodec.h>鏄疌鏂囦欢锛屾墍浠ラ渶瑕佺敤extern +extern "C" +{ +#include <libavcodec/avcodec.h> //瀹炵幇闊宠棰戠殑缂栬В鐮佸姛鑳� +#include <libavformat/avformat.h> //瀹炵幇闊宠棰戞枃浠剁殑璇诲彇鍜屽啓鍏ュ姛鑳斤紝鏀寔澶氱闊宠棰戞牸寮� +#include <libavfilter/avfilter.h> +#include <libswscale/swscale.h> +#include <libavutil/frame.h> +} + +QT_BEGIN_NAMESPACE +namespace Ui { +class FaceXMainWindow; +} +QT_END_NAMESPACE + +class FaceXMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit FaceXMainWindow(QWidget *parent = 0); + ~FaceXMainWindow(); + + void mousePressEvent(QMouseEvent *event)override; + void mouseMoveEvent(QMouseEvent *event)override; + void mouseReleaseEvent(QMouseEvent *event)override; + void mouseDoubleClickEvent(QMouseEvent *event)override; + + +private slots: + void on_btnSelect_clicked(); + + void on_toolButton_clicked(); + + void on_toolButton_3_clicked(); + + void on_toolButton_2_clicked(); + + void on_btn_play_clicked(); + + void on_btn_cut_clicked(); + + void SetImage(const QImage &image); + + +private: + Ui::FaceXMainWindow *ui; + QPoint offset; + + QRect dragArea; + bool isDragging; + + QMediaPlayer *m_player; + QMediaPlaylist *m_playerlist; + QVideoWidget *m_videowidget; + + QFFmpeg *m_ffmpeg; + RtspThread *m_rtspThread; + + void setPlayButtonIcon(bool isPlaying); +}; + +#endif // FACEXMAINWINDOW_H diff --git "a/Client/\350\221\243\346\276\216\351\237\254/code/main.cpp" "b/Client/\350\221\243\346\276\216\351\237\254/code/main.cpp" new file mode 100644 index 0000000..168202d --- /dev/null +++ "b/Client/\350\221\243\346\276\216\351\237\254/code/main.cpp" @@ -0,0 +1,11 @@ +#include "facexmainwindow.h" +#include <QApplication> + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + FaceXMainWindow w; + w.show(); + + return a.exec(); +} diff --git "a/Client/\350\221\243\346\276\216\351\237\254/code/qffmpeg.cpp" "b/Client/\350\221\243\346\276\216\351\237\254/code/qffmpeg.cpp" new file mode 100644 index 0000000..756314e --- /dev/null +++ "b/Client/\350\221\243\346\276\216\351\237\254/code/qffmpeg.cpp" @@ -0,0 +1,113 @@ +#include "qffmpeg.h" +#include <QDateTime> +#include <QDebug> + +QFFmpeg::QFFmpeg(QObject *parent) : + QObject(parent) +{ + videoStreamIndex=-1; + av_register_all();//娉ㄥ唽搴撲腑鎵�鏈夊彲鐢ㄧ殑鏂囦欢鏍煎紡鍜岃В鐮佸櫒 + avformat_network_init();//鍒濆鍖栫綉缁滄祦鏍煎紡,浣跨敤RTSP缃戠粶娴佹椂蹇呴』鍏堟墽琛� + pAVFormatContext = avformat_alloc_context();//鐢宠涓�涓狝VFormatContext缁撴瀯鐨勫唴瀛�,骞惰繘琛岀畝鍗曞垵濮嬪寲 + pAVFrame=av_frame_alloc(); +} + +QFFmpeg::~QFFmpeg() +{ + if (pAVFormatContext) { + avformat_close_input(&pAVFormatContext); + avformat_free_context(pAVFormatContext); + } + if (pAVFrame) { + av_frame_free(&pAVFrame); + } + if (pSwsContext) { + sws_freeContext(pSwsContext); + } + avpicture_free(&pAVPicture); +} + +bool QFFmpeg::Init() +{ + //鎵撳紑瑙嗛娴� + int result=avformat_open_input(&pAVFormatContext, url.toStdString().c_str(),NULL,NULL); + if (result<0){ + qDebug()<<"鎵撳紑瑙嗛娴佸け璐�"; + return false; + } + + //鑾峰彇瑙嗛娴佷俊鎭� + result=avformat_find_stream_info(pAVFormatContext,NULL); + if (result<0){ + qDebug()<<"鑾峰彇瑙嗛娴佷俊鎭け璐�"; + avformat_close_input(&pAVFormatContext); + return false; + } + + //鑾峰彇瑙嗛娴佺储寮� + videoStreamIndex = -1; +// qDebug()<<"nb:"<<pAVFormatContext->nb_streams; +// qDebug()<<"type:"<<pAVFormatContext->streams[0]->codec->codec_type; +// qDebug()<<"AVMEDIA_TYPE_VIDEO:"<<AVMEDIA_TYPE_VIDEO; + for (uint i = 0; i < pAVFormatContext->nb_streams; i++) { + if (pAVFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { + videoStreamIndex = i; + break; + } + } + + if (videoStreamIndex==-1){ + qDebug()<<"鑾峰彇瑙嗛娴佺储寮曞け璐�"; + avformat_close_input(&pAVFormatContext); + return false; + } + + //鑾峰彇瑙嗛娴佺殑鍒嗚鲸鐜囧ぇ灏� + pAVCodecContext = pAVFormatContext->streams[videoStreamIndex]->codec; + videoWidth=pAVCodecContext->width; + videoHeight=pAVCodecContext->height; + + avpicture_alloc(&pAVPicture,AV_PIX_FMT_RGB24,videoWidth,videoHeight); + + AVCodec *pAVCodec; + + //鑾峰彇瑙嗛娴佽В鐮佸櫒 + pAVCodec = avcodec_find_decoder(pAVCodecContext->codec_id); + pSwsContext = sws_getContext(videoWidth,videoHeight,AV_PIX_FMT_YUV420P,videoWidth,videoHeight,AV_PIX_FMT_RGB24,SWS_BICUBIC,0,0,0); + + //鎵撳紑瀵瑰簲瑙g爜鍣� + result=avcodec_open2(pAVCodecContext,pAVCodec,NULL); + if (result<0){ + qDebug()<<"鎵撳紑瑙g爜鍣ㄥけ璐�"; + avpicture_free(&pAVPicture); + sws_freeContext(pSwsContext); + avformat_close_input(&pAVFormatContext); + return false; + } + + qDebug()<<"鍒濆鍖栬棰戞祦鎴愬姛"; + return true; +} + +void QFFmpeg::Play() +{ + //涓�甯т竴甯ц鍙栬棰� + int frameFinished = 0; + while (av_read_frame(pAVFormatContext, &pAVPacket) >= 0) { + if (pAVPacket.stream_index == videoStreamIndex) { + qDebug() << "寮�濮嬭В鐮�" << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"); + avcodec_decode_video2(pAVCodecContext, pAVFrame, &frameFinished, &pAVPacket); + if (frameFinished) { + mutex.lock(); + sws_scale(pSwsContext, (const uint8_t* const *)pAVFrame->data, pAVFrame->linesize, 0, videoHeight, pAVPicture.data, pAVPicture.linesize); + QImage image(pAVPicture.data[0], videoWidth, videoHeight, QImage::Format_RGB888); + QImage copyImage = image.copy(); // 娣辨嫹璐� + emit GetImage(copyImage, this->index); + qDebug() << "瑙g爜鎴愬姛锛屽彂閫佸浘鍍忎俊鍙�"; + mutex.unlock(); + } + } + av_packet_unref(&pAVPacket); + } + avformat_close_input(&pAVFormatContext); +} diff --git "a/Client/\350\221\243\346\276\216\351\237\254/code/qffmpeg.h" "b/Client/\350\221\243\346\276\216\351\237\254/code/qffmpeg.h" new file mode 100644 index 0000000..9085958 --- /dev/null +++ "b/Client/\350\221\243\346\276\216\351\237\254/code/qffmpeg.h" @@ -0,0 +1,63 @@ +#ifndef QFFMPEG_H +#define QFFMPEG_H + +//蹇呴』鍔犱互涓嬪唴瀹�,鍚﹀垯缂栬瘧涓嶈兘閫氳繃,涓轰簡鍏煎C鍜孋99鏍囧噯 +#ifndef INT64_C +#define INT64_C +#define UINT64_C +#endif + +//寮曞叆ffmpeg澶存枃浠� +extern "C" +{ +#include <libavcodec/avcodec.h> +#include <libavformat/avformat.h> +#include <libavfilter/avfilter.h> +#include <libswscale/swscale.h> +#include <libavutil/frame.h> +} + +#include <QObject> +#include <QMutex> +#include <QImage> + +class QFFmpeg : public QObject +{ + Q_OBJECT +public: + explicit QFFmpeg(QObject *parent = 0); + ~QFFmpeg(); + + bool Init(); // 鍒濆鍖� + void Play(); // 鎾斁 + + void SetUrl(QString url){this->url=url;} // 璁剧疆瑙嗛婧� + + QString Url()const{return url;} + int VideoWidth()const{return videoWidth;} + int VideoHeight()const{return videoHeight;} + void SetIndex(int x){this->index=x;} + +private: + QMutex mutex; + AVPicture pAVPicture; + AVFormatContext *pAVFormatContext; + AVCodecContext *pAVCodecContext; + AVFrame *pAVFrame; + SwsContext * pSwsContext; + AVPacket pAVPacket; + + QString url; + int videoWidth; + int videoHeight; + int videoStreamIndex; + int index; + +signals: + void GetImage(const QImage &image,int x); // 鍙戦�佽В鐮佸悗鐨勫浘鍍忎俊鍙� + +public slots: + +}; + +#endif // QFFMPEG_H diff --git "a/Client/\350\221\243\346\276\216\351\237\254/code/rtspthread.cpp" "b/Client/\350\221\243\346\276\216\351\237\254/code/rtspthread.cpp" new file mode 100644 index 0000000..0420869 --- /dev/null +++ "b/Client/\350\221\243\346\276\216\351\237\254/code/rtspthread.cpp" @@ -0,0 +1,13 @@ +#include "rtspthread.h" + +RtspThread::RtspThread(QFFmpeg *ffmpeg,QObject *parent) : + QThread(parent), ffmpeg(ffmpeg) +{ +} + +void RtspThread::run() +{ + if (ffmpeg) { + ffmpeg->Play(); + } +} diff --git "a/Client/\350\221\243\346\276\216\351\237\254/code/rtspthread.h" "b/Client/\350\221\243\346\276\216\351\237\254/code/rtspthread.h" new file mode 100644 index 0000000..3232a8b --- /dev/null +++ "b/Client/\350\221\243\346\276\216\351\237\254/code/rtspthread.h" @@ -0,0 +1,22 @@ +#ifndef RTSPTHREAD_H +#define RTSPTHREAD_H + + +#include <QThread> +#include "qffmpeg.h" + +class RtspThread : public QThread +{ + Q_OBJECT +public: + explicit RtspThread(QFFmpeg *ffmpeg,QObject *parent = 0); + +protected: + void run()override; + +private: + QFFmpeg * ffmpeg; + +}; + +#endif // RTSPTHREAD_H diff --git "a/Client/\350\221\243\346\276\216\351\237\254/log/\346\227\245\345\277\227_\350\221\243\346\276\216\351\237\254_\346\227\245\346\234\237.doc" "b/Client/\350\221\243\346\276\216\351\237\254/log/\346\227\245\345\277\227_\350\221\243\346\276\216\351\237\254_0218.doc" similarity index 100% rename from "Client/\350\221\243\346\276\216\351\237\254/log/\346\227\245\345\277\227_\350\221\243\346\276\216\351\237\254_\346\227\245\346\234\237.doc" rename to "Client/\350\221\243\346\276\216\351\237\254/log/\346\227\245\345\277\227_\350\221\243\346\276\216\351\237\254_0218.doc" Binary files differ diff --git "a/Client/\350\221\243\346\276\216\351\237\254/log/\346\227\245\345\277\227_\350\221\243\346\276\216\351\237\254_0219.doc" "b/Client/\350\221\243\346\276\216\351\237\254/log/\346\227\245\345\277\227_\350\221\243\346\276\216\351\237\254_0219.doc" new file mode 100644 index 0000000..37c4831 --- /dev/null +++ "b/Client/\350\221\243\346\276\216\351\237\254/log/\346\227\245\345\277\227_\350\221\243\346\276\216\351\237\254_0219.doc" Binary files differ diff --git "a/Client/\350\247\243\346\235\245\351\221\253/log/\346\227\245\345\277\227_\345\247\223\345\220\215_\346\227\245\346\234\237.doc" "b/Client/\350\247\243\346\235\245\351\221\253/log/\346\227\245\345\277\227_\345\247\223\345\220\215_\346\227\245\346\234\237.doc" new file mode 100644 index 0000000..0f7e6cd --- /dev/null +++ "b/Client/\350\247\243\346\235\245\351\221\253/log/\346\227\245\345\277\227_\345\247\223\345\220\215_\346\227\245\346\234\237.doc" Binary files differ diff --git "a/Client/\351\203\255\346\226\207\345\274\272/document/\346\226\260\351\234\200\346\261\202\345\212\237\350\203\275\350\247\204\346\240\274\350\257\264\346\230\216\344\271\246.docx" "b/Client/\351\203\255\346\226\207\345\274\272/document/\346\226\260\351\234\200\346\261\202\345\212\237\350\203\275\350\247\204\346\240\274\350\257\264\346\230\216\344\271\246 - \351\203\255\346\226\207\345\274\272.docx" similarity index 100% rename from "Client/\351\203\255\346\226\207\345\274\272/document/\346\226\260\351\234\200\346\261\202\345\212\237\350\203\275\350\247\204\346\240\274\350\257\264\346\230\216\344\271\246.docx" rename to "Client/\351\203\255\346\226\207\345\274\272/document/\346\226\260\351\234\200\346\261\202\345\212\237\350\203\275\350\247\204\346\240\274\350\257\264\346\230\216\344\271\246 - \351\203\255\346\226\207\345\274\272.docx" Binary files differ diff --git "a/Client/\351\203\255\346\226\207\345\274\272/log/\351\203\255\346\226\207\345\274\272_20250218.doc" "b/Client/\351\203\255\346\226\207\345\274\272/log/\351\203\255\346\226\207\345\274\272_20250218.doc" new file mode 100644 index 0000000..8175193 --- /dev/null +++ "b/Client/\351\203\255\346\226\207\345\274\272/log/\351\203\255\346\226\207\345\274\272_20250218.doc" Binary files differ diff --git "a/Client/\351\203\255\346\226\207\345\274\272/log/\351\203\255\346\226\207\345\274\272_20250219.doc" "b/Client/\351\203\255\346\226\207\345\274\272/log/\351\203\255\346\226\207\345\274\272_20250219.doc" new file mode 100644 index 0000000..576ec99 --- /dev/null +++ "b/Client/\351\203\255\346\226\207\345\274\272/log/\351\203\255\346\226\207\345\274\272_20250219.doc" Binary files differ diff --git "a/ProjectInformation/1.2\351\241\271\347\233\256\350\277\233\345\272\246\350\241\250.et" "b/ProjectInformation/1.2\351\241\271\347\233\256\350\277\233\345\272\246\350\241\250.et" index 13267bc..ca4f8aa 100644 --- "a/ProjectInformation/1.2\351\241\271\347\233\256\350\277\233\345\272\246\350\241\250.et" +++ "b/ProjectInformation/1.2\351\241\271\347\233\256\350\277\233\345\272\246\350\241\250.et" Binary files differ diff --git "a/Server/\345\206\211\345\207\257/document/\346\227\245\345\277\227_\345\206\211\345\207\257_20250218.doc" "b/Server/\345\206\211\345\207\257/document/\346\227\245\345\277\227_\345\206\211\345\207\257_20250218.doc" new file mode 100644 index 0000000..2506676 --- /dev/null +++ "b/Server/\345\206\211\345\207\257/document/\346\227\245\345\277\227_\345\206\211\345\207\257_20250218.doc" Binary files differ diff --git "a/Server/\345\206\211\345\207\257/log/\346\227\245\345\277\227_\345\206\211\345\207\257_20250219.doc" "b/Server/\345\206\211\345\207\257/log/\346\227\245\345\277\227_\345\206\211\345\207\257_20250219.doc" new file mode 100644 index 0000000..2abf5e1 --- /dev/null +++ "b/Server/\345\206\211\345\207\257/log/\346\227\245\345\277\227_\345\206\211\345\207\257_20250219.doc" Binary files differ diff --git "a/Server/\345\215\242\346\225\217/log/\346\227\245\345\277\227_\345\215\242\346\225\217_2.18.doc" "b/Server/\345\215\242\346\225\217/log/\346\227\245\345\277\227_\345\215\242\346\225\217_2.18.doc" new file mode 100644 index 0000000..0c4571d --- /dev/null +++ "b/Server/\345\215\242\346\225\217/log/\346\227\245\345\277\227_\345\215\242\346\225\217_2.18.doc" Binary files differ diff --git "a/Server/\345\215\242\346\225\217/log/\346\227\245\345\277\227_\345\215\242\346\225\217_2.19.doc" "b/Server/\345\215\242\346\225\217/log/\346\227\245\345\277\227_\345\215\242\346\225\217_2.19.doc" new file mode 100644 index 0000000..4318431 --- /dev/null +++ "b/Server/\345\215\242\346\225\217/log/\346\227\245\345\277\227_\345\215\242\346\225\217_2.19.doc" Binary files differ diff --git "a/Server/\345\274\240\346\225\217\344\270\275/document/\346\227\245\345\277\227_\345\247\223\345\220\215_\346\227\245\346\234\237.doc" "b/Server/\345\274\240\346\225\217\344\270\275/document/\346\227\245\345\277\227_\345\247\223\345\220\215_\346\227\245\346\234\237.doc" new file mode 100644 index 0000000..3fcca84 --- /dev/null +++ "b/Server/\345\274\240\346\225\217\344\270\275/document/\346\227\245\345\277\227_\345\247\223\345\220\215_\346\227\245\346\234\237.doc" Binary files differ -- Gitblit v1.8.0