“This is the 11th day of my participation in the Gwen Challenge in November. See details: The Last Gwen Challenge in 2021”

I. Function introduction

The libvlc broadcast engine supports streaming video over various protocols, such as RTMP and RTSP, in addition to local videos.

Libvlc has been used in several articles, but this article continues with libvlc: playing a video for a specific protocol.

Libvlc provides two ways to open a video directly:

/** * Create a media with a certain given media resource location, * for instance a valid URL. * * \note To refer to a local file with this function, * the file://... URI syntax must be used (see IETF RFC3986). * We recommend using libvlc_media_new_path() instead when dealing with * local files. * * \see libvlc_media_release * * \param p_instance the instance * \param psz_mrl the media location  * \return the newly created media or NULL on error */
LIBVLC_API libvlc_media_t *libvlc_media_new_location(
                                   libvlc_instance_t *p_instance,
                                   const char * psz_mrl );

/** * Create a media for a certain file path. * * \see libvlc_media_release * * \param p_instance the instance * \param path local filesystem path * \return the newly created media or NULL on error */
LIBVLC_API libvlc_media_t *libvlc_media_new_path(
                                   libvlc_instance_t *p_instance,
                                   const char *path );
Copy the code

Libvlc_media_new_path is used to open the local video file, which can be directly passed to the local disk path. Such as:

libvlc_media_new_path(vlc_base,"D:\\work\\test.mp4");
Copy the code

Note: The path passed by libvlc_media_new_path on Windows must have a double right slash. If the default path is a left slash, you can use STD ::replace to convert it.

