背景
- 自从三月停止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;
}
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…
3 qt教程
官方的教程有一些例子 doc.qt.io/qt-6/zh/qte…
先抄一个表单的例子 doc.qt.io/qt-6/zh/qtd…
这个是对应的源码的地址
code.qt.io/cgit/qt/qtt…
3.1 CalculatorForm 新建项目 qt widget
这里选择 widgets 然后下一步,名称可以用上面CalculatorForm,然后再下一步
构建这里选择用qmake(抄旧的就不用cmake了),然后再下一步
这里classname改为CalculatorForm,base class 改为 QWidget,就为了跟例子抄成一样的,之后下一步到结束
3.2 CalculatorForm 添加控件,并修改名称
双击calculatorform.ui(如下图位置)
打开的页面如下所示,控件盒子的垂直滚动条可以拖到最下面
Demo里的还有布局,这里就不添加布局了,直接拖label和spinbox到界面上,如下所示
在label上双击并输入对应的文字,修改后的效果如下所示
Input1 + Input2 = Output 0
再在右侧,先点击中间的输入框,再双击对象名,并修改为inputSpinBox1(就是为了跟Demo抄一样的)
修改后的效果如下
另一个输入框改为 inputSpinBox2,修改后的效果如下
最后一个是output下面的输出label,修改为 outputWidget
3.3 信号槽连接
私有槽 updateResult doc.qt.io/qt-6/zh/qtd…
这里的例子有如下内容
点击左侧的编辑回到代码页面
双击头文件 calculatorform.h
然后添加私有槽updateResult
private slots:
void updateResult();
最终结果如下所示
选中updateResult,右键,重构,在xxx中添加定义
点击后的效果如下所示
先关联信号和槽(输入框的文本改变事件,关联到当前对象的updateResult上,两个输入框的事件都要关联)
connect(ui->inputSpinBox1,&QSpinBox::valueChanged,this,&CalculatorForm::updateResult);
connect(ui->inputSpinBox2,&QSpinBox::valueChanged,this,&CalculatorForm::updateResult);
插槽updateResult的具体内容如下
const int sum=ui->inputSpinBox1->value()+ui->inputSpinBox2->value();
ui->outputWidget->setText(QString::number(sum));
3.4 运行后的效果如下
版本库如下 github.com/xcyxiner/qt…