void Widget::on_choose_btn_clicked() { QString path = QFileDialog::getOpenFileName(nullptr, "Open Video", QDir::homePath(), "Videos (*.avi *.mp4 *.wmv)"); this->player->setMedia(QMediaContent(QUrl(path))); QVideoWidget *video_widget = new QVideoWidget(this); this->player->setVideoOutput(video_widget); QAbstractVideoSurface *surface = video_widget->videoSurface(); QLabel *label = new QLabel(this); label->setFixedSize(640, 480); // 设置标签大小 label->show(); QMetaObject::invokeMethod(this->player, "play"); // 异步播放视频 connect(surface, &QAbstractVideoSurface::frameChanged, [label, surface]() { QVideoFrame frame = surface->currentFrame(); if (!frame.isValid()) { return; } QImage image = QVideoFrameToImage(frame); QPixmap pixmap = QPixmap::fromImage(image); label->setPixmap(pixmap); }); } QImage Widget::QVideoFrameToImage(QVideoFrame &frame) { if (frame.map(QAbstractVideoBuffer::ReadOnly)) { QImage::Format format = QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat()); QImage image(frame.bits(), frame.width(), frame.height(), frame.bytesPerLine(), format); image = image.copy(); // 强制深拷贝 frame.unmap(); return image; } return QImage(); }
时间: 2023-06-26 22:05:24 浏览: 66
这是一个基于 Qt 的视频播放器的槽函数,当用户点击选择按钮时,会弹出文件选择对话框,让用户选择视频文件。选好后,将视频文件的路径设置给 QMediaPlayer 对象,并设置 QVideoWidget 作为视频播放输出设备,然后异步播放视频。同时,还连接了 QAbstractVideoSurface::frameChanged 信号,每当视频帧发生变化时,会调用 QVideoFrameToImage 函数将视频帧转换为 QImage 对象,并显示到标签上。
QVideoFrameToImage 函数会将 QVideoFrame 对象转换为 QImage 对象,首先通过 QAbstractVideoBuffer::map 函数将帧数据映射到内存中,并根据像素格式创建 QImage 对象,然后将帧数据拷贝到 QImage 对象中,最后通过 QAbstractVideoBuffer::unmap 函数解除映射。若映射失败,则返回一个空的 QImage 对象。
相关问题
//选择视频 void Widget::on_choose_btn_clicked() { //获取视频的完整路径 // QString str="D:\Qt\Qt5.12.12\QT\QT_project\output.avi"; //QString path = "D:\Qt\Qt5.12.12\QT\QT_project\output.avi"; QString path = QFileDialog::getOpenFileName(nullptr, "Open Image", QDir::homePath(), "Images (*.avi *.mp4 *.wmv)"); //加载资源文件 this->player->setMedia(QMediaContent(QUrl(path))); //设置画面的输出 this->player->setVideoOutput(video_widget); // 将视频画面输出到pictrue_lab } //开始播放 void Widget::on_start_play_btn_clicked() { //播放视频 this->player->play(); //播放滑块的初始值 this->ui->slider->setValue(0); //启动定时器 this->timer->start(1000); }将画面显示在label标签中
要将视频画面显示在label标签中,可以使用QLabel类中的setPixmap()方法来设置标签的显示内容。具体实现可以参考下面的代码:
//选择视频
void Widget::on_choose_btn_clicked() {
QString path = QFileDialog::getOpenFileName(nullptr, "Open Video", QDir::homePath(), "Videos (*.avi *.mp4 *.wmv)");
this->player->setMedia(QMediaContent(QUrl(path)));
this->player->setVideoOutput(video_widget);
}
//开始播放
void Widget::on_start_play_btn_clicked() {
this->player->play();
this->ui->slider->setValue(0);
this->timer->start(1000);
}
//更新标签显示内容
void Widget::updateLabel() {
//获取当前帧的图像
QImage frame = video_widget->grab().toImage();
//将图像缩放到标签的大小
QPixmap pixmap = QPixmap::fromImage(frame).scaled(ui->label->size(), Qt::KeepAspectRatio);
//设置标签的显示内容
ui->label->setPixmap(pixmap);
}
//定时器事件
void Widget::timerEvent(QTimerEvent *event) {
//更新标签显示内容
updateLabel();
}
其中,updateLabel()方法用来更新标签的显示内容,它首先调用video_widget->grab().toImage()方法获取当前帧的图像,然后将图像缩放到标签的大小,并使用setPixmap()方法设置标签的显示内容。定时器事件中,每隔一定时间调用updateLabel()方法更新标签的显示内容。
void Widget::on_choose_btn_clicked() { //获取视频的完整路径 // QString str="D:\Qt\Qt5.12.12\QT\QT_project\output.avi"; //QString path = "D:\Qt\Qt5.12.12\QT\QT_project\output.avi"; QString path = QFileDialog::getOpenFileName(nullptr, "Open Image", QDir::homePath(), "Images (*.avi *.mp4 *.wmv)"); //加载资源文件 this->player->setMedia(QMediaContent(QUrl(path))); //设置画面的输出 this->player->setVideoOutput(video_widget);怎么 将视频画面输出到pictrue_lab标签中
将视频画面输出到 QLabel 中需要进行一些额外的步骤,比如将视频帧转换为 QImage 格式,并将其设置为 QLabel 的背景。以下是一个简单的实现示例:
```cpp
void Widget::on_choose_btn_clicked() {
QString path = QFileDialog::getOpenFileName(nullptr, "Open Video", QDir::homePath(), "Videos (*.avi *.mp4 *.wmv)");
this->player->setMedia(QMediaContent(QUrl(path)));
this->player->setVideoOutput(video_widget);
// 添加以下代码
connect(this->player, &QMediaPlayer::videoFrameChanged, [=]() {
QImage image = QImage(this->player->videoSurface()->surfaceFormat().size(), QImage::Format_ARGB32);
QPainter painter(&image);
this->player->videoSurface()->surfaceFormat().videoFrameToPixmap(this->player->currentVideoFrame()).toImage().scaled(image.size()).swap(image);
painter.end();
picture_lab->setPixmap(QPixmap::fromImage(image));
});
}
```
这里使用了 `QMediaPlayer::videoFrameChanged` 信号来获取视频帧,并将其转换为 QImage 格式,最后设置为 QLabel 的背景。需要注意的是,这种方法可能会比较耗费资源,如果需要播放高分辨率或者高帧率的视频,可能会出现卡顿的情况。