• 2603阅读
  • 2回复

QT 实现jpg/png和mp3/aac编码合成mp4视频文件工具 [复制链接]

上一主题 下一主题
离线xiaoke123
 

图酷模式  只看楼主 倒序阅读 楼主  发表于: 2021-01-27
实现的基本功能:
1.支持单线程按顺序执行多任务
2.支持线程池多线程并发执行任务
3.支持文件类型、文件图标判断
4.支持图片(jpg/png)和音频(mp3/aac)ffmpeg合成mp4文件
5.支持视频文件预览播放(ffmpeg解码)
6.支持简单编码参数选择,如:帧率、分辨率、编码格式
7.同时支持ffmpeg命令行方式或ffmpeg API方式调用

线程池最大2线程并发处理10个任务效果:

线程池最大5线程并发处理10任务效果:

预览合成视频效果:


部分核心代码如下:
  1.     // 多线程并发合成视频
  2.     QString fileName,picName,mp4Name,spath;
  3.     QString command;
  4.     // 设置线程数和超时
  5.     qDebug() <<"CPU核心数 QThreadmax: "<<QThread::idealThreadCount();
  6.     QThreadPool::globalInstance()->setMaxThreadCount(QThread::idealThreadCount());
  7.     QThreadPool::globalInstance()->setExpiryTimeout(-1);
  8.     for(int i=0;i<m_Tasks.count();i++)
  9.     {
  10.         RunnableTask* worker;
  11.         if(m_Tasks[i].sFileName.contains(".mp3")||m_Tasks[i].sFileName.contains(".aac"))
  12.         {
  13.             int first = m_Tasks[i].sFileName.lastIndexOf ("/");
  14.             fileName = m_Tasks[i].sFileName.right (m_Tasks[i].sFileName.length ()-first-1);
  15.             fileName = fileName.left(fileName.length ()-fileName.lastIndexOf (".")+1);
  16.             spath = m_Tasks[i].sFileName.left(first);
  17.             int pos = m_Tasks[i].sFileName.lastIndexOf (".");
  18.             picName = m_Tasks[i].sFileName.left(pos)+".jpg";
  19.             mp4Name = spath+"/output/"+fileName+".mp4";
  20.             qDebug() <<"xiaoke---------- file full path:"
  21.                     <<fileName<<"\n"<<spath<<"\n"<<picName<<"\n"<<mp4Name;
  22.             // 组ffmpeg命令
  23.              command = QString("./ffmpeg -loop 1 -i %1 -i %2 -vcodec %3 -s %4 -pix_fmt yuvj420p -r %5 %6 %7")
  24.                     .arg(picName)                               // 图片
  25.                     .arg(m_Tasks[i].sFileName)                  // 音频
  26.                     .arg(ui->comboBox_format->currentText())    // 编码格式
  27.                     .arg(ui->comboBox_resolution->currentText())// 分辨率
  28.                     .arg(ui->comboBox_rate->currentText())      // 帧率
  29.                     .arg("-shortest")                           // 音频长度 用参数"-shortest" 不需要设音频长度
  30.                     .arg(mp4Name);                              // 输出文件
  31.             qDebug() <<"xiaoke---------- command:"<<command;
  32.             m_Tasks[i].sCommand = command;
  33.             m_Tasks[i].sOutput = mp4Name;
  34.             worker = new RunnableTask(m_Tasks[i].cProBar,command);
  35.         }
  36.         else
  37.             worker = new RunnableTask(m_Tasks[i].cProBar);
  38.         connect(worker, &RunnableTask::taskFinished,[=](QProgressBar* s)
  39.         {
  40.             // 完成一个视频文件合成
  41.             qDebug() <<"taskFinished"<<s;
  42.             m_Tasks[i].sStatus= "done";
  43.         });
  44.         m_Tasks[i].worker = worker;
  45.         QThreadPool::globalInstance()->start(worker);
  46.     }
  47.     // 启动定时器判断线程池所有的tasks执行完毕
  48.     tasksCode = new QTimer(this);
  49.     tasksCode->setInterval(100);
  50.     connect(tasksCode, SIGNAL(timeout()), this, SLOT(tasksFinished()));
  51.     tasksCode->start();
  52.     /* 定时器
  53.     QTimer *timer = new QTimer(this);
  54.     timer->setInterval(1000);
  55.     connect(timer, &QTimer::timeout, [&]
  56.     {
  57.         if(QThreadPool::globalInstance()->waitForDone(100))
  58.         {
  59.             timer->stop();
  60.             qDebug() <<"QThreadPool taskFinished";
  61.             writefile();
  62.             on_Btn_play_clicked();
  63.         }
  64.     });
  65.     timer->start();
  66.     */











4条评分好评度+1贡献值+1金钱+10威望+1
20091001753 好评度 +1 - 2021-02-05
20091001753 贡献值 +1 - 2021-02-05
20091001753 威望 +1 - 2021-02-05
20091001753 金钱 +10 - 2021-02-05
离线nigoole

只看该作者 1楼 发表于: 2021-01-29
  
有句话说得好:好好学习,天天向上。加油~~!有上船的朋友联系企鹅393320854
离线xiaoke123

只看该作者 2楼 发表于: 2021-01-29
回 nigoole 的帖子
nigoole:[表情]  [表情]  (2021-01-29 15:06) 

谢谢鼓励
快速回复
限100 字节
 
上一个 下一个