c++使用libvlc实现简单的播放器

12 篇文章 3 订阅

VLC Media Player是一款非常强大的播放器,基本上支持绝大部分的解码器,但是源代码编译难度很大,所以还是使用编译好的库吧。

vlc sdk下载地址:http://download.videolan.org/pub/videolan/vlc/

vlc相关

  1. VLC-QT:
    用QT的小伙伴们可以使用开源的VLC-QT库哦,widget和qml都支持,由于 VLC-Qt 集成了整个 libVLC,因此具备 libVLC 的所有特性,例如:libVLC 实例和 player、单个文件和列表播放、音频和视频控制、元数据管理,如果想快速创建一个功能齐全的跨平台媒体播放器,这个库非常合适!详细的调用方法这里就不阐述了,直接百度吧。
    VLC-QT库官网地址:https://vlc-qt.tano.si/
    VLC_QT库github地址:https://github.com/vlc-qt
    VLC_QT库使用示例地址:https://github.com/vlc-qt/examples

  2. vlmc:
    vlmc(VideoLAN Movie Creator)是基于libVLC的非线性的视频编辑软件,可在Windows,Linux和Mac OS X上运行,但是vlmc仍在开发中,因此尚未准备好进行Beta测试或发布,因此感兴趣的小伙伴可以下载源码捣鼓一下还是非常有意思的。
    官网地址:https://www.videolan.org/vlmc/
    GitHub地址:https://code.videolan.org/videolan/vlmc.git

好,接下来进入正题

libvlc使用过程中遇到的问题:

  1. libvlc_new(0,NULL);总是失败
    解决办法:将下载的SDK目录下的plugins文件夹拷贝到exe目录。
  1. libvlc_media_t *vlc_mdia= libvlc_media_new_path(inst,“D:/box.mp4”);失败,返回空
    解决办法:libvlc_media_new_path(inst,“D:\box.mp4”);
  1. “libvlc_media_read_cb”: 未声明的标识符
    解决办法:在vlc.h 文件或其它文件中 添加 typedef __int64 ssize_t;
  1. libvlc_media_get_duration / libvlc_media_player_get_length / libvlc_media_player_get_time失败返回-1
    原因:没有解析元数据。
    解决办法:ibvlc_media_t 必须先解析视频或至少播放一次才能获取元数据。也就是调用libvlc_media_parse_with_options异步解析本地媒体(同步解析函数libvlc_media_parse已弃用),或调用libvlc_media_player_play播放一次。下面会讲到libvlc_media_parse_with_options调用方法。

解析媒体数据 + vlc事件订阅

  1. 创建事件管理器
libvlc_event_manager_t* vlc_media_event_mng = libvlc_media_event_manager(vlc_media);
  1. 订阅指定事件(这里订阅媒体解析和视频总时长事件)
libvlc_event_attach(vlc_media_event_mng, libvlc_MediaParsedChanged, event_callback, nullptr);
libvlc_event_attach(vlc_media_event_mng, libvlc_MediaDurationChanged, event_callback, nullptr);
  1. 开始异步解析本地媒体
libvlc_media_parse_with_options(vlc_media, libvlc_media_parse_local,-1);

event_callback:
说明:事件回调函数
参数event:事件类型
参数userData:自定义数据类型,可为Null

void event_callback(const libvlc_event_t *event, void *userData)
{
	switch (event->type)
	{
	case libvlc_MediaParsedChanged:
	{
	//在该事件中获取帧率fps
		libvlc_media_track_t **ppTracks = nullptr;
		int uiStreamCount = libvlc_media_tracks_get(g_vlcModel->m_media, &ppTracks);
		
		for (unsigned i = 0; i < uiStreamCount; i++)
		{
			libvlc_media_track_t* pTrack = ppTracks[i];
			if (pTrack && libvlc_track_video == pTrack->i_type)
			{
				libvlc_video_track_t* pVideoTrack = pTrack->video;
				int fps = pVideoTrack->i_frame_rate_num / (float)pVideoTrack->i_frame_rate_den;
				break;
			}
		}
		if(ppTracks)
			libvlc_media_tracks_release(ppTracks, uiStreamCount);
		break;
	}
	case libvlc_MediaDurationChanged:
	{
	//获取总时长
		int64_t duration = event->u.media_duration_changed.new_duration;
		break;
	}
	case libvlc_MediaPlayerPositionChanged:
	{
	//获取当前播放进度
		float pos = event->u.media_player_position_changed.new_position;
		break;
	}
	}	
}

