QT5视频播放器制作

这里使用QT自带的QMediaPlayer

QMediaPlayer是对底层播放框架DirectShowPlayerService的封装,具体格式依赖播放框架,Windows上就是DirectShow,安装LAV Filters之类的DirectShow解码框架就可以支持更多的格式,Linux下是GStreamer

附上两个链接

LAVFilters论坛
LAVFilters下载

安装完成后即可支持更多格式的视频播放,不再提示DirectShowPlayerService::doRender: Unresolved error code 80040266这样的错误。

或者下载安装k-lite解码器

http://www.codecguide.com/download_k-lite_codec_pack_standard.htm

头文件

#pragma once
#include <QWidget>
#include <QtMultimedia/QMediaPlayer>
#include <QtMultimedia/QMediaPlaylist>
#include <QtWidgets/QWidget>
#include <QLabel>
#include <QSlider>
#include <QToolButton>
#include <QComboBox>
#include <QPushButton>
#include <QtMultimedia/QVideoProbe>
#include <QtMultimedia/QAudioProbe>
#include <QtMultimediaWidgets/QVideoWidget>
#include "ui_QtMediaplayer.h"

class VideoWidget : public QVideoWidget
{
	Q_OBJECT

public:
	VideoWidget(QWidget *parent = 0);

protected:
	void keyPressEvent(QKeyEvent *event) override;
	void mouseDoubleClickEvent(QMouseEvent *event) override;
	void mousePressEvent(QMouseEvent *event) override;
};

class QtMediaplayer : public QWidget
{
	Q_OBJECT

public:
	QtMediaplayer(QWidget *parent = Q_NULLPTR);
	~QtMediaplayer();
	bool isPlayerAvailable() const;

signals:
	void fullScreenChanged(bool fullScreen);

	private slots:
	void open();
	void durationChanged(qint64 duration);
	void positionChanged(qint64 progress);
	void metaDataChanged();
	void playClicked();
	void updateRate();
	void setState(QMediaPlayer::State state);
	void seek(int seconds);
	void statusChanged(QMediaPlayer::MediaStatus status);
	void bufferingProgress(int progress);
	void videoAvailableChanged(bool available);
	void displayErrorMessage();

private:
	void setTrackInfo(const QString &info);
	void setStatusInfo(const QString &info);
	void handleCursor(QMediaPlayer::MediaStatus status);
	void updateDurationInfo(qint64 currentInfo);

	QMediaPlayer *player;
	//QMediaPlaylist *playlist;
	VideoWidget *videoWidget;
	QLabel *coverLabel;
	QToolButton *playButton;
	QComboBox *rateBox;
	QSlider *slider;
	QLabel *labelDuration;
	QPushButton *fullScreenButton;

 	QVideoProbe *videoProbe;
 	QAudioProbe *audioProbe;

	QString trackInfo;
	QString statusInfo;
	qint64 duration;

private:
	Ui::QtMediaplayerClass ui;
};

cpp

#include <QtMultimedia/QMediaService>
#include <QtMultimedia/QMediaPlaylist>
#include <QtMultimedia/QVideoProbe>
#include <QtMultimedia/QAudioProbe>
#include <QtMultimedia/QMediaMetaData>
#include <QtWidgets>
#include <QKeyEvent>
#include <QMouseEvent>
#include "QtMediaplayer.h"


VideoWidget::VideoWidget(QWidget *parent)
	: QVideoWidget(parent)
{
	setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);

	QPalette p = palette();
	p.setColor(QPalette::Window, Qt::black);
	setPalette(p);

	setAttribute(Qt::WA_OpaquePaintEvent);
}

void VideoWidget::keyPressEvent(QKeyEvent *event)
{
	if (event->key() == Qt::Key_Escape && isFullScreen()) {
		setFullScreen(false);
		event->accept();
	}
	else if (event->key() == Qt::Key_Enter && event->modifiers() & Qt::Key_Alt) {
		setFullScreen(!isFullScreen());
		event->accept();
	}
	else {
		QVideoWidget::keyPressEvent(event);
	}
}

void VideoWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
	setFullScreen(!isFullScreen());
	event->accept();
}

void VideoWidget::mousePressEvent(QMouseEvent *event)
{
	QVideoWidget::mousePressEvent(event);
}



QtMediaplayer::QtMediaplayer(QWidget *parent)
	: QWidget(parent)
	, videoWidget(0)
	, coverLabel(0)
	, slider(0)
{
	ui.setupUi(this);
	player = new QMediaPlayer(this);

	connect(player, SIGNAL(durationChanged(qint64)), SLOT(durationChanged(qint64)));
	connect(player, SIGNAL(positionChanged(qint64)), SLOT(positionChanged(qint64)));
	connect(player, SIGNAL(metaDataChanged()), SLOT(metaDataChanged()));
	connect(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
		this, SLOT(statusChanged(QMediaPlayer::MediaStatus)));
	connect(player, SIGNAL(bufferStatusChanged(int)), this, SLOT(bufferingProgress(int)));
	connect(player, SIGNAL(videoAvailableChanged(bool)), this, SLOT(videoAvailableChanged(bool)));
	connect(player, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(displayErrorMessage()));
	connect(player, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(setState(QMediaPlayer::State)));

	videoWidget = new VideoWidget(this);
	player->setVideoOutput(videoWidget);
	
	slider = new QSlider(Qt::Horizontal, this);
	slider->setRange(0, player->duration() / 1000);

	labelDuration = new QLabel(this);
	connect(slider, SIGNAL(sliderMoved(int)), this, SLOT(seek(int)));
	
 	videoProbe = new QVideoProbe(this);
 	videoProbe->setSource(player);
 
 	audioProbe = new QAudioProbe(this);
 	audioProbe->setSource(player);

	QPushButton *openButton = new QPushButton(tr("Open"), this);

	connect(openButton, SIGNAL(clicked()), this, SLOT(open()));
	
	fullScreenButton = new QPushButton(tr("FullScreen"), this);
	fullScreenButton->setCheckable(true);

	playButton = new QToolButton(this);
	playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
	connect(playButton, SIGNAL(clicked()), this, SLOT(playClicked()));

	rateBox = new QComboBox(this);
	rateBox->addItem("0.5x", QVariant(0.5));
	rateBox->addItem("1.0x", QVariant(1.0));
	rateBox->addItem("2.0x", QVariant(2.0));
	rateBox->setCurrentIndex(1);
	connect(rateBox, SIGNAL(activated(int)), this, SLOT(updateRate()));

	QBoxLayout *displayLayout = new QHBoxLayout;
	displayLayout->addWidget(videoWidget);

	QBoxLayout *controlLayout = new QHBoxLayout;
	controlLayout->setMargin(0);
	controlLayout->addWidget(openButton);
	controlLayout->addStretch(1);
	controlLayout->addWidget(playButton);
	controlLayout->addStretch(1);
	controlLayout->addWidget(rateBox);
	controlLayout->addStretch(1);
	controlLayout->addWidget(fullScreenButton);

	QBoxLayout *layout = new QVBoxLayout;
	layout->addLayout(displayLayout, 10);
	QHBoxLayout *hLayout = new QHBoxLayout;
	hLayout->addWidget(slider);
	hLayout->addWidget(labelDuration);
	layout->addLayout(hLayout);
	layout->addLayout(controlLayout);

	setLayout(layout);

	if (!isPlayerAvailable()) {
		QMessageBox::warning(this, tr("Service not available"),
			tr("The QMediaPlayer object does not have a valid service.\n"\
				"Please check the media service plugins are installed."));
		openButton->setEnabled(false);
		fullScreenButton->setEnabled(false);
	}

	metaDataChanged();
}

