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?