VLC Qt视频播放器开发指南

        VLC的音视频编解码是对ffmpeg的封装,用FFmpeg可以开发视频播放器,推拉流,同样用VLC也可以,某些时候可能比ffmpeg还要简单点。本篇博客介绍VLC Qt视频播放器开发的预备工作。

        开发环境:VS2017, Qt5.12_x64, win10

        首先需要获取VLC的SDK,  3.0版本的VLC安装后只有dll, 没有头文件,lib库,直接用源码编译还是有一定难度的。2.x版本的安装包会有sdk, 下载链接:http://download.videolan.org/pub/videolan/vlc/ 下载后,将include, lib,dll, plugins等文件放到一块儿,方便在vs中引用,如下图:

VLC Qt视频播放器开发指南_第1张图片

        sdk也可以直接编译 vlc 2.x 的源码得到,可以看我的这篇博客:VS2013编译vlc源码

        运行的时候,dll和plugins要放到exe所在的路径。

        VS2017项目属性包含include, lib,项目依赖项添加 libvlc.lib,libvlccore.lib

        播放器界面如下:

VLC Qt视频播放器开发指南_第2张图片

        视频显示用的是QWidget, 界面用qss做了美化,

        代码不太难,下面全部贴出来,有兴趣的可以参考。

        界面qss

QMainWindow
{
	background-color: rgb(53, 53, 53);
}

QPushButton
{
	background-color:rgb(128, 138, 135);
	color:white;
    font:16px;
    border-radius:6px; 
}
 
QPushButton:hover
{
    color:#0000ff;
    background-color:rgb(210, 205, 205); /*改变背景色*/
    border-style:inset;/*改变边框风格*/
    padding-left:1px;
    padding-top:1px;
}

QSlider::groove:horizontal {
	border: 1px solid #4A708B;
	background: #C0C0C0;
	height: 5px;
	border-radius: 1px;
	padding-left:-1px;
	padding-right:-1px;
}


QSlider::sub-page:horizontal {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, 
    stop:0 #B1B1B1, stop:1 #c4c4c4);
background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,
    stop: 0 #5DCCFF, stop: 1 #1874CD);
border: 1px solid #4A708B;
height: 10px;
border-radius: 2px;
}

QSlider::add-page:horizontal {
background: #575757;
border: 0px solid #777;
height: 10px;
border-radius: 2px;
}

QSlider::handle:horizontal 
{
    background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, 
    stop:0.6 #45ADED, stop:0.778409 rgba(255, 255, 255, 255));

    width: 11px;
    margin-top: -5px;
    margin-bottom: -5px;
    border-radius: 5px;
}

QSlider::handle:horizontal:hover 
{
    background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0.6 #2A8BDA, 
    stop:0.778409 rgba(255, 255, 255, 255));

    width: 11px;
    margin-top: -5px;
    margin-bottom: -5px;
    border-radius: 5px;
}


 头文件

#pragma once

#include 
#include "ui_MyVLCPlayer.h"
#include "vlc/vlc.h"

class MyVLCPlayer : public QMainWindow
{
	Q_OBJECT

public:
	MyVLCPlayer(QWidget *parent = Q_NULLPTR);
	~MyVLCPlayer();

	void stopPlay();

private slots:
	void on_btnLoadVideo_clicked();
	void on_btnStart_clicked();
	void on_btnStop_clicked();
	int changeVolume(int vol);
	void changePosition(int pos);
	void updateInterface();
	void on_btnMute_clicked();

private:
	Ui::MyVLCPlayerClass ui;

	libvlc_instance_t *m_vlcInstance;
	libvlc_media_player_t *m_vlcPlayer;
};

  cpp文件

#pragma execution_character_set("utf-8")

#include "MyVLCPlayer.h"
#include 
#include 
#include 


