Qt 基于FFmpeg的视频播放器 - QtFFmpegPlayer

引言

在这里插入图片描述

  • 本文基于FFmpeg,使用Qt制作了一个极简的视频播放器. 如上所示:
  • FFmpeg版本信息:ffmpeg-n7.0-latest-win64-lgpl-shared-7.0

FFmpeg是一个开源的跨平台音视频处理工具,它提供了音视频编解码、格式转换、流媒体处理等功能。FFmpeg可以在命令行中使用,也可以通过API集成到其他应用程序中使用。FFmpeg支持众多音视频编码格式,如MP3、AAC、AC3、H.264、MPEG-4等。它可以将不同格式的音视频文件转换为其他格式,从而满足不同设备和平台的需求。除了转换格式,FFmpeg还可以进行音视频的剪切、合并、裁剪、旋转等操作。它可以提取音频或视频流,并且支持添加字幕、水印等特效。在流媒体处理方面,FFmpeg可以通过RTMP、HLS、UDP等协议进行直播推流和播放。它可以将本地音视频流推送到流媒体服务器,也可以从流媒体服务器拉取音视频流进行播放。FFmpeg是一个功能强大且灵活的音视频处理工具,被广泛应用于视频编辑、媒体转换、流媒体服务等领域。它的开源特性使得开发者可以自由定制和扩展功能,同时也极大地方便了用户在不同平台上进行音视频处理。

一、设计思路

参考以下博客:
【Qt+FFmpeg】解码播放本地视频(一):https://blog.youkuaiyun.com/logani/article/details/127233337
版本信息如下:

1.1 FFmpegVideo类

FFmpeg视频类,主要针对视频文件 (暂不包含音频):设计用来调用FFmpeg视频相关API,编解码以及各式转换等

  • 设计一些变量存储视频信息,主要涉及视频的读取、播放等
  • 设计函数进行视频处理 (解码、转换等) - 封装FFmpeg API

1.2 视频打开与播放函数 (本文重点)

1. 视频打开(获取相关信息):

  • 首先获取AVFormatContext,视频的上下文格式,里面包含视频的各种信息
  • 通过AVFormatContext获取视频流编号和编码器idcodec_id
  • 根据编码器id获取相应的解码器AVCodec,初始化编解码器AVCodecContext
  • 通过编解码器AVCodecContext获取视频帧率 m_fps

2. 视频播放 (循环解码即可):

  • 变量以及缓冲区初始化
  • 使用av_read_frame顺序读取AVFormatContext中一帧数据AVPacket
  • 如果是视频流即用avcodec_send_packet解码,avcodec_receive_frame获取解码输出
  • 使用sws_scale进行将一帧图片转换为RGB格式,赋值到QImage
  • 发送赋值后的QImage到相应的显示窗口 (信号和槽)
  • 根据视频帧率m_fps,使用QThread::msleep延时 (或使用QTimer等实现延时效果)

/todo 视频格式的转换等

1.3 播放线程

在主窗体里创建播放线程:QThread * m_PlayThread;

  • 初始化播放线程,将FFmpegVideo移动到线程中
  • 绑定线程的开始信号FFmpegVideo播放槽函数
  • 启动线程即可播放视频 (需要先读取视频文件)

还可以直接将FFmpegVideo设计为继承QThead,将视频播放的代码放到run()函数即可

1.4 播放窗口

新建一个窗口,继承QWidget

  • 创建接收图片的槽函数,保存接收的图片,然后刷新界面update()
  • 重新实现paintEvent窗体重绘函数,将槽函数接收到的图片画在界面上drawImage

需要绑定FFmpeg发送图片的信号 和 界面中接收图片的槽函数

二、核心源码

2.1 FFmpegVideo类

  • ffmpegvideo.h
#ifndef FFMPEGVIDEO_H
#define FFMPEGVIDEO_H

#include <QString>
#include <QObject>
#include <QImage>

// FFmpeg头文件
extern "C"{
   
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavdevice/avdevice.h>
#include <libavutil/avutil.h>
#include <libavutil/imgutils.h>
#include "libswresample/swresample.h"
}

class FFmpegVideo : public QObject
{
   
    Q_OBJECT

public:
    /**
     * @brief FFmpegVideo构造函数
     */
    FFmpegVideo();

    ~FFmpegVideo();


public:  // 值
    QString m_filename;  ///< 文件名

    AVFormatContext* avformat_context;  ///< 视频文件上下文格式
    AVCodecContext* avcodec_context;    ///< 编解码器上下文格式
    int av_stream_index;                ///< 保存视频流的索引
    int m_fps;           ///< 帧率
    int m_frame_id;      ///< 当前帧id
    bool m_stop;         ///< 是否暂停

public:  // 函数
    /**
     * @brief  加载视频
     * @param filename
     * @return
     */
    bool loadVideoFile(QString filename);

public slots:
    /**
     * @brief 播放视频
     */
    void play();

signals:
    void sig_SendOneFrame(QImage image);  ///< 发送一帧
};

#endif // FFMPEGVIDEO_H

  • ffmpegvideo.cpp
#include "ffmpegvideo.h"
#include <QDebug>
#include <QThread>

FFmpegVideo::FFmpegVideo(){
   

}

FFmpegVideo::~FFmpegVideo(){
   

}

bool FFmpegVideo::loadVideoFile(QString filename){
   

    this->m_filename = filename;
    char* error_info = new char[32];     //异常信息

    // 获取视频文件格式
    avformat_context = a
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

das白

感谢认可!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值