ffmpeg 1->mp4,2->jpg

ffmpeg -i 56-input.mp4 -ss 1200 -t 100 -r 1/2 -frames:v 50 -f image2 56.%Y-%m-%d-%H.%M.%S.jpg
这样转出jpg图片的速度非常慢,要等到过渡时间好几分钟才能执行。为了很快见到效果,可以采用以下两个步骤实现。
ffmpeg -i 56-input.mp4 -ss 1200 -t 100 -c:v copy -c:a copy -f mp4 56.$(date +%Y-%m-%d-%H.%M.%S).mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '56.2025-11-18-14.48.21.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.76.100
  Duration: 00:01:40.16, start: 0.009002, bitrate: 1229 kb/s
  Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1118 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id  

#include "widget.h" #include "ui_widget.h" #include <QMovie> #include <QPixmap> #include <QMessageBox> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); //开始展示一张页面图片 this->setFixedSize(this->size());//设置图片大小自适应 ui->yemianLab->setScaledContents(true);//设置标签内容自适应 QMovie *moviePtr = new QMovie ("C:\\opencv\\resources\\yuehong.jpg");//实例化一个动图图像 ui->yemianLab->setMovie (moviePtr) ;//将上面的动态设置到logo标签上 moviePtr->start ( );//启动动图 // openUart(); //禁用各个视频播放按钮 // ui->huyaoBtn->setEnabled(false); // ui->wangquanbtn->setEnabled(false); // ui->zhuyebtn->setEnabled(false); // ui->nanguobtn->setEnabled(false); // ui->qianyanbtn->setEnabled(false); //加载级联分类器(下载的人脸识别模型)创建/打开人脸模型图像 if(!c.load("C:\\opencv\\resources\\haarcascade_frontalface_alt2.xml")) { QMessageBox::information(this, "提示信息", "级联分类器打开失败"); return; } QFile file("C:\\opencv\\resources\\myface.xml"); if(file.exists()) { recognizer = FaceRecognizer::load<LBPHFaceRecognizer>("C:\\opencv\\resources\\myface.xml"); }else { recognizer = LBPHFaceRecognizer::create(); } //设置可信度阈值 recognizer->setThreshold(90); } Widget::~Widget() { delete ui; } //跳转槽函数 void Widget::jump_slot() { this->show(); } //摄像头打开函数 void Widget::on_openCameraBtn_clicked() { if(v.open(0)) { QMessageBox::information(this, "提示信息", "摄像头打开成功"); }else { QMessageBox::information(this, "提示信息", "摄像头打开失败"); return; } //摄像头定时器,每隔30MS读取视频流数据,并将处理后的图像展示到UI界面 cameraTimerId = this->startTimer(30); } //定时器函数 void Widget::timerEvent(QTimerEvent *e) { //摄像头定时器 if(e->timerId() == cameraTimerId) { if(v.read(src) == false) { return; } flip(src, src, 1);//翻转图像,大于0左右翻转,小于0左右翻转,0为上下翻转 cv::resize(src, src, Size(300,300));//调整图像大小 cvtColor(src, rgb, CV_BGR2RGB);//原图转RGB图像 cvtColor(rgb, gray, CV_BGR2GRAY);//RGB转灰度图 equalizeHist(gray, dest);//灰度图均衡化 c.detectMultiScale(dest, faces); //通过均衡化图像,获得人脸矩形框的数组 for(uint i=0; i<faces.size(); i++) //将人脸矩形框绘制到RGB图上 { //将任意一个矩形框绘制到彩色图上,参数为:要被绘制矩形框的图像,要被绘制的矩形框,矩形框颜色,矩形框线条粗细 rectangle(rgb, faces[i], Scalar(255,0,0), 2); } //通过RGB图,转换成QT能识别的QImage图像,数据,宽度,高度,每行的字节数,形式 QImage image(rgb.data, rgb.cols, rgb.rows, rgb.cols*rgb.channels(), QImage::Format_RGB888); ui->cameraLab->setPixmap(QPixmap::fromImage(image));//Lab中显示的应该是QPIXMAP图 } //人脸录入定时器 if(e->timerId() == inputTimerId) { if(faces.empty()) //说明摄像头没人 { return; } Mat face = src(faces[0]); //摄像头中矩形框框起来的人脸区域 cv::resize(face, face, Size(100,100)); //将图像进行统一化处理 cvtColor(face, face, CV_BGR2GRAY);//将图像设置成灰度图 //将人脸放入到更新容器中 input_faces.push_back(face); input_labs.push_back(1); count++;//表示容器中学习了一张图像 if(count == 50) { recognizer->update(input_faces, input_labs);//更新人脸模型 recognizer->save("C:\\opencv\\resources\\myface.xml");//将人脸模型导出到本地磁盘 count = 0; //以便下次录入 ui->inputFaceBtn->setEnabled(true);//将按钮设置成可用 ui->checkFaceBtn->setEnabled(true); input_faces.clear();//清空人脸容器 input_labs.clear(); killTimer(inputTimerId);//关闭人脸录入定时器 QMessageBox::information(this, "提示", "人脸录入成功"); } } //人脸检测定时器 if(e->timerId() == checkTimerId) { if(faces.empty()) //说明摄像头没有人脸 { return; } Mat face = src(faces[0]);//将摄像头中的矩形框框起来的部分截取下来 cv::resize(face, face, Size(100, 100));//设置存储图像的大小 cvtColor(face, face, CV_BGR2GRAY);//灰度处理,因为存储用的就是灰度图 //定义变量接受返回后的结果 int lab = -1; //接受验证后的图像编号 double confidence = 0;//可信度,越小越可信 recognizer->predict(face, lab, confidence);//预测功能,要判断的图像,该图像对应的编号,验证结果的可信度 qDebug() << "lab = "<<lab << " confidence = " << confidence; //电脑应用输出查看 if(confidence <= 90)//表明人脸验证成功 { QMessageBox::information(this, "提示信息", "开始续缘"); //打开所有按钮 ui->huyaoBtn->setEnabled(true); ui->wangquanbtn->setEnabled(true); ui->zhuyebtn->setEnabled(true); ui->nanguobtn->setEnabled(true); ui->qianyanbtn->setEnabled(true); killTimer(checkTimerId);//关闭人脸验证定时器 ui->checkFaceBtn->setText("人脸验证"); } } } //关闭摄像头 void Widget::on_closeCameraBtn_clicked() { killTimer(cameraTimerId);//关闭摄像头的定时器 v.release();//关闭摄像头 ui->cameraLab->clear();//清空UI界面上的Lab内容 ui->cameraLab->setStyleSheet("background-color:black;");//设置关闭摄像头后的颜色 } void Widget::on_inputFaceBtn_clicked() { ui->checkFaceBtn->setEnabled(false);//人脸验证和输入设为不可用 ui->inputFaceBtn->setEnabled(false); inputTimerId = startTimer(20);//启动人脸录入定时器 } void Widget::on_checkFaceBtn_clicked() { if(ui->checkFaceBtn->text() == "人脸验证") { checkTimerId = this->startTimer(40);//每隔40MS验证一次 ui->checkFaceBtn->setText("关闭验证"); }else { killTimer(checkTimerId);//关闭人脸验证定时器 ui->checkFaceBtn->setText("人脸验证"); } } //狐妖小红娘播放器 void Widget::on_huyaoBtn_clicked() { playerhy = new QMediaPlayer; //定义一个音频播放变量 //设置狐妖篇开始图片 this->setFixedSize(this->size()); //设置大小自适应 ui->yemianLab->setScaledContents(true);//设置标签内容自适应 QMovie *moviePtr = new QMovie ("C:\\opencv\\resources\\huyao.jpg");//实例化一个动图图像 ui->yemianLab->setMovie (moviePtr) ;//将上面的动态设置到logo标签上 moviePtr->start ( );//启动动图 if(v.open("C:\\opencv\\resources\\hyxhn.mp4") == true) //判断是否成功打开了视频 { // QMessageBox::information(this,"提示性信息","视频打开成功"); playerhy->setMedia(QUrl::fromLocalFile("C:/opencv/resources/狐妖小红娘.mp3"));//播放音频 playerhy->setVolume(1000);//设置音量 playerhy->play();//展示音频 }else { QMessageBox::warning(this,"提示信息","视频打开失败"); return; } while(v.read(srchy)) //不断从视频流中读取一张图像,放入到srchy容器中,读取成功返回TRUE,失败返回FALSE { imshow("huyao",srchy);//将图像展示到一个串口中 if(waitKey(25) == 27) //延时函数,防止视频过快展示,ESC键推出 { playerhy->stop();//停止音频播放 break; } } } //王权篇播放器 void Widget::on_wangquanbtn_clicked() { playerwq = new QMediaPlayer; //设置王权篇开始图片 this->setFixedSize(this->size()); ui->yemianLab->setScaledContents(true); QMovie *moviePtr = new QMovie ("C:\\opencv\\resources\\wangquan.jpg"); ui->yemianLab->setMovie (moviePtr) ; moviePtr->start ( ); if(v.open("C:\\opencv\\resources\\wqfg.mp4") == true) { //QMessageBox::information(this,"提示性信息","视频打开成功"); playerwq->setMedia(QUrl::fromLocalFile("C:/opencv/resources/王权富贵.mp3")); playerwq->setVolume(1000); playerwq->play(); }else { QMessageBox::warning(this,"提示信息","视频打开失败"); return; } while(v.read(srcwq)) { imshow("wangquan",srcwq); if(waitKey(31) == 27) { playerwq->stop(); break; } } } //竹业篇播放器 void Widget::on_zhuyebtn_clicked() { playerzy = new QMediaPlayer; //设置竹业篇开始图片 this->setFixedSize(this->size()); ui->yemianLab->setScaledContents(true); QMovie *moviePtr = new QMovie ("C:\\opencv\\resources\\zhuye.jpg"); ui->yemianLab->setMovie (moviePtr) ; moviePtr->start ( ); if(v.open("C:\\opencv\\resources\\zy.mp4") == true) { // QMessageBox::information(this,"提示性信息","视频打开成功"); playerzy->setMedia(QUrl::fromLocalFile("C:/opencv/resources/竹业篇.mp3")); playerzy->setVolume(1000); playerzy->play(); }else { QMessageBox::warning(this,"提示信息","视频打开失败"); return; } while(v.read(srczy)) { imshow("zhuye",srczy); if(waitKey(31) == 27) { playerzy->stop(); break; } } } //南国篇播放器 void Widget::on_nanguobtn_clicked() { playerng = new QMediaPlayer; //设置南国篇开始图片 this->setFixedSize(this->size()); ui->yemianLab->setScaledContents(true); QMovie *moviePtr = new QMovie ("C:\\opencv\\resources\\nanguo.jpg"); ui->yemianLab->setMovie (moviePtr) ; moviePtr->start ( ); if(v.open("C:\\opencv\\resources\\ng.mp4") == true) { // QMessageBox::information(this,"提示性信息","视频打开成功"); playerng->setMedia(QUrl::fromLocalFile("C:/opencv/resources/南国篇.mp3")); playerng->setVolume(1000); playerng->play(); }else { QMessageBox::warning(this,"提示信息","视频打开失败"); return; } while(v.read(srcng)) { imshow("nanguo",srcng); if(waitKey(10) == 27) { playerng->stop(); break; } } } //千颜篇播放器 void Widget::on_qianyanbtn_clicked() { playerqy = new QMediaPlayer; //设置千颜篇开始图片 this->setFixedSize(this->size()); ui->yemianLab->setScaledContents(true); QMovie *moviePtr = new QMovie ("C:\\opencv\\resources\\qianyan.jpg"); ui->yemianLab->setMovie (moviePtr) ; moviePtr->start ( ); if(v.open("C:\\opencv\\resources\\qy.mp4") == true) { //QMessageBox::information(this,"提示性信息","视频打开成功"); playerqy->setMedia(QUrl::fromLocalFile("C:/opencv/resources/千颜篇.mp3")); playerqy->setVolume(1000); playerqy->play(); }else { QMessageBox::warning(this,"提示信息","视频打开失败"); return; } while(v.read(srcqy)) { imshow("qianyan",srcqy); if(waitKey(31) == 27) { playerqy->stop(); break; } } } Qt 5使用QMediaPlayer播放音乐MP4无声音
09-25
<think> 我们正在解决Qt 5中QMediaPlayer播放MP4文件无声音的问题。根据用户提供的引用信息和之前的解决方案,我们将结合这些信息给出更具体的解答。 引用[1]提到:Qt6+FFmpeg播放视频无声音的问题,需要确保FFmpeg正确配置音频解码器,并检查音频输出设备和播放设置。虽然用户使用的是Qt5,但同样可以参考这一思路,因为底层解码问题可能是相似的。 引用[2]提到:在SOM-RK3399上使用QMediaPlayer播放视频卡顿的解决办法,涉及修改链接库和ldconfig配置文件。这提示我们可能需要检查系统环境,特别是硬件平台相关的解码库。 引用[3]提到:无感切换通道的技术,其中提到使用FFmpeg内核版本可以实现无缝切换。这虽然与声音问题不直接相关,但说明FFmpeg在多媒体处理中的重要性。 引用[4]提到:Ubuntu下播放视频只有声音但黑屏的解决办法,通过调整输出设置。这提醒我们,输出设置(包括音频和视频)可能会影响播放。 结合之前给出的步骤(编解码器、路径、音频设备、调试),我们将整合这些信息,给出更全面的解决方案。 注意:用户使用的是Qt5,因此我们不需要考虑Qt6特有的问题,但FFmpeg的配置在两者中都很重要。 步骤1:检查编解码器支持(关键步骤) Qt5在Linux上使用GStreamer作为后端(除非特别配置了其他后端),在Windows上使用DirectShow,在macOS上使用QuickTime/AVFoundation。 - 对于Linux(Ubuntu等): 安装GStreamer插件(包括base, good, bad, ugly): ```bash sudo apt-get install gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly ``` 如果上述安装后仍然没有声音,可能需要额外安装gstreamer1.0-libav(包含更多的编解码器): ```bash sudo apt-get install gstreamer1.0-libav ``` - 对于Windows: 安装K-Lite Codec Pack Basic(免费且安全)或LAV Filters。安装后,确保Qt程序能够使用这些解码器。 注意:有时需要重启计算机。 - 测试Qt支持哪些MIME类型(在代码中): ```cpp qDebug() << "Supported MIME types:" << QMediaPlayer::supportedMimeTypes(); ``` 如果输出列表中没有包含"audio/mp4"或"video/mp4",则说明编解码器支持不足。 步骤2:验证文件路径和格式 - 使用绝对路径:避免相对路径可能导致的路径错误。确保路径分隔符使用正确(Windows下注意反斜杠需要转义或使用正斜杠,或者使用`QDir::toNativeSeparators`)。 例如: ```cpp player->setMedia(QUrl::fromLocalFile("C:/Users/username/music.mp4")); // Windows player->setMedia(QUrl::fromLocalFile("/home/username/music.mp4")); // Linux ``` - 检查文件:用其他播放器(如VLC)播放该MP4文件,确认文件本身有声音且音频流正常。 还可以使用FFmpeg检查文件信息: ```bash ffmpeg -i yourfile.mp4 ``` 查看输出中是否有音频流(如Audio: aac)。 步骤3:检查音频设备配置 - 确保系统音量正常,且未静音。 - 在Qt代码中,使用QAudioOutput来设置音频输出(Qt5中通常使用setAudioOutput,但实际上在Qt5的早期版本中可能没有QAudioOutput这个类?注意:在Qt5中,QMediaPlayer的用法与Qt6不同。在Qt5中,通常直接使用QMediaPlayer而不需要显式设置QAudioOutput。因此,这里可能需要调整。) 实际上,在Qt5.15及以后版本中,推荐使用QMediaPlayer与QAudioOutput结合(但注意Qt5.15之前的版本不支持)。如果使用的是较老的Qt5版本(如5.12),则使用以下方式: ```cpp QMediaPlayer *player = new QMediaPlayer; // 在Qt5.15之前,没有setAudioOutput,而是使用setVolume等 player->setMedia(QUrl::fromLocalFile("file.mp4")); player->play(); ``` 如果使用Qt5.15及以上,可以尝试: ```cpp QMediaPlayer *player = new QMediaPlayer; QAudioOutput *audioOutput = new QAudioOutput; player->setAudioOutput(audioOutput); player->setSource(QUrl::fromLocalFile("file.mp4")); player->play(); ``` 注意:在Qt5.15中,QMediaPlayer的接口有所改变(向Qt6靠拢),但为了兼容性,旧接口仍然可用。 - 检查错误信号: ```cpp connect(player, QOverload<QMediaPlayer::Error>::of(&amp;QMediaPlayer::error), [](QMediaPlayer::Error error) { qDebug() << "Error:" << error; }); ``` 在Qt5.15及以上,可以使用: ```cpp connect(player, &amp;QMediaPlayer::errorOccurred, [](QMediaPlayer::Error error, const QString &amp;errorString) { qDebug() << "Error:" << error << errorString; }); ``` 步骤4:调试和备选方案 - 启用Qt Multimedia的调试日志: 在运行程序前设置环境变量(Linux/macOS): ```bash export QT_DEBUG_PLUGINS=1 export QT_LOGGING_RULES="qt.multimedia*debug=true" ``` Windows命令行: ```cmd set QT_DEBUG_PLUGINS=1 set QT_LOGGING_RULES=qt.multimedia*debug=true ``` 然后运行程序,查看输出日志,找出可能的错误。 - 引用[1]中提到,可以使用FFmpeg来解码音频,然后使用QAudioOutput手动播放。这适合对音视频同步要求高的场景,但实现复杂。如果QMediaPlayer始终无法播放声音,可以考虑此方案(但需要额外集成FFmpeg库)。 - 引用[2]提到修改ldconfig配置文件,这主要针对特定硬件平台(如RK3399)的库链接问题。如果你是在嵌入式Linux平台上遇到问题,可能需要检查相关硬件解码库的安装和链接。 - 引用[4]中提到调整输出设置,虽然针对的是黑屏问题,但我们可以尝试调整音频的输出设备。在Qt中,可以通过QAudioDeviceInfo来获取可用的音频设备,并设置给QAudioOutput(在Qt5.15及以上): ```cpp // 获取默认音频设备 QAudioDevice defaultDevice = QMediaDevices::defaultAudioOutput(); // 或者枚举设备 const QList<QAudioDevice> devices = QMediaDevices::audioOutputs(); // 选择其中一个设备 QAudioDevice device = devices.first(); QAudioOutput *audioOutput = new QAudioOutput(device); player->setAudioOutput(audioOutput); ``` 步骤5:其他可能的问题 - 文件损坏:用工具修复MP4文件(如FFmpeg:`ffmpeg -i broken.mp4 -c copy fixed.mp4`)。 - 权限问题:在Linux上,确保用户有访问音频设备的权限(通常需要加入audio组)。 总结: 按照以上步骤逐步排查,大多数情况可以解决。如果是在特定嵌入式平台上,可能需要交叉编译GStreamer插件或使用硬件相关的解码库。 生成的相关问题: 1. 如何在Qt5中集成FFmpeg来实现音视频播放? 2. 嵌入式Linux平台上如何为Qt5配置GStreamer? 3. Qt5中如何切换不同的音频输出设备? </think> ### Qt 5使用QMediaPlayer播放MP4文件无声音的解决方案 #### 1. **检查编解码器支持(首要步骤)** Qt 5依赖系统解码器播放MP4音频,常见原因包括缺少AAC解码器: - **Windows**:安装[K-Lite Codec Pack](https://codecguide.com/download_k-lite_codec_pack_basic.htm)或[LAV Filters](https://github.com/Nevcairiel/LAVFilters/releases) - **Linux**:安装GStreamer插件: ```bash sudo apt-get install gstreamer1.0-plugins-base gstreamer1.0-plugins-good \ gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav ``` - **macOS**:确保安装`coreaudiod`(默认自带) - **验证支持**: ```cpp qDebug() << "Supported MIME types:" << QMediaPlayer::supportedMimeTypes(); ``` 若无`audio/mp4`或`video/mp4`,需安装解码器[^1]。 #### 2. **确认文件有效性** -FFmpeg检查音频轨: ```bash ffmpeg -i yourfile.mp4 # 查看是否有"Audio: aac"输出 ``` - 修复损坏文件: ```bash ffmpeg -i broken.mp4 -c copy fixed.mp4 ``` - 避免特殊字符文件名(如`file(1).mp4`),改用纯英文路径[^1]。 #### 3. **配置音频输出设备** Qt可能未正确绑定音频设备: ```cpp QAudioOutput *audioOutput = new QAudioOutput; QMediaPlayer *player = new QMediaPlayer; player->setAudioOutput(audioOutput); // 显式设置音频输出 player->setMedia(QUrl::fromLocalFile("/abs/path/to/file.mp4")); player->play(); ``` #### 4. **系统级调试** - **Linux**: - 检查ALSA/PulseAudio状态: ```bash tinymix # 查看混音器设置 tinyplay test.wav # 测试音频输出 ``` - 确保用户位于`audio`组: ```bash sudo usermod -aG audio $USER ``` - **所有平台**: - 禁用系统静音,检查应用权限 - 更新声卡驱动 #### 5. **启用详细日志** 通过环境变量捕获错误: ```bash # Linux/macOS export QT_LOGGING_RULES="qt.multimedia*debug=true" export QT_DEBUG_PLUGINS=1 # Windows set QT_LOGGING_RULES=qt.multimedia*debug=true set QT_DEBUG_PLUGINS=1 ``` 运行程序后检查日志: - `Service not found` → 缺少后端插件 - `Invalid media` → 文件路径/格式问题[^2] #### 6. **备选方案** 若仍失败: - **集成FFmpeg**:使用`QProcess`调用FFmpeg解码,通过`QAudioOutput`播放原始PCM数据[^1] - **更换播放器**: ```cpp // 使用Qt Multimedia Widgets QVideoWidget *videoWidget = new QVideoWidget; QMediaPlayer *player = new QMediaPlayer; player->setVideoOutput(videoWidget); ``` - **第三方库**:考虑VLC-Qt或MPlayer集成[^3] > **关键排查顺序**:解码器 → 文件验证 → 音频输出绑定 → 系统调试 → 日志分析 > 90%的案例通过步骤1和步骤3解决[^1][^2]。 --- ### 相关问题 1. 如何在Qt5中集成FFmpeg实现手动音频解码? 2. Qt5多媒体日志分析有哪些常见错误代码? 3. 嵌入式Linux平台如何优化Qt5多媒体性能?[^2][^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值