VLC-SDK调用学习
VLC属于Video LAN开源项目组织中的一款全开源的流媒体服务器和多媒体播放器。作为流媒体服务器,VLC跨平台,支持多操作系统和计算机体系结构;作为多媒体播放器,VLC可以播放多种格式的媒体文件。主要包括有:WMV、ASF、MPG、MP、AVI、H.264等多种常见媒体格式。
通过查看官方文档,学习的了下VLC简单的调用接口,实现了一个音乐播放器,其实还是挺简单的。
为此特意将VLC的调用封装一个类:
QVlcPlayer
#ifndef QVLCPLAYER_H
#define QVLCPLAYER_H
#include <QObject>
typedef void (* pfnPosChanged) (void *data, int iPos); // 文件位置变化
struct libvlc_instance_t;
struct libvlc_media_player_t;
struct libvlc_event_t;
class QVlcPlayer : public QObject
{
Q_OBJECT
public:
explicit QVlcPlayer(QObject *parent = 0);
~QVlcPlayer();
bool Play(QString strPath); // 播放路径为strPath的文件
void Play (); // 播放
void Pause(); // 暂停
void Stop (); // 停止
// void PlayPreviouse(); // 播放上一首
// void PlayNext(); // 播放下一首
void Volume(int nVol); // 音量设置为nVol
void VolumeIncrease(); // 音量增大
void VolumeReduce(); // 音量减小
void SeekTo(int nPos); // 跳到指定位置nPos
void SeekForward(); // 快进
void SeekBackward(); // 快退
void SetCallback(pfnPosChanged pfn); // 设置文件位置改变时的回调函数
pfnPosChanged GetCallback(); // 获取文件位置改变时的回调函数
bool IsOpen(); // 文件是否打开
bool IsPlaying(); // 文件是否正在播放
bool IsPause(); // 是否暂停
int GetPos(); // 获取文件当前播放的位置
qint64 GetTime(); // 获取时间
void SetPlayTime(qint64 time); // 设置播放时间
qint64 GetLength(); // 获取长度
int GetPlayStatue(); // 获取播放状态
const char* getLibVlcVersion();
private:
libvlc_instance_t *m_pVLC_Inst; // VLC实例
libvlc_media_player_t *m_pVLC_Player; // VLC播放器
pfnPosChanged m_pfn; // 文件位置改变时的回调函数
QString m_filePath; // 文件路径
void Init(); // 初始化
QString UnicodeToUTF8(const QString &strWide); // 编码转化
void Release(); // 清理内存
};
#endif // QVLCPLAYER_H
QVlcPlayer.cpp
#include "qvlcplayer.h"
#include "vlc/vlc.h"
#include "vlc/libvlc_media.h"
#include <qmath.h>
#include <QStringList>
#include <QTextCodec>
// VLC的事件管理
void OnVLC_EndReached(const libvlc_event_t *event, void *data);
void OnVLC_PositionChanged(const libvlc_event_t *event, void *data);
QVlcPlayer::QVlcPlayer(QObject *parent)
: QObject(parent),
m_pVLC_Inst(NULL),
m_pVLC_Player(NULL),
m_pfn(NULL)
{
}
//
QVlcPlayer::~QVlcPlayer()
{
this->Release();
}
//播放媒体
bool QVlcPlayer::Play(QString strPath)
{
if (!m_pVLC_Inst)
{
this->Init();
}
if (strPath.isEmpty() || !m_pVLC_Inst)
{
return false;
}
this->Stop();
bool bRet = false;
libvlc_media_t *m;
#if defined(Q_OS_WIN)
m_filePath = strPath.replace("/","\\",Qt::CaseSensitive);
#elif defined(Q_OS_LINUX)
m_filePath = strPath;
#endif
//将文件路径进行编码转换(不转换的话不能识别中文,进而会出现错误)
m_filePath = UnicodeToUTF8(m_filePath);
m = libvlc_media_new_path(m_pVLC_Inst,m_filePath.toAscii());
if (m)
{
m_pVLC_Player = libvlc_media_player_new_from_media(m);
if (m_pVLC_Player)
{
libvlc_media_player_play(m_pVLC_Player);
// 事件管理
libvlc_event_manager_t *vlc_evt_man = libvlc_media_player_event_manager(m_pVLC_Player);
libvlc_event_attach(vlc_evt_man, libvlc_MediaPlayerEndReached, ::OnVLC_EndReached, this);
libvlc_event_attach(vlc_evt_man, libvlc_MediaPlayerPositionChanged, ::OnVLC_PositionChanged, this);
bRet = true;
}
libvlc_media_release(m);
}
return bRet;
}
void QVlcPlayer::Play()
{
if (m_pVLC_Player)
{
libvlc_media_player_play(m_pVLC_Player);
}
}
//暂停
void QVlcPlayer::Pause()
{
if (m_pVLC_Player)
{
libvlc_media_player_pause(m_pVLC_Player);
}
}
//停止播放媒体
void QVlcPlayer::Stop()
{
if (m_pVLC_Player)
{
libvlc_media_player_stop(m_pVLC_Player); /*stop playing*/
libvlc_media_player_release(m_pVLC_Player); /*Free the media_player*/
m_pVLC_Player = NULL;
}
}
void QVlcPlayer::Volume(int nVol)
{
if (m_pVLC_Player)
{
libvlc_audio_set_volume(m_pVLC_Player,nVol);
}
}
//增加音量
void QVlcPlayer::VolumeIncrease()
{
if (m_pVLC_Player)
{
int nVol = libvlc_audio_get_volume(m_pVLC_Player);
Volume((int)ceil(nVol * 1.1));
}
}
//减小音量
void QVlcPlayer::VolumeReduce()
{
if (m_pVLC_Player)
{
int nVol = libvlc_audio_get_volume(m_pVLC_Player);
Volume((int)floor(nVol * 0.9));
}
}
void QVlcPlayer::SeekTo(int nPos)
{
if (m_pVLC_Player)
{
libvlc_media_player_set_position(m_pVLC_Player, nPos/(float)10000.0);
}
}
//快进
void QVlcPlayer::SeekForward()
{
int nPos = GetPos();
//SeekTo(ceil(nPos * 1.1));
SeekTo(nPos + 10);
}
//快退
void QVlcPlayer::SeekBackward()
{
int nPos = GetPos();
//SeekTo(floor(nPos * 0.9));
SeekTo(nPos - 10);
}
void QVlcPlayer::SetCallback(pfnPosChanged pfn)
{
m_pfn = pfn;
}
pfnPosChanged QVlcPlayer::GetCallback()
{
return m_pfn;
}
bool QVlcPlayer::IsOpen()
{
return NULL != m_pVLC_Player;
}
bool QVlcPlayer::IsPlaying()
{
if (m_pVLC_Player)
{
return libvlc_media_player_is_playing(m_pVLC_Player);
}
return FALSE;
}
bool QVlcPlayer::IsPause()
{
bool tem;
if (m_pVLC_Player)
{
int state = libvlc_media_player_get_state(m_pVLC_Player);
switch(state)
{
case libvlc_Paused:
case libvlc_Stopped:
tem = true;
break;
default:
break;
}
}else{
tem = false;
}
return tem;
}
//获取文件当前播放的位置
int QVlcPlayer::GetPos()
{
if (m_pVLC_Player)
{
return (int)(100 * libvlc_media_player_get_position(m_pVLC_Player));
}
return 0;
}
//获取时间:当前播放的时间
qint64 QVlcPlayer::GetTime()
{
if (m_pVLC_Player)
{
return libvlc_media_player_get_time(m_pVLC_Player);
}
return 0;
}
void QVlcPlayer::SetPlayTime(qint64 time)
{
if (m_pVLC_Player)
{
libvlc_media_player_set_time(m_pVLC_Player,time);
}
}
//获取长度:当前媒体的总时间长度
qint64 QVlcPlayer::GetLength()
{
if (m_pVLC_Player)
{
return libvlc_media_player_get_length(m_pVLC_Player);
}
return 0;
}
/* typedef enum libvlc_state_t { libvlc_NothingSpecial = 0, libvlc_Opening, libvlc_Buffering, libvlc_Playing, libvlc_Paused, libvlc_Stopped, libvlc_Ended, libvlc_Error } libvlc_state_t; */
int QVlcPlayer::GetPlayStatue()
{
if (m_pVLC_Inst)
{
return libvlc_media_player_get_state(m_pVLC_Player);
}
return 0;
}
const char *QVlcPlayer::getLibVlcVersion()
{
if (m_pVLC_Inst)
{
return libvlc_get_version();
}
return "";
}
//VLC实例初始化
void QVlcPlayer::Init()
{
if (!m_pVLC_Inst)
{
m_pVLC_Inst = libvlc_new(0,NULL);
}
m_filePath = "";
}
//unicode转utf8
QString QVlcPlayer::UnicodeToUTF8(const QString &strWide)
{
QString strUtf8;
QStringList t;
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
for (int i = 0; i <strWide.length(); i+=4)
{
t.append(strWide.mid(i,4));
}
foreach (const QString &str, t) {
strUtf8.append(str);
}
return codec->fromUnicode(strUtf8);
}
void QVlcPlayer::Release()
{
this->Stop();
if (m_pVLC_Inst)
{
libvlc_release(m_pVLC_Inst);
m_pVLC_Inst = NULL;
}
}
void OnVLC_EndReached(const libvlc_event_t *event,void *data)
{
}
void OnVLC_PositionChanged(const libvlc_event_t *event, void *data)
{
switch (event->type)
{
case libvlc_MediaPlayerPositionChanged:
{
float fPos = event->u.media_player_position_changed.new_position;
QVlcPlayer *pAVPlayer = (QVlcPlayer *) data;
if (pAVPlayer)
{
pfnPosChanged pfn = pAVPlayer->GetCallback();
if (pfn)
{
pfn(pAVPlayer, int(fPos * 100));
}
}
}
break;
case libvlc_MediaPlayerSnapshotTaken:
break;
default:
break;
}
}
以上代码就是播放器的核心部分,代码注释很详细,完全可以看懂。而VLC又是跨平台的,因此这完全可以在linux、MAC下运行,只需要相应的动态库即可。关于编译不同平台的VLC动态库,官网有详细的介绍,这里就不做过多的介绍。
关于这个播放器界面,实现起来也很简单,参考我模仿的酷狗音乐界面,完全可以实现。
写完播放器很想让它在我的ARM板上跑起来,但是在编译VLC库时,遇到了很多问题,不得已而终止,心里还是有些许的遗憾的。编译ARM版本动态库的路上遇到了奇怪的问题,而这些问题网上的资料也很少,究其原因是因为VLC的依赖库太多了,好多的错误提示是缺少相应的库,安装上这些库之后又提醒某个文件中缺少头文件,很是让人头疼!看来只能转向Mplayer播放器了!
一下是configure之后的截图,这一步算数成功了。
在之后的make过程中,错误百出!
若是有哪位大神编译好了ARM版本的VLC库,还是很希望能交流下,不胜感激!
技术在于交流、分享……
博客地址:http://blog.****.net/u013704336\
Email:kevinlq0912@163.com
QQ:936563422