QtMediaplayer::~QtMediaplayer()
{
}

bool QtMediaplayer::isPlayerAvailable() const
{
	return player->isAvailable();
}

void QtMediaplayer::open()
{
	QFileDialog fileDialog(this);
	fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
	fileDialog.setWindowTitle(tr("Open Files"));
	QStringList supportedMimeTypes = player->supportedMimeTypes();
	if (!supportedMimeTypes.isEmpty()) {
		supportedMimeTypes.append("audio/x-m3u"); // MP3 playlists
		fileDialog.setMimeTypeFilters(supportedMimeTypes);
	}
	fileDialog.setDirectory(QStandardPaths::standardLocations(QStandardPaths::MoviesLocation).value(0, QDir::homePath()));
	if (fileDialog.exec() == QDialog::Accepted)
	{
		player->setMedia(fileDialog.selectedUrls().at(0));
		player->play();
	}
}

void QtMediaplayer::durationChanged(qint64 duration)
{
	this->duration = duration / 1000;
	slider->setMaximum(duration / 1000);
}

void QtMediaplayer::positionChanged(qint64 progress)
{
	if (!slider->isSliderDown()) {
		slider->setValue(progress / 1000);
	}
	updateDurationInfo(progress / 1000);
}

void QtMediaplayer::metaDataChanged()
{
	if (player->isMetaDataAvailable()) {
		setTrackInfo(QString("%1 - %2")
			.arg(player->metaData(QMediaMetaData::AlbumArtist).toString())
			.arg(player->metaData(QMediaMetaData::Title).toString()));

		if (coverLabel) {
			QUrl url = player->metaData(QMediaMetaData::CoverArtUrlLarge).value<QUrl>();

			coverLabel->setPixmap(!url.isEmpty()
				? QPixmap(url.toString())
				: QPixmap());
		}
	}
}

void QtMediaplayer::playClicked()
{
	switch (player->state()) {
	case QMediaPlayer::StoppedState:
	case QMediaPlayer::PausedState:
		player->play();
		break;
	case QMediaPlayer::PlayingState:
		player->pause();
		break;
	}
}

void QtMediaplayer::updateRate()
{
	player->setPlaybackRate(rateBox->itemData(rateBox->currentIndex()).toDouble());
}

void QtMediaplayer::setState(QMediaPlayer::State state)
{
	switch (state) {
	case QMediaPlayer::PlayingState:
		playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
		break;
	case QMediaPlayer::PausedState:
		playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
		break;
	}
}

void QtMediaplayer::seek(int seconds)
{
	player->setPosition(seconds * 1000);
}

void QtMediaplayer::statusChanged(QMediaPlayer::MediaStatus status)
{
	handleCursor(status);
	// handle status message
	switch (status) {
	case QMediaPlayer::UnknownMediaStatus:
	case QMediaPlayer::NoMedia:
	case QMediaPlayer::LoadedMedia:
	case QMediaPlayer::BufferingMedia:
	case QMediaPlayer::BufferedMedia:
		setStatusInfo(QString());
		break;
	case QMediaPlayer::LoadingMedia:
		setStatusInfo(tr("Loading..."));
		break;
	case QMediaPlayer::StalledMedia:
		setStatusInfo(tr("Media Stalled"));
		break;
	case QMediaPlayer::EndOfMedia:
		QApplication::alert(this);
		break;
	case QMediaPlayer::InvalidMedia:
		displayErrorMessage();
		break;
	}
}

void QtMediaplayer::handleCursor(QMediaPlayer::MediaStatus status)
{
#ifndef QT_NO_CURSOR
	if (status == QMediaPlayer::LoadingMedia ||
		status == QMediaPlayer::BufferingMedia ||
		status == QMediaPlayer::StalledMedia)
		setCursor(QCursor(Qt::BusyCursor));
	else
		unsetCursor();
#endif
}

