first commit

This commit is contained in:
luocai 2024-01-18 22:22:26 +08:00
commit cca1d056c9
12 changed files with 834 additions and 0 deletions

17
.clang-format Normal file
View File

@ -0,0 +1,17 @@
BasedOnStyle: LLVM
ObjCBlockIndentWidth: 4
IndentWidth: 4
TabWidth: 4
AccessModifierOffset: -4
ColumnLimit: 120
#模板声明后换行
AlwaysBreakTemplateDeclarations: true
# 是否允许短if单行 If true, if (a) return; 可以放到同一行
AllowShortIfStatementsOnASingleLine: true
#短句 while (true) continue; 能被放到单行。
AllowShortLoopsOnASingleLine: true
AllowShortFunctionsOnASingleLine: false

10
AudioDecoder.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "AudioDecoder.h"
extern "C" {
#include "libavcodec/avcodec.h"
}
AudioDecoder::AudioDecoder(const AVCodec *codec) {
}
void AudioDecoder::push(const std::shared_ptr<AVPacket> &packet) {
}

14
AudioDecoder.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef __AUDIODECODER_H__
#define __AUDIODECODER_H__
#include <memory>
struct AVCodec;
struct AVPacket;
class AudioDecoder {
public:
AudioDecoder(const AVCodec *codec);
void push(const std::shared_ptr<AVPacket> &packet);
};
#endif // __AUDIODECODER_H__

64
CMakeLists.txt Normal file
View File

@ -0,0 +1,64 @@
cmake_minimum_required(VERSION 3.27)
project(FFmpegPlayer)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(Projects_ROOT E:/Projects)
set(Libraries_ROOT ${Projects_ROOT}/Libraries)
set(BOOST_ROOT ${Libraries_ROOT}/boost_1_84_0_msvc2022_64bit)
set(Boost_INCLUDE_DIR ${BOOST_ROOT}/include/boost-1_84)
option(Boost_USE_STATIC_LIBS OFF)
add_compile_definitions(
BOOST_USE_WINAPI_VERSION=BOOST_WINAPI_VERSION_WIN10
)
find_package(Boost REQUIRED COMPONENTS json)
set(OpenSSL_ROOT D:/Qt/Tools/OpenSSLv3/Win_x64)
set(OPENSSL_INCLUDE_DIR ${OpenSSL_ROOT}/include)
set(OpenSSL_LIBRARY_DIRS ${OpenSSL_ROOT}/lib)
set(OpenSSL_LIBRARIES libssl libcrypto)
set(FFMPEG_ROOT ${Libraries_ROOT}/ffmpeg-6.0-full_build-shared)
set(FFMPEG_INCLUDE_DIR ${FFMPEG_ROOT}/include)
set(FFMPEG_LIBRARY_DIRS ${FFMPEG_ROOT}/lib)
set(FFMPEG_LIBRARIES avcodec avformat avutil)
find_package(Qt6 REQUIRED COMPONENTS Widgets)
qt_standard_project_setup()
set(LibDataChannel_DIR E:/Projects/Libraries/libdatachannel-0.19.5_msvc2022_64bit_debug/lib/cmake/LibDataChannel)
find_package(LibDataChannel)
add_subdirectory(E:/Projects/Kylin/Universal Universal)
add_subdirectory(E:/Projects/Kylin/HttpProxy HttpProxy)
add_executable(FFmpegPlayer main.cpp
Demuxer.h Demuxer.cpp
AudioDecoder.h AudioDecoder.cpp
VideoDecoder.h VideoDecoder.cpp
WebRTCPublisher.h WebRTCPublisher.cpp
)
target_include_directories(FFmpegPlayer
PRIVATE ${FFMPEG_INCLUDE_DIR}
)
target_link_directories(FFmpegPlayer
PRIVATE ${FFMPEG_LIBRARY_DIRS}
PRIVATE ${OpenSSL_LIBRARY_DIRS}
)
target_link_libraries(FFmpegPlayer
PRIVATE Qt6::Widgets
PRIVATE Universal
PRIVATE HttpProxy
PRIVATE ${FFMPEG_LIBRARIES}
PRIVATE ${OpenSSL_LIBRARIES}
PRIVATE LibDataChannel::LibDataChannel
)

419
CMakeLists.txt.user Normal file
View File

