【问题标题】:libvlc is unable to stop streaming & causes crash in Qt Applicationlibvlc 无法停止流式传输并导致 Qt 应用程序崩溃
【发布时间】:2015-02-26 21:28:37
【问题描述】:

我正在使用 libvlc 在 QT 中创建一个流媒体应用程序,它将播放来自任何来源的 RTSP 流媒体。我已经创建了它,它对我来说工作正常,除了每当我想关闭它时,我的应用程序就会崩溃。我的代码如下。

ThreadVlc.h

<pre>
#ifndef THREADVLC_H
#define THREADVLC_H
#include <vlc\vlc.h>
#include <vlc\libvlc.h>
#include <QtGui>
#include <QWidget>
#include <QThread>
#include <QApplication>
class vlcOnQtPlayer : public QThread
{
Q_OBJECT
	bool isVideoPlayingCheck;
    libvlc_instance_t *libvlcInstance;
    libvlc_media_player_t *libvlcMediaPlayer;
    libvlc_media_t *libvlcMedia;
	QString rtspLink;
	QMutex mmutex;

public:
    vlcOnQtPlayer(WId parentWinId);
    void stop();
protected:
	void run();

public slots:
	void vlcOnQtSetLink(QString link);
	//void playRtspLink();
	int onVlcStreamCapture(QString imageSavePath);
private:
	WId windowId;
};
#endif

</pre>

ThreadVlc.cpp

<pre>

#include "ThreadVlc.h"
#include <QVBoxLayout>
#include <QPushButton>
#include <QFrame>
#include<iostream>
#include<QMessageBox>
using namespace std;
vlcOnQtPlayer::vlcOnQtPlayer(WId parentWinId) : QThread()
{

	mmutex.lock();
	windowId=parentWinId;
	mmutex.unlock();
	isVideoPlayingCheck=false;
}

void vlcOnQtPlayer::stop()
{
	//QMessageBox::warning(0,"Warning", "before libvlc_media_player_stop");
    libvlc_media_player_stop (libvlcMediaPlayer);
	QMessageBox::warning(0,"Warning", "After libvlc_media_player_stop");
	libvlc_media_player_release (libvlcMediaPlayer);
    libvlc_release (libvlcInstance);
	
}

void vlcOnQtPlayer::run()
{
	if(rtspLink!=NULL)
	{

	const char * const vlc_args[] = { "--no-audio","-vv" };
	libvlcInstance=libvlc_new(sizeof(vlc_args)/sizeof(vlc_args[0]), vlc_args);          
    
     //Create a new LibVLC media descriptor
	libvlcMedia = libvlc_media_new_location(libvlcInstance, rtspLink.toAscii());
    
    libvlcMediaPlayer=libvlc_media_player_new_from_media (libvlcMedia);


    // Get our media instance to use our window 
     libvlc_media_player_set_hwnd(libvlcMediaPlayer, windowId);//vlcOnQtVideoFrame->winId());
    
    // Play 
    libvlc_media_player_play (libvlcMediaPlayer);
	   
    isVideoPlayingCheck=true;   
	//return 0;
	}
	else
		isVideoPlayingCheck=false;
		//return 1;
}

int vlcOnQtPlayer::onVlcStreamCapture(QString imageSavePath)
{
	const char *file_Path=imageSavePath.toLocal8Bit().constData();
	//Function to take the snap shot of the screen
	int i=libvlc_video_take_snapshot(libvlcMediaPlayer,0,file_Path,0,0);
	return i;
}


void vlcOnQtPlayer::vlcOnQtSetLink(QString link) 
{ 
	mmutex.lock();
	rtspLink=link;
	mmutex.unlock();
}



</pre>

ThreadVlcMainWindow.h

<pre>

		
	#ifndef THREADVLCMAINWINDOW_H 
	#define THREADVLCMAINWINDOW_H
	 /* Including necessary classes*/
	 #include <QtGui>
	 #include <QMainWindow> 
	 #include <QApplication>
	 #include <ThreadVlc.h>
	 #include <QThread>
	 #include <QEvent>
	/* Proto type for the Main Window Class*/	
	class streamParentClass : public QMainWindow 
	{ 
		Q_OBJECT 
	public: 
		int count,noOfCam; // Variables for munber of cameras and counter
		streamParentClass(QWidget *parent = 0);
		~streamParentClass();
		QWidget *centralWidgetWindow; //Window to be set as central widget (central widget of main window)
		QGridLayout *streamIfaceLayout;
		QFrame * streamFrame;
		vlcOnQtPlayer * streamPlayerInstance;

		//QList <QPushButton *>btn;
		void guiDesign(); //For basic design of controls
		void addStreamWin(int); // To add vlc instances to main window
		void closeEvent(QCloseEvent *);
	};

