본문 바로가기
SWE/스트리밍

Qt GStreamer RTSP Viewer || VLC로 스트리밍해서 테스트하기

by S나라라2 2022. 9. 26.
반응형

qt-gstreamer 예제 player 프로그램 코드를 약간 개조해서 RTSP 로 영상을 재생해보자

 

[VLC 앱] ------streaming--------> [Qt GStreamer Viewer 프로그램]

 

 


여기 예제는 player 코드를 이해한다는 전제하에 설명하고 있다. 

https://flower0.tistory.com/685

 

Qt 동영상 플레이어 예제 코드 분석 | GStreamer

Qt-Gstreamer에서 예제 코드를 몇 개 제공한다. 그 중에서 player코드를 분석해보자. 해당 플레이어는 pc에 저장된 동영상 파일을 읽어와서 재생, 정지, 일시정지 기능을 제공한다. 코드 구조 - 매우 심

flower0.tistory.com

 

 


Qt-Gstreamer player 예제 프로그램

 

Player 예제 코드를 보면 playbin을 이용해 영상을 플레이하고 있다. 

기존 예제에서는 로컬 영상 파일을 로드해서 재생,정지,일시정지 등 컨트롤을 하고 있지만,

해당 파이프라인 playbin에 URI를 전달해주면 동일하게 재생이 가능하다.

 

따라서 UI로 URI입력 받는 창을 추가하여 RTSP로 리모트 영상을 재생해보자.

 

추가 코드

// 버튼 추가. 임의로 SP_ArrowRight 이미지를 사용하였다.

// 버튼을 클릭하면  connectRTSP() 함수가 동작한다.

void MediaApp::createUI(QBoxLayout *appLayout)
{
	...
	m_connectButton = initButton(QStyle::SP_ArrowRight, tr("Connect Server"),
                              this, SLOT(connectRTSP()), btnLayout);
    ...
}

 

추가 코드

// QInputDialog로 URI를 사용자로부터 입력받는다.

// QInputDialog의 다섯번째 인자는 디폴트입력값이다. 사용자가 입력하기 전에 기본으로 입력되어 있다.

void MediaApp::connectRTSP()
{
    bool ok;
    QString url = QInputDialog::getText(this, "RTSP URL", "URL: ", QLineEdit::Normal, "rtsp://[remote local ip]:9000/rtspTest", &ok);

    if( ok && !url.isEmpty() ) 
    {
        std::cout<<"url: "<<url.toStdString()<<std::endl;

        m_player->stop();
        m_player->setUri(url);
        m_player->play();
    }
}

 

위의 코드를 추가하고 실행하면 된다.

 

아래 풀코드 추가해놓겠다.


 

VLC 프로그램에서 RTSP 스트리밍 하기

 

1. VLC 미디어 재생기 프로그램 실행

 

2. 미디어 선택

 

 

3. '스트림하기' 선택

 

4. '추가' 클릭하여 로컬 영상 파일 선택

로컬 폴더에 있는 비디오 영상 파일 선택하기

 

5. '스트림' 선택

 

6. '다음' 선택

 

7.목적지 'RTSP' 선택하고 오른쪽 '추가'버튼 클릭

 

8. 포트랑 경로 입력하고 '다음' 선택

 

9. 프로파일 선택하고 '다음'

개인 비디오 파일에 맞는 프로파일 선택하기 

나는 'webm' 선택함

 

10. '스트림'선택

 

11.완료

 

 

 


QtGStreamer player 실행

'>' 버튼을 클릭하면 RTSP URL 이름의 다이얼로그가 뜬다. 

여기 텍스트인풋 박스에 URL을 입력하고 ok 버튼을 클릭한다.

 

VLC 프로그램으로 스트리밍하고 있는 영상을 Qt-GStreamer player 예제 프로그램에서 재생하는 것을 확인할 수 있다.

 

 


 

Qt GStreamer RTSP Viewer Example

전체 코드

 

// CMakeLists.txt

더보기
project(qtgst-example-player)

 

