ffmpeg播放器1

141 阅读4分钟

背景

  • 自从三月停止snmp后,一直在学ffmpeg,翻了微信读书上的有关书,但是还是不知道从哪入手。
  • 腾讯元宝给出的建议是先从播放器入手。
  • 一开始是在安卓上使用termux尝试,ffmpeg还是没尝试成功
  • 之后在腾讯云买了云主机,安装了ubuntu server之后,安卓手机上安装了termux,通过ssh连接到ubuntu,使用vim 编码运行,获取到文件流(见下文)。
  • 之后想看播放后的效果,使用ffplay等试了各种办法(x11等方法),还是没法在手机上播放,之后就放弃尝试继续(尝试的基础在于看到希望)
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <libavutil/error.h>
#include <ostream>
#include <cstring>
#include <string>
#include <sys/types.h>
extern "C"{
#include "libavformat/avformat.h"
}
#include <linux/limits.h>
#include <unistd.h>
void showlog(std::string m){
    std::cout<<m<<std::endl;
}
std::string getExecPath(){
    char buffer[PATH_MAX];
    ssize_t len=readlink("/proc/self/exe",buffer, sizeof(buffer)-1);
    if (len==-1) {
        return "";
    }
    buffer[len]='\0';

    char *pos=strrchr(buffer,'/');
    if (pos!=nullptr) {
        *pos='\0';
    }else {
        return "";
    }
    return std::string(buffer);
}
int main(){
    std::cout<<"xplayer start "<<std::endl;
    AVFormatContext *fctx=NULL;
    std::string filename=getExecPath()+"/data/input.mp4";
    int openresult=avformat_open_input(&fctx,filename.c_str(), NULL, NULL);
    if (openresult<0) {
        showlog("error");
        exit(1); 
    }

    int findstream=avformat_find_stream_info(fctx, nullptr);
    
    
   if (findstream<0) {
        showlog("not found stram");
       exit(1);
   } 
    showlog("success");
    return 0;
}

github.com/xcyxiner/xp…

root@VM-12-4-ubuntu:/home/ubuntu/xcyxiner/xplay# ./build/xplayer
xplayer
success

直到昨天在腾讯元宝上找到如下记录,感觉自己又能作死了

#### **1. 入门实战首选:hplayer开源播放器项目​****理由**​:

-**技术栈匹配**​:采用C++核心框架(Qt+FFmpeg+OpenGL),覆盖音视频开发全流程(解封装、解码、渲染),符合刚转C++的工程化学习需求。
-**项目结构清晰**​:代码分层明确(界面层、编解码层、渲染层),适合理解音视频处理流程。
-**学习路径指导**​:提供从播放器架构到FFmpeg进阶的递进式学习建议,避免盲目踩坑。
-**实战价值**​:通过调试编译错误、优化播放性能等,快速积累C++音视频调试经验。

​**学习步骤**​:

1.  先掌握Qt界面开发基础(信号槽机制、多线程通信)。
1.  结合FFmpeg官方文档,理解`avformat_open_input``avcodec_send_packet`等核心API用法。
1.  尝试扩展功能:添加字幕支持、实现倍速播放。

直接上地址 github.com/ithewei/hpl…

2 qt安装

因为电脑是window系统,所以当前只考虑window的,除非没法用,再考虑 ubuntu虚拟机

github.com/ithewei/hpl… 使用的是 qt5.11,现在官网安装包只能下到 qt6 下载地址,凑合使用(qt5 windows的得使用源码安装,有必要的时候再尝试) www.qt.io/download-qt…

image.png

3 qt教程

官方的教程有一些例子 doc.qt.io/qt-6/zh/qte…

先抄一个表单的例子 doc.qt.io/qt-6/zh/qtd…

image.png 这个是对应的源码的地址 code.qt.io/cgit/qt/qtt…

3.1 CalculatorForm 新建项目 qt widget

image.png

这里选择 widgets 然后下一步,名称可以用上面CalculatorForm,然后再下一步

image.png

构建这里选择用qmake(抄旧的就不用cmake了),然后再下一步

image.png

这里classname改为CalculatorForm,base class 改为 QWidget,就为了跟例子抄成一样的,之后下一步到结束

3.2 CalculatorForm 添加控件,并修改名称

双击calculatorform.ui(如下图位置)

image.png

打开的页面如下所示,控件盒子的垂直滚动条可以拖到最下面

image.png

Demo里的还有布局,这里就不添加布局了,直接拖label和spinbox到界面上,如下所示

image.png

在label上双击并输入对应的文字,修改后的效果如下所示

Input1 + Input2 = Output 0

image.png

再在右侧,先点击中间的输入框,再双击对象名,并修改为inputSpinBox1(就是为了跟Demo抄一样的)

image.png

修改后的效果如下 image.png

另一个输入框改为 inputSpinBox2,修改后的效果如下

image.png

最后一个是output下面的输出label,修改为 outputWidget

image.png

3.3 信号槽连接

私有槽 updateResult doc.qt.io/qt-6/zh/qtd…

这里的例子有如下内容

image.png

点击左侧的编辑回到代码页面 image.png

双击头文件 calculatorform.h

image.png

然后添加私有槽updateResult

private slots:
    void updateResult();

最终结果如下所示

image.png

选中updateResult,右键,重构,在xxx中添加定义

image.png

点击后的效果如下所示 image.png

先关联信号和槽(输入框的文本改变事件,关联到当前对象的updateResult上,两个输入框的事件都要关联)

    connect(ui->inputSpinBox1,&QSpinBox::valueChanged,this,&CalculatorForm::updateResult);
    connect(ui->inputSpinBox2,&QSpinBox::valueChanged,this,&CalculatorForm::updateResult);

image.png

插槽updateResult的具体内容如下

    const int sum=ui->inputSpinBox1->value()+ui->inputSpinBox2->value();
    ui->outputWidget->setText(QString::number(sum));

image.png

3.4 运行后的效果如下

image.png

版本库如下 github.com/xcyxiner/qt…

4 hplayer 下一篇再添加页面