void QtMediaplayer::bufferingProgress(int progress)
{
	setStatusInfo(tr("Buffering %4%").arg(progress));
}

void QtMediaplayer::videoAvailableChanged(bool available)
{
	if (!available) {
		disconnect(fullScreenButton, SIGNAL(clicked(bool)),
			videoWidget, SLOT(setFullScreen(bool)));
		disconnect(videoWidget, SIGNAL(fullScreenChanged(bool)),
			fullScreenButton, SLOT(setChecked(bool)));
		videoWidget->setFullScreen(false);
	}
	else {
		connect(fullScreenButton, SIGNAL(clicked(bool)),
			videoWidget, SLOT(setFullScreen(bool)));
		connect(videoWidget, SIGNAL(fullScreenChanged(bool)),
			fullScreenButton, SLOT(setChecked(bool)));

		if (fullScreenButton->isChecked())
			videoWidget->setFullScreen(true);
	}
}

void QtMediaplayer::setTrackInfo(const QString &info)
{
	trackInfo = info;
	if (!statusInfo.isEmpty())
		setWindowTitle(QString("%1 | %2").arg(trackInfo).arg(statusInfo));
	else
		setWindowTitle(trackInfo);
}

void QtMediaplayer::setStatusInfo(const QString &info)
{
	statusInfo = info;
	if (!statusInfo.isEmpty())
		setWindowTitle(QString("%1 | %2").arg(trackInfo).arg(statusInfo));
	else
		setWindowTitle(trackInfo);
}

void QtMediaplayer::displayErrorMessage()
{
	setStatusInfo(player->errorString());
}

void QtMediaplayer::updateDurationInfo(qint64 currentInfo)
{
	QString tStr;
	if (currentInfo || duration) {
		QTime currentTime((currentInfo / 3600) % 60, (currentInfo / 60) % 60, currentInfo % 60, (currentInfo * 1000) % 1000);
		QTime totalTime((duration / 3600) % 60, (duration / 60) % 60, duration % 60, (duration * 1000) % 1000);
		QString format = "mm:ss";
		if (duration > 3600)
			format = "hh:mm:ss";
		tStr = currentTime.toString(format) + " / " + totalTime.toString(format);
	}
	labelDuration->setText(tStr);
}

main

#include "QtMediaplayer.h"
#include <QtWidgets/QApplication>
#include <QCommandLineParser>
#include <QCommandLineOption>
#include <QDir>

int main(int argc, char *argv[])
{
	QApplication app(argc, argv);

	QCoreApplication::setApplicationName("Player Example");
	QCoreApplication::setOrganizationName("QtProject");
	QCoreApplication::setApplicationVersion(QT_VERSION_STR);
	QCommandLineParser parser;
	parser.setApplicationDescription("Qt MultiMedia Player Example");
	parser.addHelpOption();
	parser.addVersionOption();
	parser.addPositionalArgument("url", "The URL to open.");
	parser.process(app);

	QtMediaplayer player;
	
#if defined(Q_WS_SIMULATOR)
	player.setAttribute(Qt::WA_LockLandscapeOrientation);
	player.showMaximized();
#else
	player.show();
#endif
	return app.exec();
}

如果发布后,发现报错:Error : The QMediaPlayer object does not have a valid service ;

则需要找到 plugins / mediaservice,将整个mediaservice文件夹复制到与exe同一目录下即可。

