libvlc 使用mediaplayer 播放rtsp

环境  ubuntu18.04 vlc3.0.6源码

从 github上下载的vlc 源码,默认配置,默认编译,用命令

./vlc rtsp://192.168.43.129:10086/stream
竟然无法播放,但是直接./vlc test.mp4  用 修改 vlc.c 里的main函数替换成用 vlm推送rtsp流, 都可行。

现象:

[00007fe66c001670] satip stream error: Failed to setup RTSP session

问题排除 

1: 用wind上的vlc搭建rtsp推流,同时用wind上另一个 vlc播放rtsp ok. (推送端 rtsp正常)

2:ubuntu上关掉防火墙 #ufw  disable   #ufw status (ok已关闭)

3:卸载掉自己编译的vlc ,删除掉 user~.config/vlc  重新用 apt-get install vlc, 安装vlc, 还是老问题,似乎重新安装的过程有些毛病。 目的是使用 默认安装的vlc 执行上述的命令来确认系统网络正常,但是没有达到目的 。

4:直接从源码处查看具体问题。。。。。(头大)

5:用wireshark抓包分析

直接就 setup ,连 option 请求都没有,果然是有问题的。

6 运行源码编译出来的vlc, vlc --list 列举出可以加载的插件模块,发现是没有rtsp的接受端支持的,只有rtsp 发送点播插件。

7.0 configure --help 

默认是不支持 realrtsp的。找到原因了,重新配置源码,./configure --enable-realrtsp --enable-live555。

8.0 不过我的configure 打开live555,configure 是失败的,提示live555不存在或者过老,需要自己更新

9.0 https://wiki.videolan.org/UnixCompile#The_method_for_badly-behaved_distributions 

类似于ubuntu 编译libvlc,你需要下载各种依赖代码的源码,操作方法如上官方介绍 (速度奇慢,还会碰到 从谷歌仓库下载 aom(支持av1的解码开源项目),当然下不到,导致失败)

隔天再次分析出错的信息,上述第4 条,如果上述的配置 ./configure --enable-realrtsp --enable-live555 ,只开启realrtsp而disable-live555 ,也会报错。在access.c文件中的

access_new()

{

 access->p_module = module_need(access, "access", access->psz_name,
                                       true);

//上面输出一下 pszname , 输出结果为 :rtsp,也就要加载一个rtsp的access

//查找一下 

}

所有 描述为 rtsp的模块,并且能力为access的,有:

1.0 access/rtsp/access.c  2.0 access/live555.cpp 3.0 access/satip.c

上述wireshark抓包只有一个 setup的,就是匹配到 satip.c模块,出错,然后继续匹配 到 access/rtsp/access.c,结果这个模块发生未知错误加载失败,猜测这个可能已经抛弃,使用的 live555,但是这里没有。。。。。。

安装live555, 上面第9条,vlc官方提供的方法,但是安装又有问题,头文件找不到,编译不过,干脆自行下载一个live555, 

http://www.live555.com/liveMedia/public/

#cd live

#./genMakefiles linux-64bit

#make

#make install

如果不行,手动拷贝一下上面的make install 中安装的文件到 contrib/x86_64-linux-gnu/

嫌麻烦可以 export DESTDIR =XXXanzhuangmulu

#make install

最终程序:

正常安装好live555, 在vlc顶层目录下 重新配置 ./configure --enable-realrtsp --enable-live555  ,执行编译 #make

使用./vlc rtsp://192.168.43.129:10086/stream  播放pc端vlc搭建的服务器rtsp流,播放ok!

环境就绪,现改用mediaplayer 播放rtsp。

在 bin/vlc.c 源码vlc入口函数,用我们自己的 main函数来替换掉源码的main函数,这样demo头文件和环境之类可以保持正确

自己的main代码