if (NOT BUILDING_QTGSTREAMER)
    set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules)
    find_package(Qt4or5 COMPONENTS Core Gui Widgets REQUIRED)
    if (${QT_VERSION} STREQUAL "5")
        find_package(Qt5GStreamer REQUIRED)
    else()
        find_package(QtGStreamer REQUIRED)
    endif()
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()

 

include_directories(${QTGSTREAMER_INCLUDES})
add_definitions(${QTGSTREAMER_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QTGSTREAMER_FLAGS}")

 

set(player_SOURCES main.cpp player.cpp mediaapp.cpp)

 

add_executable(hy_player ${player_SOURCES})
target_link_libraries(hy_player ${QTGSTREAMER_UI_LIBRARIES})
qt4or5_use_modules(hy_player Core Gui Widgets)

 

// main.cpp

더보기
/*
    Copyright (C) 2010  Marco Ballesio <gibrovacco@gmail.com>

 

    This library is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published
    by the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.

 

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

 

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "mediaapp.h"
#include <QApplication>
#include <QGst/Init>

 

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QGst::init(&argc, &argv);

 

    MediaApp media;
    media.show();

 

    if (argc == 2) {
        media.openFile(argv[1]);
    }

 

    return app.exec();
}

 

// mediaapp.h

더보기
/*
    Copyright (C) 2010 Marco Ballesio <gibrovacco@gmail.com>
    Copyright (C) 2011 Collabora Ltd.
      @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>

    This library is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published
    by the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MEDIAAPP_H
#define MEDIAAPP_H

#include <QTimer>
#include <QWidget>
#include <QStyle>

class Player;
class QBoxLayout;
class QLabel;
class QSlider;
class QToolButton;
class QTimer;

class MediaApp : public QWidget
{
    Q_OBJECT
public:
    MediaApp(QWidget *parent = 0);
    ~MediaApp();

    void openFile(const QString & fileName);

private Q_SLOTS:
    void connectRTSP();
    void open();
    void toggleFullScreen();

    void onStateChanged();
    void onPositionChanged();

    void setPosition(int position);

    void showControls(bool show = true);
    void hideControls() { showControls(false); }

protected:
    void mouseMoveEvent(QMouseEvent *event);

private:
    QToolButton *initButton(QStyle::StandardPixmap icon, const QString & tip,
                            QObject *dstobj, const char *slot_method, QLayout *layout);
    void createUI(QBoxLayout *appLayout);

    QString m_baseDir;
    Player *m_player;
    QToolButton *m_connectButton;
    QToolButton *m_openButton;
    QToolButton *m_fullScreenButton;
    QToolButton *m_playButton;
    QToolButton *m_pauseButton;
    QToolButton *m_stopButton;
    QSlider *m_positionSlider;
    QSlider *m_volumeSlider;
    QLabel *m_positionLabel;
    QLabel *m_volumeLabel;
    QTimer m_fullScreenTimer;
};

#endif

 

 

 

//mediaapp.cpp

더보기
/*
   Copyright (C) 2010 Marco Ballesio <gibrovacco@gmail.com>
   Copyright (C) 2011 Collabora Ltd.
     @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>

 

   This library is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
   by the Free Software Foundation; either version 2.1 of the License, or
   (at your option) any later version.

 

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.

 

   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "mediaapp.h"
#include "player.h"

 

#include <QBoxLayout>
#include <QFileDialog>
#include <QToolButton>
#include <QLabel>
#include <QSlider>
#include <QMouseEvent>
#include <QInputDialog>

 

#include <iostream>

 

MediaApp::MediaApp(QWidget *parent)
    : QWidget(parent)
{
    //create the player
    m_player = new Player(this);
    connect(m_player, SIGNAL(positionChanged()), this, SLOT(onPositionChanged()));
    connect(m_player, SIGNAL(stateChanged()), this, SLOT(onStateChanged()));

 

    //m_baseDir is used to remember the last directory that was used.
    //defaults to the current working directory
    m_baseDir = QLatin1String(".");

 

    //this timer (re-)hides the controls after a few seconds when we are in fullscreen mode
    m_fullScreenTimer.setSingleShot(true);
    connect(&m_fullScreenTimer, SIGNAL(timeout()), this, SLOT(hideControls()));

 

    //create the UI
    QVBoxLayout *appLayout = new QVBoxLayout;
    appLayout->setContentsMargins(0, 0, 0, 0);
    createUI(appLayout);
    setLayout(appLayout);

 

    onStateChanged(); //set the controls to their default state

 

    setWindowTitle(tr("QtGStreamer example player"));
    resize(400, 400);
}

 

MediaApp::~MediaApp()
{
    delete m_player;
}

 

void MediaApp::openFile(const QString & fileName)
{
    m_baseDir = QFileInfo(fileName).path();

 

    m_player->stop();
    m_player->setUri(fileName);
    m_player->play();
}

 

void MediaApp::connectRTSP()
{
    bool ok;
    QString url = QInputDialog::getText(this, "RTSP URL", "URL: ", QLineEdit::Normal, "rtsp://[remote local ip]:9000/rtspTest", &ok);

 

    if( ok && !url.isEmpty() )
    {
        std::cout<<"url: "<<url.toStdString()<<std::endl;

 

        m_player->stop();
        m_player->setUri(url);
        m_player->play();
    }
}

 

void MediaApp::open()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open a Movie"), m_baseDir);

 

    if (!fileName.isEmpty()) {
        openFile(fileName);
    }
}

 

void MediaApp::toggleFullScreen()
{
    if (isFullScreen()) {
        setMouseTracking(false);
        m_player->setMouseTracking(false);
        m_fullScreenTimer.stop();
        showControls();
        showNormal();
    } else {
        setMouseTracking(true);
        m_player->setMouseTracking(true);
        hideControls();
        showFullScreen();
    }
}

 

void MediaApp::onStateChanged()
{
    QGst::State newState = m_player->state();
    m_playButton->setEnabled(newState != QGst::StatePlaying);
    m_pauseButton->setEnabled(newState == QGst::StatePlaying);
    m_stopButton->setEnabled(newState != QGst::StateNull);
    m_positionSlider->setEnabled(newState != QGst::StateNull);
    m_volumeSlider->setEnabled(newState != QGst::StateNull);
    m_volumeLabel->setEnabled(newState != QGst::StateNull);
    m_volumeSlider->setValue(m_player->volume());

 

    //if we are in Null state, call onPositionChanged() to restore
    //the position of the slider and the text on the label
    if (newState == QGst::StateNull) {
        onPositionChanged();
    }
}

 

/* Called when the positionChanged() is received from the player */
void MediaApp::onPositionChanged()
{
    QTime length(0,0);
    QTime curpos(0,0);

 

    if (m_player->state() != QGst::StateReady &&
        m_player->state() != QGst::StateNull)
    {
        length = m_player->length();
        curpos = m_player->position();
    }

 

    m_positionLabel->setText(curpos.toString("hh:mm:ss.zzz")
                                        + "/" +
                             length.toString("hh:mm:ss.zzz"));

 

    if (length != QTime(0,0)) {
        m_positionSlider->setValue(curpos.msecsTo(QTime(0,0)) * 1000 / length.msecsTo(QTime(0,0)));
    } else {
        m_positionSlider->setValue(0);
    }

 

    if (curpos != QTime(0,0)) {
        m_positionLabel->setEnabled(true);
        m_positionSlider->setEnabled(true);
    }
}

 

/* Called when the user changes the slider's position */
void MediaApp::setPosition(int value)
{
    uint length = -m_player->length().msecsTo(QTime(0,0));
    if (length != 0 && value > 0) {
        QTime pos(0,0);
        pos = pos.addMSecs(length * (value / 1000.0));
        m_player->setPosition(pos);
    }
}

 

void MediaApp::showControls(bool show)
{
    m_connectButton->setVisible(show);
    m_openButton->setVisible(show);
    m_playButton->setVisible(show);
    m_pauseButton->setVisible(show);
    m_stopButton->setVisible(show);
    m_fullScreenButton->setVisible(show);
    m_positionSlider->setVisible(show);
    m_volumeSlider->setVisible(show);
    m_volumeLabel->setVisible(show);
    m_positionLabel->setVisible(show);
}

 

void MediaApp::mouseMoveEvent(QMouseEvent *event)
{
    Q_UNUSED(event);
    if (isFullScreen()) {
        showControls();
        m_fullScreenTimer.start(3000); //re-hide controls after 3s
    }
}

 

QToolButton *MediaApp::initButton(QStyle::StandardPixmap icon, const QString & tip,
                                  QObject *dstobj, const char *slot_method, QLayout *layout)
{
    QToolButton *button = new QToolButton;
    button->setIcon(style()->standardIcon(icon));
    button->setIconSize(QSize(36, 36));
    button->setToolTip(tip);
    connect(button, SIGNAL(clicked()), dstobj, slot_method);
    layout->addWidget(button);

 

    return button;
}

 

void MediaApp::createUI(QBoxLayout *appLayout)
{
    appLayout->addWidget(m_player);

 

    m_positionLabel = new QLabel();

 

    m_positionSlider = new QSlider(Qt::Horizontal);
    m_positionSlider->setTickPosition(QSlider::TicksBelow);
    m_positionSlider->setTickInterval(10);
    m_positionSlider->setMaximum(1000);

 

    connect(m_positionSlider, SIGNAL(sliderMoved(int)), this, SLOT(setPosition(int)));

 

    m_volumeSlider = new QSlider(Qt::Horizontal);
    m_volumeSlider->setTickPosition(QSlider::TicksLeft);
    m_volumeSlider->setTickInterval(2);
    m_volumeSlider->setMaximum(10);
    m_volumeSlider->setMaximumSize(64,32);

 

    connect(m_volumeSlider, SIGNAL(sliderMoved(int)), m_player, SLOT(setVolume(int)));

 

    QGridLayout *posLayout = new QGridLayout;
    posLayout->addWidget(m_positionLabel, 1, 0);
    posLayout->addWidget(m_positionSlider, 1, 1, 1, 2);
    appLayout->addLayout(posLayout);

 

    QHBoxLayout *btnLayout = new QHBoxLayout;
    btnLayout->addStretch();

 

    m_connectButton = initButton(QStyle::SP_ArrowRight, tr("Connect Server"),
                              this, SLOT(connectRTSP()), btnLayout);

 

    m_openButton = initButton(QStyle::SP_DialogOpenButton, tr("Open File"),
                              this, SLOT(open()), btnLayout);

 

    m_playButton = initButton(QStyle::SP_MediaPlay, tr("Play"),
                              m_player, SLOT(play()), btnLayout);

 

    m_pauseButton = initButton(QStyle::SP_MediaPause, tr("Pause"),
                               m_player, SLOT(pause()), btnLayout);

 

    m_stopButton = initButton(QStyle::SP_MediaStop, tr("Stop"),
                              m_player, SLOT(stop()), btnLayout);

 

    m_fullScreenButton = initButton(QStyle::SP_TitleBarMaxButton, tr("Fullscreen"),
                                    this, SLOT(toggleFullScreen()), btnLayout);
    btnLayout->addStretch();

 

    m_volumeLabel = new QLabel();
    m_volumeLabel->setPixmap(
        style()->standardIcon(QStyle::SP_MediaVolume).pixmap(QSize(32, 32),
                QIcon::Normal, QIcon::On));

 

    btnLayout->addWidget(m_volumeLabel);
    btnLayout->addWidget(m_volumeSlider);
    appLayout->addLayout(btnLayout);
}

 

#include "moc_mediaapp.cpp"

 

 

// player.h

더보기
/*
    Copyright (C) 2010 Marco Ballesio <gibrovacco@gmail.com>
    Copyright (C) 2011 Collabora Ltd.
      @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>

 

    This library is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published
    by the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.

 

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

 

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PLAYER_H
#define PLAYER_H

 

#include <QTimer>
#include <QTime>
#include <QGst/Pipeline>
#include <QGst/Ui/VideoWidget>

 

class Player : public QGst::Ui::VideoWidget
{
    Q_OBJECT
public:
    Player(QWidget *parent = 0);
    ~Player();

 

private:
    QString m_url;
    QString m_port;

 

public:
    void setUri(const QString & uri);

 

    QTime position() const;
    void setPosition(const QTime & pos);
    int volume() const;

 

    QTime length() const;
    QGst::State state() const;

 

public Q_SLOTS:
    void play();
    void pause();
    void stop();
    void setVolume(int volume);

 

Q_SIGNALS:
    void positionChanged();
    void stateChanged();

 

private:
    void onBusMessage(const QGst::MessagePtr & message);
    void handlePipelineStateChange(const QGst::StateChangedMessagePtr & scm);

 

    QGst::PipelinePtr m_pipeline;
    QTimer m_positionTimer;
};

 

#endif

 

 

 

// player.cpp

더보기
/*
    Copyright (C) 2010 Marco Ballesio <gibrovacco@gmail.com>
    Copyright (C) 2011 Collabora Ltd.
      @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>

 

    This library is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published
    by the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.

 

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

 

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "player.h"
#include <QDir>
#include <QUrl>
#include <QRegExp>
#include <QGlib/Connect>
#include <QGlib/Error>
#include <QGst/Pipeline>
#include <QGst/ElementFactory>
#include <QGst/Bus>
#include <QGst/Message>
#include <QGst/Query>
#include <QGst/ClockTime>
#include <QGst/Event>
#include <QGst/StreamVolume>

 

#include <iostream>

 

Player::Player(QWidget *parent)
    : QGst::Ui::VideoWidget(parent)
{
    //this timer is used to tell the ui to change its position slider & label
    //every 100 ms, but only when the pipeline is playing
    connect(&m_positionTimer, SIGNAL(timeout()), this, SIGNAL(positionChanged()));
}

 

Player::~Player()
{
    if (m_pipeline) {
        m_pipeline->setState(QGst::StateNull);
        stopPipelineWatch();
    }
}



// rtsp://55.101.57.164:9000/rtspTest
void Player::setUri(const QString & uri)
{
    QString realUri = uri;

 

    //if uri is not a real uri, assume it is a file path
    if (realUri.indexOf("://") < 0) {
        realUri = QUrl::fromLocalFile(realUri).toEncoded();
    }

 

    // get port
    if( realUri.indexOf(":", QString("rtsp://").length()) > 0  ) {
        QRegExp re("(rtsp:\\/\\/)([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+):([0-9]+)/([a-zA-Z]+)");
        re.indexIn(realUri);
        QStringList list = re.capturedTexts();

 

        m_port = list.at(3);
        std::cout<<"port: "<<m_port.toStdString()<<std::endl;
    }

 

    if (!m_pipeline) {
       
        m_pipeline = QGst::ElementFactory::make("playbin").dynamicCast<QGst::Pipeline>();
        if (m_pipeline) {
            //let the video widget watch the pipeline for new video sinks
            watchPipeline(m_pipeline);

 

            //watch the bus for messages
            QGst::BusPtr bus = m_pipeline->bus();
            bus->addSignalWatch();
            QGlib::connect(bus, "message", this, &Player::onBusMessage);
        } else {
            qCritical() << "Failed to create the pipeline";
        }
    }

 

    if (m_pipeline) {
        std::cout<<"uri: "<<reaUri.toStdString()<<std::endl;
        m_pipeline->setProperty("uri", realUri);
    }

 

    m_url = realUri;
}

 

QTime Player::position() const
{
    if (m_pipeline) {
        //here we query the pipeline about its position
        //and we request that the result is returned in time format
        QGst::PositionQueryPtr query = QGst::PositionQuery::create(QGst::FormatTime);
        m_pipeline->query(query);
        return QGst::ClockTime(query->position()).toTime();
    } else {
        return QTime(0,0);
    }
}

 

void Player::setPosition(const QTime & pos)
{
    QGst::SeekEventPtr evt = QGst::SeekEvent::create(
        1.0, QGst::FormatTime, QGst::SeekFlagFlush,
        QGst::SeekTypeSet, QGst::ClockTime::fromTime(pos),
        QGst::SeekTypeNone, QGst::ClockTime::None
    );

 

    m_pipeline->sendEvent(evt);
}

 

int Player::volume() const
{
    if (m_pipeline) {
        QGst::StreamVolumePtr svp =
            m_pipeline.dynamicCast<QGst::StreamVolume>();

 

        if (svp) {
            return svp->volume(QGst::StreamVolumeFormatCubic) * 10;
        }
    }

 

    return 0;
}



void Player::setVolume(int volume)
{
    if (m_pipeline) {
        QGst::StreamVolumePtr svp =
            m_pipeline.dynamicCast<QGst::StreamVolume>();

 

        if(svp) {
            svp->setVolume((double)volume / 10, QGst::StreamVolumeFormatCubic);
        }
    }
}

 

QTime Player::length() const
{
    if (m_pipeline) {
        //here we query the pipeline about the content's duration
        //and we request that the result is returned in time format
        QGst::DurationQueryPtr query = QGst::DurationQuery::create(QGst::FormatTime);
        m_pipeline->query(query);
        return QGst::ClockTime(query->duration()).toTime();
    } else {
        return QTime(0,0);
    }
}

 

QGst::State Player::state() const
{
    return m_pipeline ? m_pipeline->currentState() : QGst::StateNull;
}

 

void Player::play()
{
    if (m_pipeline) {
        m_pipeline->setState(QGst::StatePlaying);
    }
}

 

void Player::pause()
{
    if (m_pipeline) {
        m_pipeline->setState(QGst::StatePaused);
    }
}

 

void Player::stop()
{
    if (m_pipeline) {
        m_pipeline->setState(QGst::StateNull);

 

        //once the pipeline stops, the bus is flushed so we will
        //not receive any StateChangedMessage about this.
        //so, to inform the ui, we have to emit this signal manually.
        Q_EMIT stateChanged();
    }
}

 

void Player::onBusMessage(const QGst::MessagePtr & message)
{
    switch (message->type()) {
    case QGst::MessageEos: //End of stream. We reached the end of the file.
        stop();
        break;
    case QGst::MessageError: //Some error occurred.
        qCritical() << message.staticCast<QGst::ErrorMessage>()->error();
        stop();
        break;
    case QGst::MessageStateChanged: //The element in message->source() has changed state
        if (message->source() == m_pipeline) {
            handlePipelineStateChange(message.staticCast<QGst::StateChangedMessage>());
        }
        break;
    default:
        break;
    }
}

 

void Player::handlePipelineStateChange(const QGst::StateChangedMessagePtr & scm)
{
    switch (scm->newState()) {
    case QGst::StatePlaying:
        //start the timer when the pipeline starts playing
        m_positionTimer.start(100);
        break;
    case QGst::StatePaused:
        //stop the timer when the pipeline pauses
        if(scm->oldState() == QGst::StatePlaying) {
            m_positionTimer.stop();
        }
        break;
    default:
        break;
    }

 

    Q_EMIT stateChanged();
}

 

#include "moc_player.cpp"

 

 

// player.pro

더보기

# This is a qmake project file, provided as an example on how to use qmake with QtGStreamer.

TEMPLATE = app
TARGET = player

# produce nice compilation output
CONFIG += silent

# Tell qmake to use pkg-config to find QtGStreamer.
CONFIG += link_pkgconfig

# Now tell qmake to link to QtGStreamer and also use its include path and Cflags.
contains(QT_VERSION, ^4\\..*) {
  PKGCONFIG += QtGStreamer-1.0 QtGStreamerUi-1.0
}
contains(QT_VERSION, ^5\\..*) {
  PKGCONFIG += Qt5GStreamer-1.0 Qt5GStreamerUi-1.0
  QT += widgets
}

# Recommended if you are using g++ 4.5 or later. Must be removed for other compilers.
#QMAKE_CXXFLAGS += -std=c++0x

# Recommended, to avoid possible issues with the "emit" keyword
# You can otherwise also define QT_NO_EMIT, but notice that this is not a documented Qt macro.
DEFINES += QT_NO_KEYWORDS

# Input
HEADERS += mediaapp.h player.h
SOURCES += main.cpp mediaapp.cpp player.cpp

반응형