@ -0,0 +1,419 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 12.0.1, 2024-01-18T22:20:08. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{11f4a1e9-12b5-4bf9-bf26-e33024189f36}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="qlonglong">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">0</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
<value type="bool" key="AutoTest.Framework.Boost">true</value>
<value type="bool" key="AutoTest.Framework.CTest">false</value>
<value type="bool" key="AutoTest.Framework.Catch">true</value>
<value type="bool" key="AutoTest.Framework.GTest">true</value>
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
</valuemap>
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
<value type="int" key="AutoTest.RunAfterBuild">0</value>
<value type="bool" key="AutoTest.UseGlobal">true</value>
<valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">3</value>
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
</valuemap>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.6.1 MSVC2019 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.6.1 MSVC2019 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.661.win64_msvc2019_64_kit</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="CMake.Build.Type">Debug</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_BUILD_TYPE:STRING=Debug
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">E:\Projects\FFmpegPlayer-Desktop_Qt_6_6_1_MSVC2019_64bit-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="CMake.Build.Type">Release</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">E:\Projects\FFmpegPlayer-Desktop_Qt_6_6_1_MSVC2019_64bit-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="QString" key="CMake.Build.Type">RelWithDebInfo</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">E:\Projects\FFmpegPlayer-Desktop_Qt_6_6_1_MSVC2019_64bit-RelWithDebInfo</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release with Debug Information</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.3">
<value type="QString" key="CMake.Build.Type">RelWithDebInfo</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">E:\Projects\FFmpegPlayer-Desktop_Qt_6_6_1_MSVC2019_64bit-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.4">
<value type="QString" key="CMake.Build.Type">MinSizeRel</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_BUILD_TYPE:STRING=MinSizeRel
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">E:\Projects\FFmpegPlayer-Desktop_Qt_6_6_1_MSVC2019_64bit-MinSizeRel</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Minimum Size Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">5</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">FFmpegPlayer</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeRunConfiguration.FFmpegPlayer</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">FFmpegPlayer</value>
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">E:/Projects/FFmpegPlayer-Desktop_Qt_6_6_1_MSVC2019_64bit-Debug</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="qlonglong">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

66
Demuxer.cpp Normal file
View File

@ -0,0 +1,66 @@
#include "Demuxer.h"
#include "BoostLog.h"
extern "C" {
#include "libavformat/avformat.h"
}
static_assert(AVMEDIA_TYPE_VIDEO == Stream::Video, "enum value must same...");
Demuxer::Demuxer() {
m_context = avformat_alloc_context();
}
Demuxer::~Demuxer() {
m_exit = true;
if (m_thread.joinable()) m_thread.join();
}
void Demuxer::open(const std::string &path) {
avformat_open_input(&m_context, path.c_str(), nullptr, nullptr);
av_dump_format(m_context, 0, path.c_str(), 0);
const AVCodec *videoCodec = nullptr, *audioCodec = nullptr;
m_streams[Stream::Video] = av_find_best_stream(m_context, AVMEDIA_TYPE_VIDEO, -1, -1, &videoCodec, 0);
m_streams[Stream::Audio] = av_find_best_stream(m_context, AVMEDIA_TYPE_AUDIO, -1, -1, &audioCodec, 0);
LOG(info) << "video stream index: " << m_streams[Stream::Video]
<< ", audio stream index: " << m_streams[Stream::Audio];
m_codecInformations[Stream::Video] = {videoCodec, m_context->streams[Stream::Video]->codecpar};
m_codecInformations[Stream::Audio] =
std::pair<const AVCodec *, const AVCodecParameters *>(audioCodec, m_context->streams[Stream::Audio]->codecpar);
}
Demuxer::CodecInformation Demuxer::codecInformation(Stream type) const {
return m_codecInformations[type];
}
void Demuxer::setStreamPacketCallback(Stream type, const Callback &callback) {
m_callback[type] = callback;
}
void Demuxer::start() {
m_exit = false;
m_thread = std::thread(&Demuxer::run, this);
}
void Demuxer::run() {
auto packet = av_packet_alloc();
while (!m_exit) {
int ret = av_read_frame(m_context, packet);
if (ret == AVERROR_EOF) {
LOG(info) << "end of file.";
break;
} else if (ret < 0) {
char buffer[AV_ERROR_MAX_STRING_SIZE] = {0};
av_strerror(ret, buffer, sizeof(buffer));
LOG(error) << "read failed: " << ret << ", " << buffer;
break;
}
std::shared_ptr<AVPacket> out(av_packet_alloc(), [](AVPacket *packet) { av_packet_free(&packet); });
av_packet_ref(out.get(), packet);
if (m_callback[packet->stream_index]) m_callback[packet->stream_index](out);
// LOG(info) << ". " << packet->stream_index;
av_packet_unref(packet);
}
av_packet_free(&packet);
}