int main()
{
	
		/* The so-called POSIX-compliant MacOS X reportedly processes SIGPIPE even
		 * if it is blocked in all thread.
		 * Note: this is NOT an excuse for not protecting against SIGPIPE. If
		 * LibVLC runs outside of VLC, we cannot rely on this code snippet. */
		signal (SIGPIPE, SIG_IGN);
		/* Restore SIGCHLD in case our parent process ignores it. */
		signal (SIGCHLD, SIG_DFL);
	
#ifndef NDEBUG
		/* Activate malloc checking routines to detect heap corruptions. */
		setenv ("MALLOC_CHECK_", "2", 1);
	
		/* Disable the ugly Gnome crash dialog so that we properly segfault */
		setenv ("GNOME_DISABLE_CRASH_DIALOG", "1", 1);
#endif
	
#ifdef TOP_BUILDDIR
		setenv ("VLC_PLUGIN_PATH", TOP_BUILDDIR"/modules", 1);
		setenv ("VLC_DATA_PATH", TOP_SRCDIR"/share", 1);
#endif
	
	/* Clear the X.Org startup notification ID. Otherwise the UI might try to
	 * change the environment while the process is multi-threaded. That could
	 * crash. Screw you X.Org. Next time write a thread-safe specification. */
	unsetenv ("DESKTOP_STARTUP_ID");



	 libvlc_instance_t *vlc; 
	 libvlc_media_player_t *media_player;
	 libvlc_media_t *media;
	
	 vlc = libvlc_new(0, NULL);	
	 if(vlc == NULL)
	 {
	 	printf("wang erro libvlc_new \n");
		return -1;
	 }
	 media_player = libvlc_media_player_new(vlc);
	
	#if 1
	media =  libvlc_media_new_location(vlc,"rtsp://192.168.43.233:8989/stream");
	#else
	media =  libvlc_media_new_path(vlc,"bydtest.mp4");
	libvlc_media_add_option(media, ":sout=#duplicate{dst=rtp{sdp=rtsp://:10086/stream},dst=display}");
	#endif
	
	 if(media_player == NULL || media == NULL)
	 {
	 	printf("wang erro new_media_player \n");
		return -1;
	 }

	 libvlc_media_player_set_media(media_player,media);
	 
	 libvlc_media_player_play(media_player);

	 
	//注意release , 测试代码,没处理
      
	//play 30s	
	//usleep(10000*100*30);  
	while(1); //主线程不能退出,不然子线程也挂掉,播放不了了
	libvlc_vlm_release(vlc);	
	return 0;

}
#endif

主要步骤 

 vlc = libvlc_new(0, NULL);    

media_player = libvlc_media_player_new(vlc); //创建 media_player

media =  libvlc_media_new_location(vlc,"rtsp://192.168.43.233:8989/stream"); //创建media

libvlc_media_player_set_media(media_player,media);//设置media到mediaplayer
libvlc_media_player_play(media_player);//mediaplayer 播放

