Page 1 of 1
Streaming YouTube video?
Posted: 14 Sep 2020 02:27
by neosettler
Greetings,
Is there any example I could chew on how to stream YouTube videos? v3.0.11
Opening url with libvlc_media_new_location. Setting libvlc_video_set_format_callbacks then play. The event libvlc_video_set_format_callbacks never fires, neither does libvlc_MediaPlayerVout.
Looking at the debug, an endless loop of text is outputting but no errors it seems.
Any help would be greatly appreciated,
Thank you
Re: Streaming YouTube video?
Posted: 14 Sep 2020 10:07
by mfkl
For youtube links, you need to parse the original URL first and then play one of its subitems (usually the first).
C# example
https://code.videolan.org/videolan/LibV ... tube-video
Re: Streaming YouTube video?
Posted: 14 Sep 2020 17:32
by neosettler
Thank you for your input mfkl, I’m not familiar with the C# api, any idea how this parsing operation would translate to C++?
Re: Streaming YouTube video?
Posted: 15 Sep 2020 09:34
by mfkl
Code: Select all
libvlc_media_new_location
libvlc_media_parse_with_options
libvlc_media_subitems
Re: Streaming YouTube video?
Posted: 24 Sep 2020 23:24
by neosettler
hummm, I'm a bit in the blind here. Is there any working example (Windows ideally) I could get my hands on?
Re: Streaming YouTube video?
Posted: 25 Sep 2020 11:55
by mfkl
https://code.videolan.org/videolan/vlc- ... doc/libvlc
you should probably share your code so people can help you. Are you using C?
Re: Streaming YouTube video?
Posted: 25 Sep 2020 18:17
by neosettler
Thank you for your support, I've been looking at the repo but I dont see anything particular regarding streaming.
The setup is on the spaghetti side so I've extracted the essential.
With this config, libvlc_media_new_location is hit but libvlc_video_get_size returns false and libvlc_video_set_format_callbacks never fires.
Note that I'm rendering to an OpenGL texture but it shouldn't have any impact on the previous statement.
Code: Select all
Bool ZVideoLanMovie::Read(const Char *in_path)
{
Close();
if (ZStr::StartsWith(in_path, "http"))
{
m_Media = libvlc_media_new_location(m_VLC, in_path);
}
else
{
#if defined(ZEN_PLATFORM_WINDOWS)
m_Media = libvlc_media_new_path(m_VLC, ZAgnostic::SlashesToBackSlashes(in_path));
#else
m_Media = libvlc_media_new_path(m_VLC, in_path);
#endif
}
ZenValidateReturn(m_Media, false);
m_Player = libvlc_media_player_new_from_media(m_Media);
ZenValidateReturn(m_Player, false);
return true;
}
Bool ZVideoLanMovie::Open(const Char *in_path, const e_OpenStates &in_mode)
{
if (Read(in_path) == false)
{
Close();
ZenError("%s failed to open media.", in_path);
return false;
}
SetEventHandler(&ZVideoLanMovie::CallbackEvent, this);
libvlc_media_parse(m_Media);
libvlc_media_retain(m_Media);
libvlc_video_set_key_input(m_Player, false);
libvlc_video_set_mouse_input(m_Player, false);
UInt l_h, l_w;
if (libvlc_video_get_size(m_Player, 0, &l_w, &l_h) == 0)
{
if (e_ImageOrientation == ImageOrientationLeftTop ||
e_ImageOrientation == ImageOrientationLeftBottom ||
e_ImageOrientation == ImageOrientationRightTop ||
e_ImageOrientation == ImageOrientationRightBottom)
{
if (l_w != l_h)
{
/// xor swap.
l_w ^= l_h;
l_h ^= l_w;
l_w ^= l_h;
}
}
/// For each pixels plane, the scan line pitch must be bigger than or equal to the number of bytes per pixel multiplied by the pixel width.
/// Similarly, the number of scan lines must be bigger than of equal to the pixel height. We recommend that pitches and lines be multiple of 32.
UInt l_pitch = l_w + (l_w % VLC_PITCH_MULTIPLE);
UInt l_channelCount = GetChannelCount();
libvlc_video_set_format(m_Player, l_channelCount == 3 ? "RV24" : "RV32", l_pitch, l_h, l_pitch * l_channelCount);
CopyPixels(NULL, l_pitch, l_h);
}
else
{
libvlc_video_set_format_callbacks(m_Player, ZVideoLanMovie::CallbackSetup, ZVideoLanMovie::CallbackCleanup);
}
libvlc_video_set_callbacks(m_Player, ZVideoLanMovie::CallbackLock, ZVideoLanMovie::CallbackUnlock, ZVideoLanMovie::CallbackDisplay, this);
libvlc_media_player_play(m_Player);
return true;
}
EDIT: output log as soon as it plays:
Code: Select all
[000002dee4d662b0] main input debug: EOF reached
[000002dee18fc4a0] main demux debug: removing module "directory"
[000002dee18eca50] main stream debug: removing module "record"
[000002dee0c83f40] main stream debug: removing module "lua"
[000002dee5674e90] main stream debug: removing module "prefetch"
[000002dee4d280a0] main stream debug: removing module "access"
[000002dee4d280a0] http stream debug: local stream 1 shut down
[000002dee4d280a0] http stream debug: out RST_STREAM (0x03) frame of 4 bytes, flags 0x00, stream 1
[000002dee4d280a0] http stream debug: local shutdown
[000002dee4d280a0] http stream debug: out GOAWAY (0x07) frame of 8 bytes, flags 0x00, global
[000002dee0ced600] main audio output debug: removing module "directsound"
Re: Streaming YouTube video?
Posted: 28 Sep 2020 09:49
by mfkl
You're mixing a lot of libvlc calls without checking for return values.
First you should try playing a Youtube video with the functions I mentioned previously (2 of which you are not using). You can troubleshoot callbacks after.
If you are planning to render with opengl yourself, then you should use libvlc 4 (preview)
https://github.com/videolan/vlc/blob/ma ... player.cpp
Re: Streaming YouTube video?
Posted: 28 Sep 2020 17:53
by Rémi Denis-Courmont
AFAIK, if you try to play a YouTube video web page in VLC 3.x, you will get a child media item (libvlc_MediaSubItemAdded event) instead of an actual video. You need to then play that child item to get the video.
Re: Streaming YouTube video?
Posted: 29 Sep 2020 03:19
by neosettler
I think I'm getting the hang of it, render to textures always baffles me though. I understand it would be more efficient with 4.0 but last time I checked, webm was not stable so I might give it another try eventually.
As previously suggested, here is the new addition:
Code: Select all
void ZVideoLanMovie::UnlockMutexEvent(const VLC_Event *in_events, void *in_opaque)
{
std::condition_variable *l_cv = static_cast<std::condition_variable *>(in_opaque);
l_cv->notify_one();
}
Bool ZVideoLanMovie::MediaParse(libvlc_media_t *in_media, const libvlc_media_parse_flag_t &in_flags)
{
std::mutex l_mutex;
std::condition_variable l_cv;
std::unique_lock<std::mutex> l_lock(l_mutex);
libvlc_event_attach(m_MediaEventManager, libvlc_MediaParsedChanged, UnlockMutexEvent, &l_cv);
Int l_return = libvlc_media_parse_with_options(in_media, in_flags, 0);
l_cv.wait(l_lock);
libvlc_event_detach(m_MediaEventManager, libvlc_MediaParsedChanged, UnlockMutexEvent, &l_cv);
return l_return == 0;
}
Bool ZVideoLanMovie::Read(const Char *in_path)
{
Close();
m_Player = libvlc_media_player_new(m_VLC);
ZenValidateReturn(m_Player, false);
SetPlayerEvents(&ZVideoLanMovie::CallbackEvent, this);
libvlc_media_parse_flag_t l_flags;
if (ZStr::StartsWith(in_path, "http"))
{
m_Media = libvlc_media_new_location(m_VLC, in_path);
ZenValidateReturn(m_Media, false);
SetMediaEvents(&ZVideoLanMovie::CallbackEvent, this);
l_flags = libvlc_media_parse_network;
}
else
{
m_Media = libvlc_media_new_path(m_VLC, ZAgnostic::SlashesToBackSlashes(in_path));
ZenValidateReturn(m_Media, false);
SetMediaEvents(&ZVideoLanMovie::CallbackEvent, this);
libvlc_media_player_set_media(m_Player, m_Media);
l_flags = libvlc_media_parse_local;
}
if (MediaParse(m_Media, l_flags) == false)
{
ZenError("%s parsing options.", in_path);
}
return true;
}
void ZVideoLanMovie::CallbackEvent(const VLC_Event *in_events, void *in_opaque)
{
ZVideoLanMovie *l_video = static_cast<ZVideoLanMovie *>(in_opaque);
switch (in_events->type)
{
case libvlc_MediaSubItemAdded:
{
ZenStatus("ZVideoLanMovie::libvlc_MediaSubItemAdded");
l_video->m_Media = in_events->u.media_subitem_added.new_child;
libvlc_media_player_set_media(l_video->m_Player, l_video->m_Media);
break;
}
case libvlc_MediaPlayerVout:
{
Int l_count = in_events->u.media_player_vout.new_count;
if (l_count > 0)
{
ZenStatus("ZVideoLanMovie::libvlc_MediaPlayerVout : %d", l_count);
l_video->OnPlaybackReadyEvent();
}
break;
}
};
}
Up until now, I'm still looking for a call back that says: "everything is ready" to setup UI to video size and length. libvlc_MediaPlayerVout seems to be the closest cue but the problem I'm having is that youtube lua script is still processing while libvlc_MediaPlayerVout fires and render to texture sometimes works, sometimes it doesn't.
I'm wondering if anyone could see what am I missing?
Re: Streaming YouTube video?
Posted: 29 Sep 2020 05:15
by neosettler
I just found about libvlc_MediaPlayerBuffering = 100. I think I'm all set. YouTube works fine while Vimeo does not. Oh, well.