#endif



</pre>

ThreadVlcMainWindow.cpp

<pre>

#include "ThreadVlcMainWindow.h" 
	#include <QtGui>
	#include <QToolBar> 
	#include <QIcon> 
	#include <QAction> 
	streamParentClass::streamParentClass(QWidget *parent) : QMainWindow(parent) 
    {
		noOfCam=1;
		guiDesign();     //Initializing controls
		addStreamWin(noOfCam);
	}

	
	streamParentClass::~streamParentClass()
	{
		for(int i=0;i<noOfCam;i++)
		{
			streamPlayerInstance->stop();
			streamIfaceLayout->removeWidget(streamFrame);

		}
		
		qApp->quit();
	}
	void streamParentClass::guiDesign()
	{
		centralWidgetWindow=new QWidget(this);
		streamIfaceLayout=new huffnetInterfaceLayout(centralWidgetWindow,4);
		centralWidgetWindow->setLayout(streamIfaceLayout);
		setCentralWidget(centralWidgetWindow);

	}
	void streamParentClass::addStreamWin(int n)
	{				
			for(int i=0;i<n;i++)
			{   
		    	streamFrame=new QFrame(centralWidgetWindow);
				streamFrame->setWindowFlags(Qt::FramelessWindowHint);
				streamPlayerInstance= new vlcOnQtPlayer(streamFrame->winId());
				streamIfaceLayout->addWidget(streamFrame,0,0);
				connect(streamPlayerInstance,SIGNAL(finished()),streamPlayerInstance,SLOT(deleteLater()));
				streamPlayerInstance->vlcOnQtSetLink("rtsp://:8554/strm");
				streamPlayerInstance->start();
			}
				
	}
	
	
	void streamParentClass::closeEvent(QCloseEvent *event)
		{
			
			for(int i=0;i<noOfCam;i++)
			{
				streamPlayerInstance->stop();//~vlcOnQtPlayer();
				delete streamFrame;
				delete centralWidgetWindow;
			//QMessageBox::warning(0,"Warning", "Inside for ");	
			}	

			qApp->quit();
		}
				 

</pre>

Main.cpp

<pre>

#include "ThreadVlcMainWindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
	QApplication app(argc,argv);
	streamParentClass mp;
	mp.resize(500,400);
	mp.show();
	return app.exec();
}

</pre>

我正在使用 Qt 4.8 和 Microsoft Visual Studio 2010 来构建它。它从服务器流式传输正常。我正在使用 Vlc 媒体播放器创建一个流式传输视频的流媒体服务器。但是当我尝试关闭它时,它正在崩溃我的窗口。我检查了几个错误并且喜欢 libvlc 无法处理命令 libvlc_media_player_stop() 。感谢您的任何建议。

【问题讨论】:

  • 你使用什么 libvlc 版本?
  • 尊敬的 RSATom 感谢您的快速回复,我使用的 libvlc 版本是 2.1.5 winx64
  • ThreadVlc.cpp 中,函数 stop() 正在打印消息 在 libvlc_media_player_stop 之前,但它没有显示消息在此声明之后。
  • 那么,是崩溃还是挂起?
  • 视频流继续。并且不会停止。如果我删除它正在运行的 QFrame 窗口,那么它会继续在后台工作。如果我使用插槽 qApp->quit() 则应用程序崩溃。

标签: visual-studio-2010 qt4 libvlc


【解决方案1】:

在代码中找到了mainProblem。 主要问题在于多线程,因为当我们在 threadVLC.cpp 中调用 libvlc_media_player_stop() 时,多个线程无法通信。所以我们要么强制终止线程,要么我们必须跳过线程。 libvlc_media_player_stop() 工作正常。我在videoLAN论坛上搜索过它。 https://forum.videolan.org/viewtopic.php?t=106415

感谢 RSATom 向我推荐论坛。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 2016-06-04
    • 2011-08-24
    • 2014-05-03
    相关资源
    最近更新 更多