Getting Raw Audio Data with libVLC on Qt Application
Posted: 15 Mar 2022 19:04
Hello, I have been developing a Qt Application that uses libVLC to display output from game capture cards for video/audio analysis.
I have all the video output working fine for a while now and I want to start looking into how to get audio data to first doing visualizations and ultimately do audio analysis.
The tutorial I'm following is from here:
https://wiki.videolan.org/Stream_to_mem ... _tutorial/
However, when I initialize vlc instance with the smem options, the callback functions doesn't get called at all, I'm not sure what I'm missing...
Here's my code, I also include the part where it starts the mediaplayer with capture card in case there are things that affects it:
I have all the video output working fine for a while now and I want to start looking into how to get audio data to first doing visualizations and ultimately do audio analysis.
The tutorial I'm following is from here:
https://wiki.videolan.org/Stream_to_mem ... _tutorial/
However, when I initialize vlc instance with the smem options, the callback functions doesn't get called at all, I'm not sure what I'm missing...
Here's my code, I also include the part where it starts the mediaplayer with capture card in case there are things that affects it:
Code: Select all
// Audio prerender callback
static void cbAudioPrerender (void* p_audio_data, uint8_t** pp_pcm_buffer , unsigned int size)
{
qDebug() << "test"
}
// Audio postrender callback
static void cbAudioPostrender(void* p_audio_data, uint8_t* p_pcm_buffer, unsigned int channels, unsigned int rate, unsigned int nb_samples, unsigned int bits_per_sample, unsigned int size, int64_t pts )
{
}
VLCWrapper::VLCWrapper(QLabel* videoWidget, QSlider* volumeSlider, QWidget *parent)
: QWidget(parent)
, m_volumeSlider(volumeSlider)
, m_videoWidget(videoWidget)
{
char smem_options[256];
sprintf(smem_options
, "#transcode{acodec=s16l}:smem{"
"audio-prerender-callback=%lld,"
"audio-postrender-callback=%lld,"
"audio-data=%lld}"
, (long long int)(intptr_t)(void*)&cbAudioPrerender
, (long long int)(intptr_t)(void*)&cbAudioPostrender
, (long long int)&ctxAudio);
const char* const vlc_args[] = {
"--intf", "dummy",
"--vout", "dummy",
"--sout", smem_options
};
m_instance = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
m_mediaPlayer = libvlc_media_player_new(m_instance);
ctx.m_label = m_videoWidget;
ctx.m_pixels = new uchar[VIDEO_WIDTH * VIDEO_HEIGHT * 4];
memset(ctx.m_pixels, 0, VIDEO_WIDTH * VIDEO_HEIGHT * 4);
}
bool VLCWrapper::start(const QString &vdev, const QString &adev)
{
if (vdev.isEmpty() && adev.isEmpty()) return false;
m_media = libvlc_media_new_location(m_instance, "dshow://");
// Video
QString vdevOption = ":dshow-vdev=";
vdevOption += vdev.isEmpty() ? "none" : vdev;
libvlc_media_add_option(m_media, vdevOption.toStdString().c_str());
// Audio
QString adevOption = ":dshow-adev=";
adevOption += adev.isEmpty() ? "none" : adev;
libvlc_media_add_option(m_media, adevOption.toStdString().c_str());
// Aspect ratio, resolution
libvlc_media_add_option(m_media, ":dshow-aspect-ratio=16:9");
// Caching
libvlc_media_add_option(m_media, ":live-caching=0");
// Pass to player and release media
libvlc_media_player_set_media(m_mediaPlayer, m_media);
libvlc_media_release(m_media);
// Set the callback to extract the frame or display it on the screen
ctx.m_frame = QImage(VIDEO_WIDTH, VIDEO_HEIGHT, QImage::Format_ARGB32);
ctx.m_frame.fill(QColor(0,0,0));
libvlc_video_set_callbacks(m_mediaPlayer, lock, unlock, display, &ctx);
libvlc_video_set_format(m_mediaPlayer, "BGRA", VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_WIDTH * 4);
// Play media
int result = libvlc_media_player_play(m_mediaPlayer);
if (result == -1)
{
return false;
}
else
{
libvlc_video_set_adjust_int(m_mediaPlayer, libvlc_video_adjust_option_t::libvlc_adjust_Enable, true);
return true;
}
}