libvlcpp MediaPlayerEventManager callback question
Posted: 28 May 2020 23:09
I'm working in a visual studio c++/MFC project. I've got a single main dialog with two list boxes, where you can add a "station" which has its own rudimentary playlist. If you click an item in the playlist, you can click play/stop to play or stop the video. I want to make this so that my custom playlist just continues along to the next video when the onEndReached event is triggered.
I am not using the playlist built into libvlcpp because in the future I intend to add features that will require complete control over the playlist myself.
So, when you click the play button the following happens:
When I watch it in the debugger, it goes into setMedia and never comes back out, so effectively the program freezes. However, it does appear to still be doing something, or maybe it's at a deadlock? I really don't know.
Code is below (HandlePlay() is the function reference in the list above, WM_PLAYNEXT message corresponds to OnPlaynext() ):
So, down to the question: Am I using the onEndReached event callback correctly? I couldn't figure out any other way to pass in a reference to the main object.
If I'm not using it correctly, what's the recommended way to make a callback that can handle management of my MainVidCont dialog such that I can automatically transition into the next video?
I am not using the playlist built into libvlcpp because in the future I intend to add features that will require complete control over the playlist myself.
So, when you click the play button the following happens:
- If MainVidCont dialog is open, destroy it.
- Get updated station/playlist information.
- Create new Media object and set it to the selected file.
- Set MediaPlayer media.
- Get MediaPlayer event manager and store it to station struct.
- Create/store lambda with a capture of View class (which we are executing this code from).
- Set MediaPlayer.onEndReached to the stored lambda.
- Main Window spawns a MainVidCont modeless dialog
- Set MainVidCont panel size
- Pass reference to player into MainVidCont so it can be stopped on panel close.
- Call MediaPlayer.setHwnd with hwnd of MainVidCont
- Call MediaPlayer.play()
When I watch it in the debugger, it goes into setMedia and never comes back out, so effectively the program freezes. However, it does appear to still be doing something, or maybe it's at a deadlock? I really don't know.
Code is below (HandlePlay() is the function reference in the list above, WM_PLAYNEXT message corresponds to OnPlaynext() ):
Code: Select all
void CStreamOVisionView::HandlePlay() {
int stationIndex = StationList.GetCurSel();
if (::IsWindow(MainVidCont.m_hWnd)) {
MainVidCont.DestroyWindow();
}
if (stationIndex == LB_ERR) {
return;
}
if (PlaylistContents.GetCurSel() == LB_ERR) {
return;
}
Stations[stationIndex].MediaCurrentIndex = PlaylistContents.GetCurSel();
CString cStrVid = Stations[stationIndex].Media[Stations[stationIndex].MediaCurrentIndex].Path;
char* strVid = ConvertCStringtoStr(cStrVid.GetString());
auto media = VLC::Media(Stations[stationIndex].vlcInstance, strVid, VLC::Media::FromPath);
Stations[stationIndex].vlcPlayer.setMedia(media);
Stations[stationIndex].vlcMediaPlayerEventMgr = &Stations[stationIndex].vlcPlayer.eventManager();
auto vlcEndFunc = [this]() -> void {
::SendMessageW(this->GetSafeHwnd(), WM_PLAYNEXT, NULL, NULL);
};
Stations[stationIndex].vlcMediaPlayerEventMgr->onEndReached(vlcEndFunc);
MainVidCont.Create(IDD_MAINVID);
CRect windowRect, thisRect;
MainVidCont.GetWindowRect(&windowRect);
GetWindowRect(&thisRect);
MainVidCont.MoveWindow(windowRect.left + thisRect.Width() + 25, thisRect.top - 75, ViewerSettings.Width, ViewerSettings.Height);
MainVidCont.ShowWindow(SW_SHOW);
MainVidCont.SetMediaPlayer(&Stations[stationIndex].vlcPlayer);
Stations[stationIndex].vlcPlayer.setHwnd(MainVidCont.GetSafeHwnd());
Stations[stationIndex].vlcPlayer.play();
}
afx_msg LRESULT CStreamOVisionView::OnPlaynext(WPARAM wParam, LPARAM lParam)
{
int stationIndex = StationList.GetCurSel();
if (this->PlaylistContents.GetCurSel() == this->PlaylistContents.GetCount() - 1) {
this->PlaylistContents.SetSel(-1, FALSE);
}
else {
this->Stations[stationIndex].MediaCurrentIndex = this->Stations[stationIndex].MediaCurrentIndex++;
this->PlaylistContents.SetCurSel(this->Stations[stationIndex].MediaCurrentIndex);
}
HandlePlay();
return 0;
}
If I'm not using it correctly, what's the recommended way to make a callback that can handle management of my MainVidCont dialog such that I can automatically transition into the next video?