42
Demuxer.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef __DEMUXER_H__
#define __DEMUXER_H__
#include <functional>
#include <string>
#include <thread>
struct AVFormatContext;
struct AVCodec;
struct AVCodecParameters;
struct AVPacket;
enum Stream : uint32_t {
Video,
Audio,
Size,
};
class Demuxer {
public:
using CodecInformation = std::pair<const AVCodec *, const AVCodecParameters *>;
using Callback = std::function<void(const std::shared_ptr<AVPacket> &)>;
Demuxer();
~Demuxer();
void open(const std::string &path);
CodecInformation codecInformation(Stream type) const;
void setStreamPacketCallback(Stream type, const Callback &callback);
void start();
protected:
void run();
private:
bool m_exit;
std::thread m_thread;
AVFormatContext *m_context;
int m_streams[Stream::Size];
CodecInformation m_codecInformations[Stream::Size];
Callback m_callback[Stream::Size];
};
#endif // __DEMUXER_H__

60
VideoDecoder.cpp Normal file
View File

@ -0,0 +1,60 @@
#include "VideoDecoder.h"
#include "BoostLog.h"
extern "C" {
#include "libavcodec/avcodec.h"
}
VideoDecoder::VideoDecoder(const AVCodec *codec, const AVCodecParameters *parameters) {
m_context = avcodec_alloc_context3(codec);
avcodec_parameters_to_context(m_context, parameters);
avcodec_open2(m_context, codec, nullptr);
}
void VideoDecoder::start() {
m_exit = false;
m_thread = std::thread(&VideoDecoder::run, this);
}
void VideoDecoder::push(const std::shared_ptr<AVPacket> &packet) {
std::lock_guard locker(m_mutex);
LOG(info) << "dts: " << packet->dts << ", pts: " << packet->pts;
m_packets.push(packet);
}
void VideoDecoder::run() {
using namespace std::chrono_literals;
auto frame = av_frame_alloc();
while (!m_exit) {
m_mutex.lock();
if (m_packets.empty()) {
m_mutex.unlock();
std::this_thread::sleep_for(5ms);
continue;
}
auto packet = m_packets.front();
m_packets.pop();
m_mutex.unlock();
auto ret = avcodec_send_packet(m_context, packet.get());
if (ret < 0) {
char buffer[AV_ERROR_MAX_STRING_SIZE] = {0};
av_strerror(ret, buffer, sizeof(buffer));
LOG(error) << "read failed: " << ret << ", " << buffer;
}
while (true) {
ret = avcodec_receive_frame(m_context, frame);
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) {
break;
} else if (ret < 0) {
char buffer[AV_ERROR_MAX_STRING_SIZE] = {0};
av_strerror(ret, buffer, sizeof(buffer));
LOG(error) << "read failed: " << ret << ", " << buffer;
break;
}
LOG(info) << "width: " << frame->width << ", height: " << frame->height << ", pts: " << frame->pts
<< ", pkt_dts:" << frame->pkt_dts;
av_frame_unref(frame);
}
}
av_frame_free(&frame);
}

29
VideoDecoder.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef __VIDEODECODER_H__
#define __VIDEODECODER_H__
#include <memory>
#include <mutex>
#include <queue>
struct AVPacket;
struct AVCodec;
struct AVCodecContext;
struct AVCodecParameters;
class VideoDecoder {
public:
VideoDecoder(const AVCodec *codec, const AVCodecParameters *parameters);
void start();
void push(const std::shared_ptr<AVPacket> &packet);
protected:
void run();
private:
bool m_exit;
std::thread m_thread;
AVCodecContext *m_context;
std::mutex m_mutex;
std::queue<std::shared_ptr<AVPacket>> m_packets;
};
#endif // __VIDEODECODER_H__

60
WebRTCPublisher.cpp Normal file
View File

