├── .gitignore ├── LICENSE ├── README.md ├── bld_qtmultimedia.bat ├── setcompilerenv.bat ├── setupqtbldenv.bat └── videotst ├── main.cpp ├── main.qml ├── qml.qrc └── videotst.pro /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Gunnar Roth 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # How to use Qt in Windows with gstreamer, especially to display rtsp streams 2 | This repository contains scripts, simple sample programs and documentation to build qtmultimedia support with gstreamer on windows 10 and Visual Studio 2017/19. 3 | Additonally a simple test program is provided , which shows an publicly available(at the time of this writing) rtsp stream inside a qml application. 4 | 5 | Note that I only did this for the 64 bit version of Qt and gstreamer on Windows 10. 6 | 7 | ## Prerequisite 8 | 9 | 1. Install Visual Studio 2017 or 2019 (recommended). Community version is sufficient. 10 | 2. Install Qt for windows >= 5.13 (my tests were made with Qt 5.15.0) for your Visual Studio version 11 | 3. Install gstreamer-1.0 packages for windows and msvc. 12 | * https://gstreamer.freedesktop.org/data/pkg/windows/1.18.0/msvc/gstreamer-1.0-msvc-x86_64-1.18.0.msi 13 | * https://gstreamer.freedesktop.org/data/pkg/windows/1.18.0/msvc/gstreamer-1.0-devel-msvc-x86_64-1.18.0.msi 14 | 15 | Note that Windows 10 will probably block the installation, as the msi is unsigned. 16 | Click on the More info link in the warning box, which appears and press the appearing Run Anyway Button. 17 | See also https://www.youtube.com/watch?v=_JZNCypATOY 18 | 19 | ## Build QtMultimedia with gstreamer support. 20 | 21 | 1. Open a command shell 22 | 2. clone this repository 23 | 3. cd into the repository directory 24 | 4. clone the qtmultimedia repository 25 | * ```` git clone http://code.qt.io/qt/qtmultimedia.git ```` 26 | * ```` cd qtmultimedia```` 27 | * ```` git checkout ```` *\* should match the qt version tag, you have installed, e.g. v5.15.1 28 | * ```` cd .. ```` 29 | 30 | 5. execute ````bld_qtmultimedia.bat []}```` ( you can give an alternative install directory as second parameter without the volume, for example ````bld_qtmultimedia.bat C:\Qt\5.15.0 \Users\\qtmultimedia```` to get a add-on installation, which you can copy onto other Qt installations of the same type and version ) 31 | 32 | ## Build and run a video test application using rtsp url. 33 | 34 | 1. execute ````setupqtbldenv.bat c:\Qt\5.15.1```` or where you have qt installed. (You can also give the full path to the qt bin directory as parameter) 35 | 2. ````cd videotst```` 36 | 2. ````qmake```` 37 | 2. ````jom```` or ````nmake```` 38 | 2. ````release\videotst```` 39 | 40 | Now the rtsp stream rtsp://170.93.143.139/rtplive/470011e600ef003a004ee33696235daa showing a highway will be displayed. 41 | 42 | 43 | ### Bonus: creating your own rtsp stream from your notebook webcam 44 | 45 | 1. download and unzip http://www.happytimesoft.com/downloads/happytime-rtsp-server-x64.zip 46 | 2. start rtspserver.exe in the unzipped directory 47 | 3. copy the url shown below "stream from camera device." in the appearing dos box. 48 | 4. I had to add 1 to the end of the url (making it videodevice1), when setting it as source property in the Video element in main.qml. 49 | 5. After a rebuild with nmake or jom, start ````release\videotst```` and you will hopefully see yourself ;-). 50 | -------------------------------------------------------------------------------- /bld_qtmultimedia.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal enableDelayedExpansion 3 | if not defined GSTREAMER_1_0_ROOT_MSVC_X86_64 ( 4 | echo Error:GSTREAMER_1_0_ROOT_MSVC_X86_64 is not set. 5 | exit /b 1 6 | ) 7 | set gstbin=%GSTREAMER_1_0_ROOT_MSVC_X86_64%\bin 8 | @if not defined _echo echo off 9 | 10 | 11 | FOR /F "tokens=* USEBACKQ" %%F IN (`where jom`) DO ( 12 | SET MAKECMD=%%F 13 | ) 14 | if not defined MAKECMD set "MAKECMD=nmake" 15 | 16 | echo %path%|find /i "%gstbin:"=%">nul || set path=%gstbin%;%path% 17 | SETLOCAL EnableDelayedExpansion 18 | call %~dp0setupqtbldenv.bat %1 19 | if %ERRORLEVEL% NEQ 0 ( 20 | echo setupqtbldenv %1 failed. 21 | exit /b 1 22 | ) 23 | pushd %~dp0\qtmultimedia 24 | set INCLUDE=%GSTREAMER_1_0_ROOT_MSVC_X86_64%\include\gstreamer-1.0;%GSTREAMER_1_0_ROOT_MSVC_X86_64%\include;%GSTREAMER_1_0_ROOT_MSVC_X86_64%\include\glib-2.0;%GSTREAMER_1_0_ROOT_MSVC_X86_64%\lib\glib-2.0\include;%INCLUDE% 25 | set LIB=%GSTREAMER_1_0_ROOT_MSVC_X86_64%\lib;%LIB% 26 | echo "INCLUDE=%INCLUDE%" 27 | ECHO "LIB=%LIB% 28 | qmake 29 | if %ERRORLEVEL% NEQ 0 ( 30 | echo qmake failed. 31 | goto :fail 32 | ) 33 | call %MAKECMD% 34 | if %ERRORLEVEL% NEQ 0 ( 35 | echo %MAKECMD% failed. 36 | goto :fail 37 | ) 38 | set INSTALL_ROOT=%2 39 | nmake install 40 | if %ERRORLEVEL% NEQ 0 ( 41 | echo Install failed. 42 | goto :fail 43 | ) 44 | popd 45 | 46 | 47 | exit /b 0 48 | 49 | :fail 50 | popd 51 | exit /b 1 52 | -------------------------------------------------------------------------------- /setcompilerenv.bat: -------------------------------------------------------------------------------- 1 | @if not defined _echo echo off 2 | 3 | if defined VCINSTALLDIR ( 4 | echo Info: VCINSTALLDIR is set, so compiler env was setup already 5 | exit /b 0 6 | ) 7 | setlocal enableDelayedExpansion 8 | 9 | if "%~1" == "" ( 10 | set "VSCMD=-arch=x64 -host_arch=x64" 11 | ) 12 | 13 | set rlocalp=Microsoft Visual Studio\Installer\vswhere.exe 14 | echo "%ProgramFiles(x86)%\!rlocalp!" 15 | if exist "%ProgramFiles(x86)%\!rlocalp!" ( 16 | set vswbin="%ProgramFiles(x86)%\!rlocalp!" 17 | ) else if exist "%ProgramFiles%\!rlocalp!" ( 18 | set vswbin="%ProgramFiles%\!rlocalp!" 19 | ) else ( 20 | echo "Error: cannot find vswhere.exe" 21 | ) 22 | endlocal&set "vswbin=%vswbin%"&set "VSCMD=%VSCMD% 23 | 24 | 25 | for /f "usebackq delims=" %%i in (`%vswbin% -prerelease -latest -property installationPath`) do ( 26 | if exist "%%i\Common7\Tools\vsdevcmd.bat" ( 27 | call "%%i\Common7\Tools\vsdevcmd.bat" %* %VSCMD% 28 | exit /b 0 29 | ) 30 | ) 31 | 32 | echo "No Compiler installation found with vswhere" 33 | exit /b 2 -------------------------------------------------------------------------------- /setupqtbldenv.bat: -------------------------------------------------------------------------------- 1 | @if not defined _echo echo off 2 | 3 | if "%~1" == "" ( 4 | echo Need path to qt installation as parameter, either root as c:\Qt\5.15.0 or dir as in c:\Qt\5.15.0\msvcyyyy_64 5 | exit /b 1 6 | ) 7 | set QTDIR=%1 8 | 9 | 10 | call %~dp0setcompilerenv.bat -arch=x64 -host_arch=x64 11 | if not defined GSTREAMER_1_0_ROOT_MSVC_X86_64 ( 12 | echo gstreamer 1.0 64 bit for msvc is not installed. 13 | echo Download the following packages and install them. 14 | echo https://gstreamer.freedesktop.org/data/pkg/windows/1.18.0/msvc/gstreamer-1.0-msvc-x86_64-1.18.0.msi 15 | echo https://gstreamer.freedesktop.org/data/pkg/windows/1.18.0/msvc/gstreamer-1.0-devel-msvc-x86_64-1.18.0.msi 16 | 17 | exit /b 1 18 | ) 19 | set gstbin=%GSTREAMER_1_0_ROOT_MSVC_X86_64%\bin 20 | echo %path%|find /i "%gstbin:"=%">nul || set path=%gstbin%;%path% 21 | 22 | 23 | call :getvsyear 24 | 25 | echo VSYEAR=%VSYEAR% 26 | 27 | echo Trying %QTDIR% 28 | if not exist %QTDIR%\bin ( 29 | if exist %QTDIR%\msvc%VSYEAR%_64\bin ( 30 | set QTDIR=%QTDIR%\msvc%VSYEAR%_64\bin 31 | ) else ( 32 | echo Error: cannot find Qt using %1 parameter, lookign for %QTDIR%\msvc%VSYEAR%_64\bin 33 | exit /b 1 34 | ) 35 | ) else ( 36 | set QTDIR=%QTDIR%\bin 37 | ) 38 | 39 | echo Using QTDIR=%QTDIR% 40 | 41 | echo %path%|find /i "%QTDIR:"=%">nul || set path=%QTDIR%;%path% 42 | 43 | set QTC_PATH=%QTDIR%\..\..\..\Tools\QtCreator\bin 44 | 45 | if exist %QTC_PATH% ( 46 | for %%i in ("%QTC_PATH%") do SET "QTC_PATH=%%~fi" 47 | ) 48 | setlocal enableDelayedExpansion 49 | if defined QTC_PATH ( 50 | echo Info: adding qtcreator to PATH 51 | echo !path!|find /i "%QTC_PATH:"=%">nul || set path=!QTC_PATH!;!path! 52 | ) 53 | endlocal&set "PATH=%PATH%" 54 | 55 | exit /b 0 56 | 57 | :getvsyear 58 | setlocal enableDelayedExpansion 59 | set VCINST=%VCINSTALLDIR:\= % 60 | set VCINST=%VCINST:(= % 61 | set VCINST=%VCINST:)= % 62 | set VCINST=%VCINST::= % 63 | 64 | for %%x in (!VCINST!) do ( 65 | echo %%x|findstr /r ^[0-9][0-9][0-9][0-9]$ >nul 66 | if not defined Y ( 67 | if !ERRORLEVEL! EQU 0 ( 68 | set Y=%%x 69 | ) 70 | ) 71 | ) 72 | endlocal & set "VSYEAR=%Y%" 73 | exit /b 0 74 | 75 | 76 | -------------------------------------------------------------------------------- /videotst/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | qputenv("QT_MULTIMEDIA_PREFERRED_PLUGINS",QByteArray("gst")); 7 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 8 | 9 | QGuiApplication app(argc, argv); 10 | 11 | QQmlApplicationEngine engine; 12 | const QUrl url(QStringLiteral("qrc:/main.qml")); 13 | QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, 14 | &app, [url](QObject *obj, const QUrl &objUrl) { 15 | if (!obj && url == objUrl) 16 | QCoreApplication::exit(-1); 17 | }, Qt::QueuedConnection); 18 | engine.load(url); 19 | 20 | return app.exec(); 21 | } 22 | -------------------------------------------------------------------------------- /videotst/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.13 2 | import QtMultimedia 5.13 3 | import QtQuick.Controls 2.13 4 | 5 | ApplicationWindow { 6 | visible: true 7 | width: 400 8 | height: 300 9 | Video { 10 | id: video 11 | 12 | anchors.fill: parent 13 | source: "rtsp://170.93.143.139/rtplive/470011e600ef003a004ee33696235daa" 14 | 15 | MouseArea { 16 | anchors.fill: parent 17 | onClicked: { 18 | video.play() 19 | } 20 | } 21 | autoPlay: true 22 | focus: true 23 | Keys.onSpacePressed: video.playbackState 24 | == MediaPlayer.PlayingState ? video.pause( 25 | ) : video.play() 26 | Keys.onLeftPressed: video.seek(video.position - 5000) 27 | Keys.onRightPressed: video.seek(video.position + 5000) 28 | onErrorStringChanged: { 29 | console.log("Error:" + errorString) 30 | } 31 | onErrorChanged: { 32 | console.log("ErrorCode:" + error.toString()) 33 | } 34 | onAvailabilityChanged: { 35 | console.log("availability:" + availability.toString()) 36 | } 37 | 38 | onBufferProgressChanged: { 39 | console.log("bufferProgress:" + bufferProgress) 40 | } 41 | onPositionChanged: { 42 | console.log("position:" + position) 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /videotst/qml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | main.qml 4 | 5 | 6 | -------------------------------------------------------------------------------- /videotst/videotst.pro: -------------------------------------------------------------------------------- 1 | QT += quick 2 | 3 | CONFIG += c++11 4 | 5 | # The following define makes your compiler emit warnings if you use 6 | # any Qt feature that has been marked deprecated (the exact warnings 7 | # depend on your compiler). Refer to the documentation for the 8 | # deprecated API to know how to port your code away from it. 9 | DEFINES += QT_DEPRECATED_WARNINGS 10 | 11 | # You can also make your code fail to compile if it uses deprecated APIs. 12 | # In order to do so, uncomment the following line. 13 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 14 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 15 | 16 | SOURCES += \ 17 | main.cpp 18 | 19 | RESOURCES += qml.qrc 20 | 21 | # Additional import path used to resolve QML modules in Qt Creator's code model 22 | QML_IMPORT_PATH = 23 | 24 | # Additional import path used to resolve QML modules just for Qt Quick Designer 25 | QML_DESIGNER_IMPORT_PATH = 26 | 27 | # Default rules for deployment. 28 | qnx: target.path = /tmp/$${TARGET}/bin 29 | else: unix:!android: target.path = /opt/$${TARGET}/bin 30 | !isEmpty(target.path): INSTALLS += target 31 | --------------------------------------------------------------------------------