### 回答1: Qt 是一个跨平台的应用程序开发框架,能够帮助开发者快速地创建各种类型的应用程序。其中,Qt 视频播放器是 Qt 框架中的一个重要功能,用于播放各种视频格式的文件。 CSDN 是一个面向程序员的技术社区,提供了丰富的技术资源和交流平台。在 CSDN 上,我们可以找到很多关于 Qt 视频播放器的教程和资料。 Qt 视频播放器通过 Qt 多媒体模块实现视频播放的功能。开发者可以利用 Qt 的多媒体类库,如 QMediaPlayer 和 QVideoWidget,实现视频的播放、暂停、停止、快进、快退等功能。同时,Qt 还提供了对常见视频格式的支持,如 MP4、AVI 等,使开发者可以方便地处理不同格式的视频文件。 在 CSDN 上,我们可以找到很多关于 Qt 视频播放器的教程和示例代码。这些教程和示例代码可以帮助开发者了解 Qt 视频播放器的基本使用方法,学习如何自定义视频播放器的外观和功能,以及如何处理视频播放过程中的各种事件。 通过在 CSDN 上学习和交流,我们可以更好地掌握 Qt 视频播放器的开发技术,解决遇到的问题,提高开发效率。同时,CSDN 社区也提供了一个交流平台,我们可以在其中与其他开发者分享经验、交流技术,共同推动 Qt 视频播放器的发展。 综上所述,Qt 视频播放器是通过 Qt 框架实现的功能,用于播放各种视频格式的文件。而 CSDN 则为开发者提供了学习、交流和分享的平台,可以帮助我们更好地学习和使用 Qt 视频播放器。 ### 回答2: QT视频播放器CSDN是一个基于QT开发的视频播放器,可以用来播放各种视频文件格式。CSDN是一个开发者社区,提供了各种技术文章和资源,而QT是一款跨平台的GUI开发框架。结合使用这两个工具,可以开发出功能强大的视频播放器。 QT视频播放器CSDN具有多种功能,包括播放、暂停、快进、快退、调整音量等等。用户可以通过QT提供的UI界面进行操作,也可以通过设置快捷键来进行控制。播放器还支持播放列表功能,可以一次性导入多个视频文件进行连续播放。 开发者可以借助CSDN网站上的各种技术文章和资源,学习和掌握QT开发视频播放器的知识和技巧。CSDN上有很多关于QT的教程和案例,可以帮助开发者了解QT的基本使用方法,并实现各种高级功能。同时,CSDN还提供了丰富的开源项目,开发者可以参考这些项目的源代码,加快开发进程。 在使用过程中,有可能会遇到一些问题。此时,可以在CSDN上提问,寻求其他开发者的帮助和建议。CSDN拥有一个庞大的开发者社区,很多问题都能得到及时解答。通过与其他开发者的交流和分享,可以进一步提升自己的开发水平。 总之,QT视频播放器CSDN是一个非常有用的工具,在开发视频播放器时可以充分利用其中的资源和技术支持,帮助开发者更加高效地完成项目。 ### 回答3: Qt视频播放器是一款基于Qt框架开发的多媒体播放器,它提供了丰富的功能和友好的界面,使得用户可以便捷地播放各种格式的视频文件。 Qt作为一个跨平台的开发框架,可以在各种操作系统上运行,因此Qt视频播放器具备了较好的兼容性。它支持在Windows、macOS和Linux等操作系统上进行编译和部署,让用户能够在不同平台上享受到同样稳定可靠的视频播放体验。 Qt视频播放器拥有清晰的界面和丰富的功能,可以实现基本的视频播放功能,如播放、暂停、快进、快退和音量调节等。此外,它还支持播放列表功能,用户可以将多个视频文件添加到播放列表中,方便地切换不同的视频文件进行观看。 Qt视频播放器也支持对视频的截图操作,用户可以通过简单的操作将正在播放的视频截取下来保存为图片格式。这对于用户来说非常方便,可以用于制作视频封面、保存有趣的场景或做其他用途。 除了基本的视频播放功能外,Qt视频播放器还支持视频格式的转换和编解码功能。用户可以使用该播放器将一个视频文件转换为另一种视频格式,并可以对视频进行编解码的设置,以获得更好的播放效果。 综上所述,Qt视频播放器是一款功能丰富、界面友好并具有较好兼容性的视频播放器。无论是在个人使用还是在开发商用途上,它都能提供稳定、流畅的视频播放体验,深受用户的喜爱。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值