Qt を使用して同時に実行される複数の libVlc インスタンスを埋め込むアプリを作成しています。Qt の GUI スレッドから呼び出されると libvlc_media_player_stop がデッドロックすることがある vlc ライブラリにバグがあるようです。videolan フォーラムの 1 つで受け入れられた解決策は、別のスレッドから stop 関数を呼び出すことでした。私は、別のスレッドから停止を呼び出すための、最も関与が少なく、あまり醜くない方法を探しています。この種の状況を正確に意味する QThreadPool の使用を検討しましたが、私の特定のケースでは、解決策がうまくいきません。
これが私のコードの一部です:
VlcWidget.h
class VlcWidget : public QWidget
{
Q_OBJECT
private:
// State
bool _isPlaying;
// The streaming source, title and quality data
VideoData _videoData;
VIDEO_QUALITY _quality;
// LibVlc related members
libvlc_instance_t *_vlcInstance;
libvlc_media_player_t *_vlcMediaPlayer;
libvlc_media_t *_vlcMedia;
int _vlcTrackID;
}
VlcWidget.c
void VlcWidget::Play()
{
if(_videoData.Source() != "" && !_isPlaying)
{
// Create a new media descriptor
_vlcMedia = libvlc_media_new_location(
_vlcInstance,
_videoData.Source().toStdString().c_str());
// Tell the user about incorrect URL
if(_vlcMedia == NULL)
{
QMessageBox::information(this,
_videoData.Title(),
"Unable to open source Url.\nPlease check the source and try again.");
return;
}
libvlc_media_player_set_media(_vlcMediaPlayer, _vlcMedia);
libvlc_media_release(_vlcMedia);
libvlc_media_player_set_xwindow(_vlcMediaPlayer, parentWidget()->winId());
libvlc_media_player_play(_vlcMediaPlayer);
_vlcTrackID = libvlc_audio_get_track(_vlcMediaPlayer);
_isPlaying = true;
}
}
void VlcWidget::Stop()
{
if(_isPlaying)
{
libvlc_media_player_stop(_vlcMediaPlayer);
_vlcTrackID = -1;
_isPlaying = false;
}
}
QthreadPool を使用した私のソリューションは次のようになりました。
class AsyncVlcPlay : public QRunnable
{
private:
// State
bool *_isPlaying;
// LibVlc related members
libvlc_instance_t *_vlcInstance;
libvlc_media_player_t *_vlcMediaPlayer;
libvlc_media_t *_vlcMedia;
int *_vlcTrackID;
public:
virtual void run();
}
そして、AsyncVlcPlay::run() は、VlcWidget::Play() が単純なロックを追加して行うこととまったく同じことを行います。また、VlcWidget::Stop() にも同様のクラスが必要です。私が達成しようとしていることのために2つの新しいクラスを本当に必要とするべきではないので、私はこの解決策が好きではありません。さらに悪いことに、VlcWidgets プライベート メンバーを別のクラスのオブジェクトに渡さなければなりません。私が気付いていない非常に簡単な方法があると確信しており、あなたの一人がここで私を助けてくれることを願っています. ありがとう!
(実際、VlcWidget::Play() を別のスレッドに配置する必要はありませんが、Play と Stop の対称性を維持したいと考えています)