MyVLCPlayer::MyVLCPlayer(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

#ifdef _DEBUG
	setWindowTitle("MyVLCPlayer_d");
#else
	setWindowTitle("MyVLCPlayer");
#endif

	m_vlcPlayer = NULL;

	//创建vlc实例
	m_vlcInstance = libvlc_new(0, NULL);

	//判断vlc实例化是否ok
	if (m_vlcInstance == NULL)
	{
		QMessageBox::critical(this, "Qt libVLC player", "Could not init libVLC");
		exit(1);
	}

	//音量进度条
	connect(ui.volumeSlider, SIGNAL(sliderMoved(int)), this, SLOT(changeVolume(int)));
	ui.volumeSlider->setValue(50);

	//时间进度条
	ui.timeSlider->setMaximum(1000);
	connect(ui.timeSlider, SIGNAL(sliderMoved(int)), this, SLOT(changePosition(int)));

	QTimer *timer = new QTimer(this);
	connect(timer, SIGNAL(timeout()), this, SLOT(updateInterface()));
	timer->start(100);
}

MyVLCPlayer::~MyVLCPlayer()
{
	if (m_vlcInstance)
	{
		libvlc_release(m_vlcInstance);
	}	

	stopPlay();
}

void MyVLCPlayer::on_btnLoadVideo_clicked()
{
	QString fileName = QFileDialog::getOpenFileName(this, 
		tr("请选择视频文件"), 
		tr("D:\\TestVideo"),
		tr("视频文件 (*.flv *.rmvb *.avi *.mp4);; 所有文件 (*.*);; "));

	fileName.replace(":/", ":\\");
	setWindowTitle(fileName);
	
	//如果视频正在播放,先停止播放
	if (m_vlcPlayer && libvlc_media_player_is_playing(m_vlcPlayer))
	{
		stopPlay();
	}
		
	libvlc_media_t *vlcMedia = libvlc_media_new_path(m_vlcInstance, fileName.toStdString().c_str());
	if (!vlcMedia)
	{
		return;
	}
		
	m_vlcPlayer = libvlc_media_player_new_from_media(vlcMedia);
	libvlc_media_release(vlcMedia);

	//vlcplayer和Qt控件关联
	libvlc_media_player_set_hwnd(m_vlcPlayer, (void*)(ui.widget->winId()));
	libvlc_media_player_play(m_vlcPlayer);

	ui.btnStart->setText(tr("暂停"));
}

void MyVLCPlayer::on_btnStart_clicked()
{
	if (!m_vlcPlayer)
		return;

	if (libvlc_media_player_is_playing(m_vlcPlayer))
	{
		libvlc_media_player_pause(m_vlcPlayer);
		ui.btnStart->setText(tr("开始播放"));
	}
	else
	{
		libvlc_media_player_play(m_vlcPlayer);
		ui.btnStart->setText(tr("暂停"));
	}
}

void MyVLCPlayer::on_btnStop_clicked()
{
	stopPlay();
}

void MyVLCPlayer::stopPlay()
{
	if (m_vlcPlayer)
	{
		libvlc_media_player_stop(m_vlcPlayer);
		libvlc_media_player_release(m_vlcPlayer);
		m_vlcPlayer = NULL;
		ui.timeSlider->setValue(0);
		ui.btnStart->setText(tr("开始播放"));
	}
}

int MyVLCPlayer::changeVolume(int vol)
{
	if (m_vlcPlayer)
	{
		return libvlc_audio_set_volume(m_vlcPlayer, vol);
	}
		
	return 0;
}
void MyVLCPlayer::changePosition(int pos)
{
	if (m_vlcPlayer)
	{
		libvlc_media_player_set_position(m_vlcPlayer, (float)pos / 1000.0);
	}
}

void MyVLCPlayer::updateInterface() 
{ 
	if (!m_vlcPlayer)
	{
		return;
	}
		
	float pos = libvlc_media_player_get_position(m_vlcPlayer);
	ui.timeSlider->setValue((int)(pos*1000.0));

	if (libvlc_media_player_get_state(m_vlcPlayer) == libvlc_Ended)
	{
		this->stopPlay();
	}	
}

void MyVLCPlayer::on_btnMute_clicked()
{
	if (m_vlcPlayer)
	{
		if (ui.volumeSlider->value() == 0) 
		{ 
			this->changeVolume(80);
			ui.volumeSlider->setValue(80);
		}
		else 
		{
			this->changeVolume(0);
			ui.volumeSlider->setValue(0);
		}
	}
}

         音量处理这块儿有问题,声音曲线是log函数类型的,目前简单的处理了。视频其它功能基本ok.

         以后有时间再写写vlc推拉流。

你可能感兴趣的:(#,vlc源码分析与应用)