dpt
2025-02-21 475b9b1187de24bf8d38db31c64f26c7977c3fd8
2.20更新
5个文件已修改
2个文件已添加
1个文件已删除
203 ■■■■ 已修改文件
Client/董澎韬/code/facexmainwindow.cpp 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/董澎韬/code/facexmainwindow.h 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/董澎韬/code/form.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/董澎韬/code/main.cpp 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/董澎韬/code/qffmpeg.cpp 96 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/董澎韬/code/qffmpeg.h 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Client/董澎韬/code/存放代码.txt 补丁 | 查看 | 原始文档 | blame | 历史
Client/董澎韬/log/日志_董澎韬_0220.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/¶­Åìèº/code/facexmainwindow.cpp
@@ -8,6 +8,7 @@
#include <QScreen>
#include <QException>
#include <QThread>
#include <QWheelEvent>
FaceXMainWindow::FaceXMainWindow(QWidget *parent) :
    QMainWindow(parent),
@@ -35,7 +36,7 @@
    m_videowidget->resize(ui->label_video->size());
    m_videowidget->move(ui->label_video->pos());
    m_videowidget->show();
    ui->label_video->show();
    ui->label_video->hide();
    // è¿žæŽ¥ QFFmpeg çš„信号
    connect(m_ffmpeg, &QFFmpeg::GetImage, this, &FaceXMainWindow::SetImage, Qt::QueuedConnection);
@@ -45,6 +46,9 @@
        QMessageBox::critical(this, "播放错误", m_player->errorString());
    });
    // è¿žæŽ¥æ’­æ”¾å™¨çš„位置更新信号
    connect(m_player, &QMediaPlayer::positionChanged, this, &FaceXMainWindow::updateSliderPosition);
    connect(ui->horizontalSlider, &QSlider::sliderMoved, this, &FaceXMainWindow::on_sliderPosition_valueChanged);
}
@@ -161,6 +165,18 @@
    }
}
void FaceXMainWindow::playOrPause()
{
    isPlaying = !isPlaying;
    if (isPlaying) {
        m_player->play();
        ui->btn_play->setStyleSheet("border-image: url(:/image/pause.png)");
    } else {
        m_player->pause();
        ui->btn_play->setStyleSheet("border-image: url(:/image/start.png)");
    }
}
//播放按钮
void FaceXMainWindow::on_btn_play_clicked()
{
@@ -171,6 +187,7 @@
                m_rtspThread->start();
            }
        }
        playOrPause();
    } else {
        QMessageBox::critical(this, "错误", "播放器未初始化");
    }
@@ -189,16 +206,36 @@
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() << "接收到的图像为空";
    }
}
//更新滑块的位置
void FaceXMainWindow::updateSliderPosition()
{
    ui->horizontalSlider->setValue(m_player->position());
}
//拖动滑块来控制播放进度
void FaceXMainWindow::on_sliderPosition_valueChanged(int value)
{
    m_player->setPosition(value);
}
void FaceXMainWindow::on_btn_back_clicked()
{
    int currentPosition = m_player->position();
    m_player->setPosition(currentPosition - 10000); // åŽé€€ 10 ç§’
}
void FaceXMainWindow::on_btn_forward_clicked()
{
    int currentPosition = m_player->position();
    m_player->setPosition(currentPosition + 10000); // å‰è¿› 10 ç§’
}
Client/¶­Åìèº/code/facexmainwindow.h
@@ -45,22 +45,19 @@
    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);
    void updateSliderPosition();
    void on_sliderPosition_valueChanged(int value);
    void on_btn_back_clicked();
    void on_btn_forward_clicked();
private:
    Ui::FaceXMainWindow *ui;
@@ -76,7 +73,10 @@
    QFFmpeg *m_ffmpeg;
    RtspThread *m_rtspThread;
    bool isPlaying = false;
    void setPlayButtonIcon(bool isPlaying);
    void playOrPause();
};
#endif // FACEXMAINWINDOW_H
Client/¶­Åìèº/code/form.h
New file
@@ -0,0 +1,22 @@
#ifndef FORM_H
#define FORM_H
#include <QWidget>
namespace Ui {
class Form;
}
class Form : public QWidget
{
    Q_OBJECT
public:
    explicit Form(QWidget *parent = 0);
    ~Form();
private:
    Ui::Form *ui;
};
#endif // FORM_H
Client/¶­Åìèº/code/main.cpp
@@ -7,5 +7,11 @@
    FaceXMainWindow w;
    w.show();
    //    SDL验证
    //    SDL_version version;
    //    SDL_VERSION(&version);
    //    qDebug()<<"version major is"<<version.major;
    //    qDebug()<<"version minor is"<<version.minor;
    return a.exec();
}
Client/¶­Åìèº/code/qffmpeg.cpp
@@ -24,7 +24,6 @@
    if (pSwsContext) {
        sws_freeContext(pSwsContext);
    }
    avpicture_free(&pAVPicture);
}
bool QFFmpeg::Init()
@@ -46,9 +45,6 @@
    //获取视频流索引
    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;
