吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2262|回复: 18
收起左侧

[C&C++ 原创] 基于QT和opencv的视频播放器

  [复制链接]
海军 发表于 2023-4-22 18:06
CMakeLists.txt
[Asm] 纯文本查看 复制代码
cmake_minimum_required(VERSION 3.5)

project(player VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(OpenCV_DIR "/usr/local/include/opencv4")
set(OpenCV_LIBS opencv_core opencv_imgproc opencv_highgui opencv_imgcodecs)

find_package(OpenCV REQUIRED)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)


set(PROJECT_SOURCES
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(${PROJECT_NAME}
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
    )
# Define target properties for Android with Qt 6 as:
#    set_property(TARGET player APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
    if(ANDROID)
        add_library(${PROJECT_NAME} SHARED
            ${PROJECT_SOURCES}
        )
# Define properties for Android with Qt 5 after find_package() calls as:
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    else()
        add_executable(${PROJECT_NAME}
            ${PROJECT_SOURCES}
        )
    endif()
endif()

include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets ${OpenCV_LIBS})

set_target_properties(${PROJECT_NAME} PROPERTIES
    MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

install(TARGETS ${PROJECT_NAME}
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(${PROJECT_NAME})
endif()


mainwindow.h
[C++] 纯文本查看 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMessageBox>
#include <QFileDialog>
#include <opencv2/opencv.hpp>
#include <QTimer>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void showFrame(const cv::Mat &frame);

private slots:
    void on_playButton_clicked();

    void on_stopButton_clicked();
    void choose_video_file();

    void on_horizontalSlider_sliderMoved(int position);
    void importFrame();

private:
    Ui::MainWindow *ui;
    cv::VideoCapture capture;
    QString file_name;
    qint64 position=50;
    QTimer *timer;
    cv::Mat frame;
    int video_width=0;
    int video_height=0;
    double duration=0;
    int total_frames=0;
    double fps = 0;
};
#endif // MAINWINDOW_H


mainwindow.cpp
[C++] 纯文本查看 复制代码
#include "mainwindow.h"
#include "./ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QRect rect =  ui->label->geometry();
    video_width = rect.width();
    video_height = rect.height();
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(importFrame()));
    connect(ui->action, SIGNAL(triggered()), this, SLOT(choose_video_file()));


}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_playButton_clicked()
{
    if (file_name.isEmpty()) {
        QMessageBox::warning(this, "警告", "请选择文件再播放");
    }else{
        capture = cv::VideoCapture(file_name.toStdString());
        if (!capture.isOpened()){
            QMessageBox::critical(this, tr("严重警告"), tr("这个视频文件有问题"));
        }
        total_frames = (int)capture.get(cv::CAP_PROP_FRAME_COUNT);
        fps = capture.get(cv::CAP_PROP_FPS);
        duration = total_frames / fps;
        ui->horizontalSlider->setMaximum(duration);
        capture.set(cv::CAP_PROP_POS_FRAMES, position);
        timer->start(30);
    }
}


void MainWindow::on_stopButton_clicked()
{
    timer->stop();
}


void MainWindow::on_horizontalSlider_sliderMoved(int position)
{
    qDebug()<<position;
    ui->horizontalSlider->setSliderPosition(position / fps);
    capture.set(cv::CAP_PROP_POS_FRAMES, position);
    timer->start(30);
}

void MainWindow::showFrame(const cv::Mat &frame){
    cv::Mat rgb;
    cv::cvtColor(frame, rgb, cv::COLOR_BGR2RGB);
    QImage image((uchar*)rgb.data, rgb.cols, rgb.rows, rgb.step, QImage::Format_RGB888);
    ui->label->setPixmap(QPixmap::fromImage(image));
}

void MainWindow::importFrame()
{
    capture >> frame;
    if (!frame.empty()){
        position = capture.get(cv::CAP_PROP_POS_FRAMES);
        ui->horizontalSlider->setSliderPosition(position / fps);
        cv::flip(frame,frame,180);
        cvtColor(frame, frame, cv::COLOR_BGR2RGB);
        QImage srcQImage = QImage((uchar*)(frame.data), frame.cols, frame.rows, QImage::Format_RGB888);
        QPixmap pix_map = QPixmap::fromImage(srcQImage);
        pix_map = pix_map.scaled(800, 600);
        ui->label->setPixmap(pix_map);
        ui->label->show();
    }
}


void MainWindow::choose_video_file(){
    file_name = QFileDialog::getOpenFileName(
        this,
        tr("open a file."),
        ".",
        tr("video files(*.avi *.mp4 *.wmv *.flv *.mpeg *.m4v *.mov *.asf *.f4v *.rmvb *.rm *.3gp *.ogv)"));
    if (file_name.isEmpty()) {
        QMessageBox::warning(this, "警告", "请选择文件再播放");
    }
}




mainwindow.ui
[XML] 纯文本查看 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>428</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout_2">
    <item>
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <widget class="QLabel" name="label">
        <property name="text">
         <string/>
        </property>
       </widget>
      </item>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout">
        <item>
         <widget class="QPushButton" name="playButton">
          <property name="text">
           <string>Play</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QPushButton" name="stopButton">
          <property name="text">
           <string>Stop</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QSlider" name="horizontalSlider">
          <property name="maximum">
           <number>100</number>
          </property>
          <property name="orientation">
           <enum>Qt::Horizontal</enum>
          </property>
         </widget>
        </item>
       </layout>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>27</height>
    </rect>
   </property>
   <widget class="QMenu" name="menu">
    <property name="title">
     <string>文件</string>
    </property>
    <addaction name="action"/>
   </widget>
   <addaction name="menu"/>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <action name="action">
   <property name="text">
    <string>打开视频文件</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections/>
</ui>


main.cpp
[C++] 纯文本查看 复制代码
#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

免费评分

参与人数 3吾爱币 +9 热心值 +3 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
KING912 + 1 + 1 我很赞同!
wanfon + 1 + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 海军 发表于 2023-4-22 20:40
urdarling 发表于 2023-4-22 20:17
着岂不是编译一下直接就可以用了

是的,直接编译就可以用了,不过提前要搭建好opencv和Qt环境,将cmaklist文件里的opencv路径改成你自己安装opencv的路径即可
雾都孤尔 发表于 2023-4-22 18:27
sdieedu 发表于 2023-4-22 20:08
urdarling 发表于 2023-4-22 20:17
着岂不是编译一下直接就可以用了
52spress 发表于 2023-4-22 20:57
学习一下。
Gxiaojia 发表于 2023-4-22 20:58
膜拜大佬  学习一下
lijiyu 发表于 2023-4-22 22:11
大佬牛逼,视频播放有声音吗
wuailaoyan 发表于 2023-4-22 23:02
感谢分享,学习了。
tbloy 发表于 2023-4-23 00:13
做视频行业的,过来学习一下。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 18:58

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表