libvlc_instance_t *vlc_inst= nullptr;
libvlc_media_t *vlc_media = nullptr;
libvlc_media_player_t *vlc_player = nullptr;
libvlc_event_manager_t *vlc_media_event_mng = nullptr;
libvlc_event_manager_t *vlc_player_event_mng = nullptr;

vlc_inst = libvlc_new(0, NULL);
if (vlc_inst)
{
	vlc_media = libvlc_media_new_path(vlc_inst ,"D:\\box.mp4");
	if (vlc_media)
	{
		//创建事件管理器
		vlc__media_event_mng = libvlc_media_event_manager(vlc_media);
		//订阅指定事件(视频解析,视频总时长,当前播放进度)
		libvlc_event_attach(vlc__media_event_mng, libvlc_MediaParsedChanged, event_callback, nullptr);
		libvlc_event_attach(vlc__media_event_mng, libvlc_MediaDurationChanged, event_callback, nullptr);
		libvlc_event_attach(vlc__media_event_mng, libvlc_MediaPlayerPositionChanged, event_callback, nullptr);
		//异步解析本地媒体
		libvlc_media_parse_with_options(vlc_media, libvlc_media_parse_local,-1);

		vlc_player = libvlc_media_player_new_from_media(vlc_media);
		if (vlc_player)
		{
			vlc__player_event_mng = libvlc_media_player_event_manager(vlc__player);
			libvlc_event_attach(vlc__player_event_mng, libvlc_MediaPlayerPositionChanged, event_callback, nullptr);

            auto imgBuffer = malloc(480 * 480* 4);
			libvlc_video_set_callbacks(vlc_player, [imgBuffer](void** pBuffer) -> void* {
		       std::cout << "Lock" << std::endl;
		       *pBuffer = imgBuffer;
		       return NULL;
	           }, [](void*, void*const*) {
		       std::cout << "unlock" << std::endl;
	           }, nullptr, param);
			libvlc_video_set_format(vlc_player, "RGBA", 450, 450, 450* 4);
		}
	}
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT 可以通过使用 Libvlc 库来实现视频播放功能。下面是使用 Libvlc 在 QT 中播放视频的步骤: 1. 下载并安装 Libvlc 库。 2. 在 QT 项目中添加 Libvlc 库的头文件和库文件。可以在项目文件中添加以下代码: ```c++ // 添加头文件路径 INCLUDEPATH += /path/to/libvlc/include // 添加库文件路径和链接库 LIBS += -L/path/to/libvlc/lib \ -lvlc ``` 3. 在 QT 界面中添加一个 QFrame 控件作为视频播放区域。 4. 在 QT 中创建一个 VLCPlayer 类,用于加载和播放视频。可以参考以下代码: ```c++ #include <vlc/vlc.h> #include <QWidget> class VLCPlayer : public QWidget { Q_OBJECT public: explicit VLCPlayer(QWidget *parent = nullptr); ~VLCPlayer(); void play(const char *filePath); private: libvlc_instance_t *vlcInstance = nullptr; libvlc_media_player_t *mediaPlayer = nullptr; libvlc_media_t *media = nullptr; uintptr_t winId = 0; }; ``` 5. 在 VLCPlayer 类的实现文件中实现 play() 函数,用于加载和播放视频。可以参考以下代码: ```c++ #include "vlcplayer.h" #include <QX11Info> VLCPlayer::VLCPlayer(QWidget *parent) : QWidget(parent) { // 初始化 VLC 实例 vlcInstance = libvlc_new(0, nullptr); // 创建媒体播放器 mediaPlayer = libvlc_media_player_new(vlcInstance); // 获取视频播放区域的窗口句柄 winId = QX11Info::display() == nullptr ? winId() : QX11Info::display(); // 设置视频播放区域 libvlc_media_player_set_xwindow(mediaPlayer, winId); } VLCPlayer::~VLCPlayer() { // 释放资源 libvlc_media_player_release(mediaPlayer); libvlc_release(vlcInstance); } void VLCPlayer::play(const char *filePath) { // 创建媒体 media = libvlc_media_new_path(vlcInstance, filePath); // 设置媒体播放器的媒体 libvlc_media_player_set_media(mediaPlayer, media); // 播放视频 libvlc_media_player_play(mediaPlayer); } ``` 6. 在 QT 界面中调用 VLCPlayer 类的 play() 函数,传入视频文件路径即可播放视频。可以参考以下代码: ```c++ VLCPlayer *player = new VLCPlayer(ui->videoFrame); player->play("/path/to/video.mp4"); ``` 以上就是使用 Libvlc 在 QT 中播放视频的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值