filename="D:/work/test.mp4";
std::replace(filename.begin(), filename.end(), QChar('/'), QChar('\ \'));
Copy the code

The other libvlc_media_new_location function is used to turn on the protocol. This function is more powerful and supports many protocols. Local videos can also be opened using this function, which is a bit more general, and the path slash is just a normal left slash (Linux style), no conversion is required.

The following are some common usage examples:

Open a local file:libvlc_media_new_location (inst, "file:///D:/work/test.mp4"); Open RTSP streaming:libvlc_media_new_location (inst, "RTSP: / / 10.0.0.4:554 / CAM"); To open RTMP streaming media:libvlc_media_new_location (inst, "RTMP: / / 10.0.0.4:554 / CAM"); Play the current desktop screen:libvlc_media_new_location (inst, "screen://");
Copy the code

Note: Do not convert the path using STD ::replace after opening the path using the libvlc_media_new_location function.

Play desktop screen effect: libvlc_media_new_location (inst, "screen://")

Play the RTMP stream effect

libvlc_media_new_location (inst, "rtmp://media3.scctv.net/live/scctv_800")

Second, complete code sample

#include "widget.h"
#include "ui_widget.h"

Widget* Widget::pThis = nullptr;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    pThis=this;

    ui->setupUi(this);
	
    // Create and initialize the libvlc instance
    vlc_base=libvlc_new(0.nullptr);

    this->setWindowTitle("Video player designed by LibvLC");

}


Widget::~Widget()
{
    delete ui;
}

// Select the video
void Widget::on_pushButton_open_clicked(a)
{
    /* Select file */
    filename=QFileDialog::getOpenFileName(this."Select open file"."D:/".tr("*. *"));

    filename="file:///"+filename;

    /* Stop the media file */
    if(vlc_mediaPlayer)libvlc_media_player_stop(vlc_mediaPlayer);
    //QThread::msleep(5000);

    /* Create media for a specific file path */
    if(vlc_media)libvlc_media_release(vlc_media);
   // vlc_media=libvlc_media_new_path(vlc_base,filename.toUtf8().data());
    vlc_media=libvlc_media_new_location (vlc_base,filename.toUtf8().data());
    if(vlc_media==nullptr)
    {
        qDebug() < <"Libvlc_media_new_path execution error.";
        return;
    }


    /* Creates a player object based on the given media object */
    if(vlc_mediaPlayer)libvlc_media_player_release(vlc_mediaPlayer);
    vlc_mediaPlayer=libvlc_media_player_new_from_media(vlc_media);

    // Ignore event handling (so libvlc can't catch mouse and keyboard events)
    if (vlc_mediaPlayer)libvlc_video_set_mouse_input(vlc_mediaPlayer, false);
    if (vlc_mediaPlayer)libvlc_video_set_key_input(vlc_mediaPlayer, false);


    // Create event manager
    eventManager = libvlc_media_player_event_manager(vlc_mediaPlayer);

    // Subscribe to events
    attachEvents(eventManager);

    /* Set win32/ Win64 window handle to give media player media output */
    libvlc_media_player_set_hwnd(vlc_mediaPlayer, (void *)ui->widget->winId());

    /* Play the media file */
    if(vlc_mediaPlayer)libvlc_media_player_play(vlc_mediaPlayer);

    // Wait for VLC to parse the file. Otherwise, the following time acquisition fails
    QThread::msleep(500);

    // Get the total length of the media file ms
    libvlc_time_t length = libvlc_media_player_get_length(vlc_mediaPlayer);
    qDebug() < <"Total media file Length :"<<length;
    ui->label_t2->setText(QTime(0.0.0.0).addMSecs(int(length)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
    ui->horizontalSlider_pos->setMaximum(length);
    ui->horizontalSlider_pos->setMinimum(0);
}


// Pause and continue
void Widget::on_pushButton_pause_clicked(a)
{
    if(vlc_mediaPlayer)libvlc_media_player_pause(vlc_mediaPlayer);
}

/ / stop
void Widget::on_pushButton_stop_clicked(a)
{
    if(vlc_mediaPlayer)libvlc_media_player_stop(vlc_mediaPlayer);
}


// Subscribe to events
void Widget::attachEvents(libvlc_event_manager_t *eventManager)
{
    // Event list
    QList<libvlc_event_e> events = {
        libvlc_MediaPlayerPositionChanged,
        libvlc_MediaPlayerTimeChanged,
        libvlc_MediaPlayerLengthChanged,
        libvlc_MediaPlayerPaused,
        libvlc_MediaPlayerPlaying,
        libvlc_MediaPlayerStopped,
        libvlc_MediaPlayerEndReached,
        libvlc_MediaParsedChanged
    };

    // Subscribe to events
    for (const libvlc_event_e &e : events)
    {
        libvlc_event_attach(eventManager, e, vlcEvents, nullptr); }}void Widget::vlcEvents(const libvlc_event_t *event, void *param)
{
    qint64 pos=0;
    switch (event->type){
    case libvlc_MediaPlayerTimeChanged:
         // Get the current media playback position
         pos=event->u.media_player_time_changed.new_time;
         pThis->ui->label_t1->setText(QTime(0.0.0.0).addMSecs(int(pos)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
         pThis->ui->horizontalSlider_pos->setValue(pos);
         qDebug() < <"pos:"<<pos;
         break;
    case libvlc_MediaPlayerPositionChanged:
         //qDebug() << "Position: " << event->u.media_player_position_changed.new_position << endl;
         break;
    case libvlc_MediaPlayerLengthChanged:
         qDebug() < <"Length:"<< event->u.media_player_length_changed.new_length;
         break;
    case libvlc_MediaPlayerEndReached:
         qDebug() < <"VLC finished.";
         break;
    case libvlc_MediaPlayerStopped:
         qDebug() < <"VLC stops playing";
         break;
    case libvlc_MediaPlayerPlaying:
         qDebug() < <"VLC starts playing";
         break;
    case libvlc_MediaPlayerPaused:
         qDebug() < <"VLC pause play";
         break;
    case libvlc_MediaParsedChanged: // Get media information
          qDebug() < <"Access to media information";
         break; }}Copy the code