<think>我们正在解决QtMediaPlayer配置RTSP地址后无法播放的问题。根据引用资料,我们知道Qt的MediaPlayer底层依赖系统(本机平台)提供的编解码器,效果不佳且没有扩展性(引用[1])。同时,引用[2]指出,当运行时报错时可能因为没有对应的解析插件,因为Qt的多媒体播放底层使用DirectShowPlayerService(在Windows上),所以安装一个DirectShow解码器(如LAVFilters)可以解决运行出错问题。此外,引用[3]和[4]提供了其他思路:使用第三方播放器后端(如SkeyePlayerPro)或者使用QtMultimedia模块结合OpenCV等来实现流媒体播放和实时处理。因此,我们可以尝试以下解决方案:1.**安装DirectShow解码器(Windows平台)**:安装LAVFilters等解码器包,以提供必要的RTSP解码支持。2.**使用第三方播放器后端**:如引用[1]提到的SkeyePlayerPro,它是一个专业的后端播放器,可以替代Qt自带的MediaPlayer,提供更好的RTSP支持。3.**检查RTSP地址和网络**:确保RTSP地址正确,且网络可达。4.**使用其他Qt多媒体模块**:如引用[4]提到的,使用QtMultimedia模块实现流媒体播放器,但同样需要系统有相应的解码器。5.**使用其他库(如VLC-Qt或QtAV)**:这些库提供了更强大的媒体播放能力,支持RTSP流。下面我们将详细说明这些解决方案。###解决方案####1.安装DirectShow解码器(仅Windows)在Windows上,Qt的MediaPlayer后端使用DirectShow。如果缺少相应的解码器,将无法播放RTSP流。步骤:1.下载并安装LAVFilters(https://github.com/Nevcairiel/LAVFilters/releases)。2.安装时选择“Install”(安装)所有组件。3.重启应用程序。安装后,尝试重新播放RTSP流。####2.使用第三方播放器后端(如SkeyePlayerPro)如果系统自带的解码器无法满足需求,可以考虑使用第三方播放器后端。引用[1]中提到了SkeyePlayerPro,它是一个高性能的播放器,支持RTSP流媒体协议。步骤:1.获取SkeyePlayerPro的库文件(如dll或so)和开发包。2.在Qt项目中集成SkeyePlayerPro,替代QMediaPlayer。3.使用SkeyePlayerPro提供的API来播放RTSP流。示例代码结构可能如下(具体需参考SkeyePlayerPro文档):```cpp#include"SkeyePlayer.h"//创建播放器SkeyePlayer*player=newSkeyePlayer(this);//设置视频输出窗口player->setVideoWidget(ui->videoWidget);//设置RTSP地址player->setUrl("rtsp://example.com/stream");//开始播放player->play();```####3.检查RTSP地址和网络确保RTSP地址正确,并且网络连接正常。可以使用VLC播放器测试相同的RTSP地址,以确认地址有效。####4.使用QtMultimedia模块引用[4]提到使用QtMultimedia模块实现流媒体播放器。虽然它同样依赖系统解码器,但我们可以尝试使用QMediaPlayer和QVideoWidget。示例代码:```cpp#include<QMediaPlayer>#include<QVideoWidget>QMediaPlayer*player=newQMediaPlayer;QVideoWidget*videoWidget=newQVideoWidget;player->setVideoOutput(videoWidget);videoWidget->show();player->setMedia(QUrl("rtsp://example.com/stream"));player->play();```如果无法播放,可能需要安装额外的解码器(如步骤1)。####5.使用其他库(如VLC-Qt或QtAV)如果以上方法都不行,可以考虑使用VLC-Qt或QtAV等第三方库。-**VLC-Qt**:封装了VLC的库,支持RTSP流媒体协议。-**QtAV**:基于FFmpeg的Qt多媒体库,支持多种格式和协议。以VLC-Qt为例:1.下载VLC-Qt库(https://vlc-qt.tano.si/)。2.在项目中引入VLC-Qt库。3.使用VlcInstance和VlcMediaPlayer播放RTSP。示例代码:```cpp#include<VLCQtCore/Instance.h>#include<VLCQtCore/Media.h>#include<VLCQtCore/MediaPlayer.h>#include<VLCQtWidgets/WidgetVideo.h>VlcInstance*instance=newVlcInstance(VlcCommon::args(),this);VlcMediaPlayer*player=newVlcMediaPlayer(instance);VlcWidgetVideo*videoWidget=newVlcWidgetVideo;player->setVideoWidget(videoWidget);videoWidget->show();VlcMedia*media=newVlcMedia("rtsp://example.com/stream",instance);player->open(media);```###总结Qt自带的MediaPlayerRTSP的支持有限,主要依赖于系统解码器。在Windows上,安装LAVFilters等解码器可能解决问题。如果不行,可以考虑使用第三方播放器后端(如SkeyePlayerPro)或第三方库(如VLC-Qt、QtAV)来实现RTSP流的播放。§§相关问题§§1.如何在Qt中集成VLC-Qt来播放RTSP流?2.除了LAVFilters,还有哪些DirectShow解码器可以用于QtMediaPlayer?3.如何在Linux或macOS上解决QtMediaPlayer无法播放RTSP的问题?4.SkeyePlayerPro有哪些优势和特点?</think>### Qt MediaPlayer RTSP无法播放的解决方案 在Qt中使用`QMediaPlayer`播放RTSP流时,由于底层依赖系统编解码器且扩展性有限[^1],常会遇到无法播放的问题。以下是系统性的解决方案: #### 1. 安装DirectShow解码器(Windows平台) ```markdown 当运行时报错时,说明缺少RTSP解析插件。Qt多媒体底层使用DirectShowPlayerService: - 安装DirectShow解码器包,如 **LAV Filters** [^2] - 下载地址:https://github.com/Nevcairiel/LAVFilters/releases - 安装时勾选所有解码组件 ``` #### 2. 使用专业播放器后端 ```cpp // 替代方案:使用SkeyePlayerPro作为后端 #include <SkeyePlayer.h> SkeyePlayer* player = new SkeyePlayer(this); player->setUrl("rtsp://your_stream_url"); player->start(); ``` - 优势:专为流媒体优化的播放引擎[^1] - 支持:RTSP/RTP/RTMP等多种协议 - 文档:https://github.com/skeye/player #### 3. 检查Qt多媒体后端 ```bash # 查看当前使用的后端 qDebug() << QMediaServiceProvider::defaultServiceProvider()->supportedDevices("video"); ``` - 如果输出为空,需安装**Qt Multimedia Backend**插件 - Linux安装:`sudo apt install gstreamer1.0-plugins-bad` #### 4. 网络配置优化 ```cpp // 设置网络缓冲参数 QNetworkRequest request(QUrl("rtsp://example.com/stream")); request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); player->setNetworkConfigurations({ {QNetworkConfiguration::InternetAccessPoint, 5000} // 增加缓冲区 }); ``` #### 5. 协议兼容处理 ```cpp // 强制使用TCP传输(避免UDP被防火墙拦截) player->setMedia(QUrl("rtsp://example.com/stream?tcp")); // 或 player->setMedia(QMediaContent(QUrl("rtspt://example.com/stream"))); ``` #### 6. 错误处理机制 ```cpp connect(player, &QMediaPlayer::errorOccurred, [](QMediaPlayer::Error error){ qDebug() << "Error:" << error << player->errorString(); }); ``` 常见错误代码: - `QMediaPlayer::NetworkError`:网络连接问题 - `QMediaPlayer::FormatError`:编解码器不支持 #### 7. 备选技术方案 ```markdown 如果上述方案无效,可考虑: 1. 使用 **QtAV** 库(基于FFmpeg)[^4] ```bash git clone https://github.com/wang-bin/QtAV ``` 2. 集成 **libVLC** 方案: ```cpp VlcInstance *inst = new VlcInstance(VlcCommon::args(), this); VlcMediaPlayer *player = new VlcMediaPlayer(inst); player->setVideoWidget(ui->videoWidget); player->open(QUrl("rtsp://example.com")); ``` > **关键验证步骤**:先用VLC播放器测试相同RTSP地址,确认流可用性。如果VLC能播但Qt不能,说明是Qt环境配置问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值