@ -0,0 +1,60 @@
#include "WebRTCPublisher.h"
#include "BoostLog.h"
#include "NetworkUtility.h"
#include <boost/json/object.hpp>
#include <boost/json/serialize.hpp>
WebRTCPublisher::WebRTCPublisher(boost::asio::io_context &ioContext) : m_ioContext(ioContext) {
m_configuration.iceServers.emplace_back("mystunserver.org:3478");
m_peer = std::make_shared<rtc::PeerConnection>(m_configuration);
m_peer->onLocalDescription([&, this](rtc::Description sdp) {
LOG(info) << "Send the SDP to the remote peer: " << std::string(sdp);
const auto serverIp = "172.16.7.16";
const auto serverPort = "443";
const auto streamUrl = "/live/livestream";
std::ostringstream oss;
oss << "https://" << serverIp << ":" << serverPort << "/rtc/v1/publish/";
boost::json::object requestJson;
requestJson["api"] = oss.str();
requestJson["streamurl"] = streamUrl;
requestJson["sdp"] = std::string(sdp);
auto request = boost::json::serialize(requestJson);
LOG(info) << "body: " << request;
boost::system::error_code error;
Http::Client https(m_ioContext, Http::SSL);
https.loadRootCertificates(error);
auto reply = https.post(serverIp, serverPort, "/rtc/v1/publish/", request, error);
LOG(info) << "reply " << reply;
// Send the SDP to the remote peer
// MY_SEND_DESCRIPTION_TO_REMOTE(std::string(sdp));
});
m_peer->onLocalCandidate([](rtc::Candidate candidate) {
// Send the candidate to the remote peer
// MY_SEND_CANDIDATE_TO_REMOTE(candidate.candidate(), candidate.mid());
});
// MY_ON_RECV_DESCRIPTION_FROM_REMOTE([&pc](std::string sdp) { pc.setRemoteDescription(rtc::Description(sdp)); });
// MY_ON_RECV_CANDIDATE_FROM_REMOTE(
// [&pc](std::string candidate, std::string mid) { pc.addRemoteCandidate(rtc::Candidate(candidate, mid)); });
m_peer->onStateChange([](rtc::PeerConnection::State state) { LOG(info) << "State: " << (int)state; });
m_peer->onGatheringStateChange(
[](rtc::PeerConnection::GatheringState state) { LOG(info) << "Gathering state: " << (int)state; });
m_dataChannel = m_peer->createDataChannel("test");
m_dataChannel->onOpen([]() { LOG(info) << "Open" << std::endl; });
m_dataChannel->onMessage([](std::variant<rtc::binary, rtc::string> message) {
if (std::holds_alternative<rtc::string>(message)) {
LOG(info) << "Received: " << get<rtc::string>(message) << std::endl;
}
});
}

18
WebRTCPublisher.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef WEBRTCPUBLISHER_H
#define WEBRTCPUBLISHER_H
#include "rtc/rtc.hpp"
#include <boost/asio/io_context.hpp>
class WebRTCPublisher {
public:
WebRTCPublisher(boost::asio::io_context &ioContext);
private:
boost::asio::io_context &m_ioContext;
rtc::Configuration m_configuration;
std::shared_ptr<rtc::PeerConnection> m_peer;
std::shared_ptr<rtc::DataChannel> m_dataChannel;
};
#endif // WEBRTCPUBLISHER_H

35
main.cpp Normal file
View File

@ -0,0 +1,35 @@
#include "AudioDecoder.h"
#include "Demuxer.h"
#include "IoContext.h"
#include "VideoDecoder.h"
#include "WebRTCPublisher.h"
#include <QApplication>
#include <QWidget>
#include <iostream>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
auto ioContext = Amass::Singleton<IoContext>::instance<Amass::Construct>();
std::cout << "hello world." << std::endl;
constexpr auto path = "E:/Documents/juren-30s.mp4";
Demuxer demuxer;
demuxer.open(path);
// auto [audioCodec, audioCodecParameter] = demuxer.codecInformation(Stream::Audio);
// auto [videoCodec, videoCodecParameter] = demuxer.codecInformation(Stream::Video);
// VideoDecoder videoDecoder(videoCodec, videoCodecParameter);
// // AudioDecoder audioDecoder(audioCodec, audioCodecParameter);
// demuxer.setStreamPacketCallback(
// Stream::Video, [&videoDecoder](const std::shared_ptr<AVPacket> &packet) { videoDecoder.push(packet); });
// // demuxer.setStreamPacketCallback(Stream::Audio,
// // std::bind(&AudioDecoder::push, &audioDecoder, std::placeholders::_1));
// demuxer.start();
// videoDecoder.start();
QWidget w;
// w.show();
WebRTCPublisher rtc(*ioContext->ioContext());
ioContext->run<IoContext::Mode::Asynchronous>();
return app.exec();
}