@@ -67,8 +63,6 @@
    videoWidth=pAVCodecContext->width;
    videoHeight=pAVCodecContext->height;
    avpicture_alloc(&pAVPicture,AV_PIX_FMT_RGB24,videoWidth,videoHeight);
    AVCodec *pAVCodec;
    //获取视频流解码器
@@ -79,7 +73,6 @@
    result=avcodec_open2(pAVCodecContext,pAVCodec,NULL);
    if (result<0){
        qDebug()<<"打开解码器失败";
        avpicture_free(&pAVPicture);
        sws_freeContext(pSwsContext);
        avformat_close_input(&pAVFormatContext);
        return false;
@@ -91,23 +84,82 @@
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() << "解码成功,发送图像信号";
                mutex.unlock();
    AVPacket packet;
    int frameFinished;
    int videoStreamIndex = -1;
    // æ‰“开视频文件
    if (avformat_open_input(&pAVFormatContext, url.toStdString().c_str(), NULL, NULL) != 0)
        return;
    // èŽ·å–æµä¿¡æ¯
    avformat_find_stream_info(pAVFormatContext, NULL);
    // æ‰¾åˆ°è§†é¢‘流索引
    for (uint i = 0; i < pAVFormatContext->nb_streams; i++) {
        if (pAVFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
            break;
        }
    }
    // èŽ·å–è§£ç å™¨
    AVCodec *codec = avcodec_find_decoder(pAVFormatContext->streams[videoStreamIndex]->codec->codec_id);
    if (!codec) {
        qDebug() << "未找到解码器";
        return;
    }
    if (avcodec_open2(pAVCodecContext, codec, NULL) < 0) {
        qDebug() << "打开解码器失败";
        return;
    }
    // åˆå§‹åŒ–帧
    pAVFrame = av_frame_alloc();
    AVFrame *pFrameRGB = av_frame_alloc();
    uint8_t *buffer = (uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_RGB24, pAVCodecContext->width, pAVCodecContext->height));
    avpicture_fill((AVPicture *)pFrameRGB, buffer, AV_PIX_FMT_RGB24, pAVCodecContext->width, pAVCodecContext->height);
    // åˆå§‹åŒ–缩放上下文
    struct SwsContext *sws_ctx = sws_getContext(pAVCodecContext->width,
                                                pAVCodecContext->height,
                                                pAVCodecContext->pix_fmt,
                                                pAVCodecContext->width,
                                                pAVCodecContext->height,
                                                AV_PIX_FMT_RGB24,
                                                SWS_BILINEAR,
                                                NULL,
                                                NULL,
                                                NULL);
    while (av_read_frame(pAVFormatContext, &packet) >= 0) {
        if (packet.stream_index == videoStreamIndex) {
            avcodec_send_packet(pAVCodecContext, &packet);
            while (avcodec_receive_frame(pAVCodecContext, pAVFrame) == 0) {
                sws_scale(sws_ctx,
                        (const uint8_t **)pAVFrame->data,
                        pAVFrame->linesize,
                        0,
                        pAVCodecContext->height,
                        pFrameRGB->data,
                        pFrameRGB->linesize);
                QImage img(pFrameRGB->data[0],
                        pAVCodecContext->width,
                        pAVCodecContext->height,
                        QImage::Format_RGB888);
                emit GetImage(img, 0);
            }
        }
        av_packet_unref(&pAVPacket);
        av_packet_unref(&packet);
    }
    avformat_close_input(&pAVFormatContext);
    av_frame_free(&pAVFrame);
    av_frame_free(&pFrameRGB);
    av_free(buffer);
    sws_freeContext(sws_ctx);
}
Client/¶­Åìèº/code/qffmpeg.h
@@ -10,12 +10,19 @@
//引入ffmpeg头文件
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>     //实现音视频的编解码功能
#include <libavformat/avformat.h>   //实现音视频文件的读取和写入功能,支持多种音视频格式
#include <libavfilter/avfilter.h>
#include <libswscale/swscale.h>
#include <libavutil/frame.h>
#include <libavutil/imgutils.h>
}
// å¼•å…¥SDL2头文件
//extern "C"
//{
//   #include "SDL.h"
//}
#include <QObject>
#include <QMutex>
@@ -53,10 +60,13 @@
    int videoStreamIndex;
    int index;
    // SDL相关
//    SDL_Window *sdlWindow;
//    SDL_Renderer *sdlRenderer;
//    SDL_Texture *sdlTexture;
signals:
    void GetImage(const QImage &image,int x);    // å‘送解码后的图像信号
public slots:
};
Client/¶­Åìèº/code/´æ·Å´úÂë.txt
Client/¶­Åìèº/log/ÈÕÖ¾_¶­Åìèº_0220.doc
Binary files differ