### Install Qt6 Development Libraries Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Installs necessary Qt6 development libraries and tools. This is an alternative to installing Qt5. ```bash sudo apt-get install -y qt6-base-dev qt6-tools-dev qt6-tools-dev-tools ``` -------------------------------- ### Troubleshoot: Install Qt6 Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Provides commands to install Qt6 development packages if a 'Qt not found' error occurs and Qt6 is preferred. ```bash # Or install Qt6 sudo apt-get install qt6-base-dev qt6-tools-dev ``` -------------------------------- ### Install Build Tools Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Installs essential build tools including CMake for project configuration and GCC (build-essential) for compilation. ```bash sudo apt-get install -y cmake build-essential ``` -------------------------------- ### Troubleshoot: Install CMake Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Provides the command to install CMake if a 'CMake not found' error occurs. ```bash sudo apt-get install cmake ``` -------------------------------- ### Verify Build Tool Installations Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Commands to verify that qmake, cmake, and pkg-config (for ALSA) are installed and to check their versions. ```bash qmake --version cmake --version pkg-config --modversion alsa ``` -------------------------------- ### Troubleshoot: Install Qt5 Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Provides commands to install Qt5 development packages if a 'Qt not found' error occurs during the build process. ```bash # Install Qt5 sudo apt-get install qt5-default qtbase5-dev qtbase5-dev-tools ``` -------------------------------- ### Install Qt5 Development Libraries Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Installs necessary Qt5 development libraries and tools for building Qt applications on Debian-based systems. ```bash sudo apt-get update sudo apt-get install -y qt5-default qtbase5-dev qtbase5-dev-tools ``` -------------------------------- ### Troubleshoot: Install ALSA Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Provides the command to install ALSA development libraries if a 'ALSA not found' error is encountered. ```bash sudo apt-get install libasound2-dev ``` -------------------------------- ### Run Qt Demo Application Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Command to navigate to the project directory and execute the Qt demo application. Assumes the application has been successfully built. ```bash cd videosdk-linux-qt-quickstart ./run_qt_demo.sh ``` -------------------------------- ### Build and Run Application (Bash) Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt Provides bash commands to build the Linux Qt Quickstart application using CMake and make. It includes steps for installing dependencies, configuring the build, and running the application with different platform configurations (headless, Wayland). ```bash # Install dependencies (Ubuntu) sudo apt-get update sudo apt-get install -y qt6-base-dev qt6-tools-dev libasound2-dev cmake build-essential # Build the application cd videosdk-linux-qt-quickstart mkdir -p build && cd build export Qt6_DIR=/usr/lib/x86_64-linux-gnu/cmake/Qt6 cmake .. make -j$(nproc) # Configure session (edit src/bin/config.json) # Run the application ./run_qt_demo.sh # For headless/server environments QT_QPA_PLATFORM=offscreen ./run_qt_demo.sh # For Wayland environments QT_QPA_PLATFORM=wayland ./run_qt_demo.sh ``` -------------------------------- ### Install ALSA Development Libraries Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Installs the ALSA (Advanced Linux Sound Architecture) development libraries required for audio playback in the application. ```bash sudo apt-get install -y libasound2-dev ``` -------------------------------- ### List Build Artifacts Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Lists all files in the output directory ('src/bin/'), including the executable, configuration files, and shared libraries. ```bash ls -la src/bin/ ``` -------------------------------- ### Install Qt Development Packages (Bash) Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md This command installs the necessary Qt 6 base development packages on Ubuntu-based systems. This is a common troubleshooting step if the Qt build system cannot find Qt installations, which is required for compiling Qt applications. ```bash sudo apt-get install qt6-base-dev ``` -------------------------------- ### Build Application with Make Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Compiles the application using the 'make' utility, utilizing all available processor cores (-j$(nproc)) for faster build times. ```bash make -j$(nproc) ``` -------------------------------- ### Configure Project with CMake (Qt6) Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Configures the build system using CMake, specifying the Qt6 installation directory. This step prepares the project for compilation. ```bash export Qt6_DIR=/usr/lib/x86_64-linux-gnu/cmake/Qt6 cmake .. ``` -------------------------------- ### Install Qt Multimedia Development Packages (Bash) Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md This command installs the Qt 6 Multimedia module development packages on Ubuntu-based systems. This module provides APIs for handling audio, video, and radio, and is essential for applications that involve media playback or capture. ```bash sudo apt-get install qt6-multimedia-dev ``` -------------------------------- ### Test Executable (Help Option) Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Attempts to run the application with a '--help' argument to check for basic functionality and ensure it doesn't crash. Redirects stderr to avoid clutter if --help is not supported. ```bash src/bin/VideoSDKQtDemo --help 2>/dev/null || echo "Qt application (may not have --help)" ``` -------------------------------- ### Grant Executable Permissions and Run with User Permissions Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Demonstrates how to grant executable permissions to the application binary and run the application using `sudo` with the current user's privileges to resolve permission-related errors. ```bash # Grant executable permissions chmod +x src/bin/VideoSDKQtDemo # Run with proper user permissions sudo -u $USER ./run_qt_demo.sh ``` -------------------------------- ### Check Dynamic Library Dependencies Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Uses 'ldd' to list the dynamic libraries that the 'VideoSDKQtDemo' executable depends on, ensuring all are found. ```bash ldd src/bin/VideoSDKQtDemo ``` -------------------------------- ### Troubleshoot Qt Platform Plugin Issues Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Provides commands to inspect available Qt platform plugins and force the use of a specific plugin like XCB or Wayland to resolve platform-related issues. ```bash # Check available platform plugins ls /usr/lib/x86_64-linux-gnu/qt6/plugins/platforms/ # Force specific platform QT_QPA_PLATFORM=xcb ./run_qt_demo.sh QT_QPA_PLATFORM=wayland ./run_qt_demo.sh ``` -------------------------------- ### Check Executable Permissions Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Verifies that the 'VideoSDKQtDemo' executable has the correct read, write, and execute permissions. ```bash ls -la src/bin/VideoSDKQtDemo ``` -------------------------------- ### Troubleshoot: Fix Permission Issues Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Command to recursively grant write permissions to the current user for the project directory, addressing potential permission errors. ```bash # Make sure you have write permissions chmod -R u+w ../ ``` -------------------------------- ### Verify Executable File Type Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Uses the 'file' command to inspect the 'VideoSDKQtDemo' executable, confirming it is a 64-bit Linux executable. ```bash file src/bin/VideoSDKQtDemo ``` -------------------------------- ### Build Application with Verbose Make Output Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Compiles the application using 'make' with verbose output enabled (VERBOSE=1), showing detailed compilation commands. Useful for diagnosing build errors. ```bash make VERBOSE=1 ``` -------------------------------- ### Resolve 'Could not connect to display' with Qt Platform Plugins Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Addresses 'could not connect to display' or 'Qt platform plugin 'xcb'' errors by configuring the DISPLAY variable or selecting alternative Qt platform plugins like Wayland, EGLFS, or offscreen rendering. It also lists necessary X11 dependencies for installation. ```bash # Solution 1: Set DISPLAY variable (if X server is running) export DISPLAY=:0 ./run_qt_demo.sh # Solution 2: Use Wayland (if available) export QT_QPA_PLATFORM=wayland ./run_qt_demo.sh # Solution 3: Use EGLFS (for embedded systems) export QT_QPA_PLATFORM=eglfs ./run_qt_demo.sh # Solution 4: Use offscreen rendering (for testing) export QT_QPA_PLATFORM=offscreen ./run_qt_demo.sh # Solution 5: Install X11 dependencies sudo apt-get install -y libxcb-xinerama0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 ``` -------------------------------- ### Run Qt Demo Application (Bash) Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md This command executes the main Qt demo application using the `run_qt_demo.sh` script. This is the standard way to launch the application on a desktop environment. Ensure the script has execute permissions. ```bash ./run_qt_demo.sh ``` -------------------------------- ### CMake Project Setup and Build Configuration Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/src/CMakeLists.txt Initializes the CMake project, sets the C++ standard to 17, enables required features, and configures build output directories. It also sets up the build type to Debug and enables exporting compile commands. ```cmake cmake_minimum_required(VERSION 3.14) # Use system compilers (GCC 13) project(VideoSDKQtDemo CXX) set(TARGET_NAME VideoSDKQtDemo) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_BUILD_TYPE Debug) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Use system Qt5 completely for building, handle library conflicts at runtime find_package(Qt5 REQUIRED COMPONENTS Core Widgets) # Store SDK Qt library path for runtime set(QT_SDK_LIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib/zoom_video_sdk/qt_libs/Qt/lib) # Set Qt-specific configurations set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) ``` -------------------------------- ### Configure Project with Verbose CMake Output Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md Configures the build system with CMake, enabling verbose output for the Makefile generation. This is useful for debugging configuration issues. ```bash cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON ``` -------------------------------- ### Manage Audio/Video Devices with Zoom SDK Helpers (C++) Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt Provides functions to enumerate available cameras, microphones, and speakers using the Zoom Video SDK's helper classes. It also includes examples for selecting a specific camera and microphone by their IDs. ```cpp void populateDeviceDropdowns() { if (!video_sdk_obj) return; // Get camera list IZoomVideoSDKVideoHelper* videoHelper = video_sdk_obj->getVideoHelper(); if (videoHelper) { IVideoSDKVector* cameraList = videoHelper->getCameraList(); if (cameraList) { for (int i = 0; i < cameraList->GetCount(); i++) { IZoomVideoSDKCameraDevice* camera = cameraList->GetItem(i); printf("Camera: %s (ID: %s)\n", camera->getDeviceName(), camera->getDeviceId()); } } } // Get microphone and speaker lists IZoomVideoSDKAudioHelper* audioHelper = video_sdk_obj->getAudioHelper(); if (audioHelper) { IVideoSDKVector* micList = audioHelper->getMicList(); IVideoSDKVector* speakerList = audioHelper->getSpeakerList(); // Enumerate devices... } } // Select a specific camera void selectCamera(const QString& cameraId) { if (!video_sdk_obj || !g_in_session) return; IZoomVideoSDKVideoHelper* videoHelper = video_sdk_obj->getVideoHelper(); if (videoHelper) { bool result = videoHelper->selectCamera(cameraId.toStdString().c_str()); printf("Camera selection: %s\n", result ? "success" : "failed"); } } // Select microphone void selectMicrophone(const QString& micId, const QString& micName) { IZoomVideoSDKAudioHelper* audioHelper = video_sdk_obj->getAudioHelper(); if (audioHelper) { ZoomVideoSDKErrors err = audioHelper->selectMic( micId.toStdString().c_str(), micName.toStdString().c_str()); } } ``` -------------------------------- ### Troubleshoot: Clean Rebuild Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md A sequence of commands to clean the build directory, reconfigure with CMake, and rebuild the application. This is a common step for resolving build issues. ```bash cd videosdk-linux-qt-quickstart rm -rf build mkdir build cd build cmake .. make clean make -j$(nproc) ``` -------------------------------- ### Run Qt Demo in Wayland Environment (Bash) Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md This command runs the Qt demo application in a Wayland environment. By setting the `QT_QPA_PLATFORM=wayland` environment variable, the application will utilize the Wayland display server protocol. This is an alternative to the default X11 platform. ```bash export QT_QPA_PLATFORM=wayland ./run_qt_demo.sh ``` -------------------------------- ### Run Qt Demo with SSH X11 Forwarding (Bash) Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md This demonstrates how to run the Qt demo application over an SSH connection with X11 forwarding enabled. The `-X` flag in the `ssh` command enables X11 forwarding, allowing the GUI application to display on the local machine. The `export DISPLAY` command may be necessary to direct the output. ```bash ssh -X user@hostname export DISPLAY=:10.0 # Adjust display number as needed ./run_qt_demo.sh ``` -------------------------------- ### Configure Session with JSON C++ Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt Loads session configuration details such as session name, password, and JWT token from a JSON file. Requires the nlohmann/json library and fstream. Parses the JSON to extract session parameters. ```json { "session_name": "my-session-name", "session_psw": "optional-password", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } ``` ```cpp #include "json.hpp" #include using Json = nlohmann::json; // Load configuration from file std::string session_name, session_psw, session_token; std::ifstream config_file("config.json"); if (config_file.is_open()) { Json config_json; config_file >> config_json; if (config_json.contains("session_name")) session_name = config_json["session_name"]; if (config_json.contains("session_psw")) session_psw = config_json["session_psw"]; if (config_json.contains("token")) session_token = config_json["token"]; } ``` -------------------------------- ### Toggle Video Transmission and Preview (C++) Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt This C++ function manages the user's video transmission and preview within a Zoom SDK session. It uses the IZoomVideoSDKVideoHelper interface to start or stop video. If starting video, it also sets up a preview handler using QtPreviewVideoHandler. It requires the SDK object, session information, and a QWidget for the preview. ```cpp void toggleSelfVideo() { if (!video_sdk_obj || !g_in_session) return; IZoomVideoSDKVideoHelper* videoHelper = video_sdk_obj->getVideoHelper(); if (!videoHelper) return; if (m_selfVideoEnabled) { // Stop video transmission ZoomVideoSDKErrors err = videoHelper->stopVideo(); if (err == ZoomVideoSDKErrors_Success) { // Stop and clean up preview handler if (m_previewHandler) { m_previewHandler->StopPreview(); delete m_previewHandler; m_previewHandler = nullptr; } m_selfVideoEnabled = false; printf("Video stopped\n"); } } else { // Start video transmission ZoomVideoSDKErrors err = videoHelper->startVideo(); if (err == ZoomVideoSDKErrors_Success) { // Create preview handler for self video display m_previewHandler = new QtPreviewVideoHandler(m_selfVideoWidget); if (m_previewHandler->StartPreview()) { printf("Video started with preview\n"); } m_selfVideoEnabled = true; } } } ``` -------------------------------- ### Run Qt Demo in Headless Environment (Bash) Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md This command runs the Qt demo application in a headless or server environment using offscreen rendering. The `QT_QPA_PLATFORM=offscreen` environment variable prevents a GUI window from appearing, making it suitable for server-side operations or testing without a display. The `&` at the end runs the process in the background. ```bash QT_QPA_PLATFORM=offscreen ./run_qt_demo.sh & ``` -------------------------------- ### Configure Session Details (JSON) Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md This snippet shows the structure of the `config.json` file used to configure session details for the application. It requires session name, password (optional), and a JWT token for authentication. This file is typically located in `src/bin/` or `src/`. ```json { "session_name": "your-session-name", "session_psw": "your-session-password", "token": "your-jwt-token" } ``` -------------------------------- ### Initialize Zoom Video SDK C++ Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt Initializes the Zoom Video SDK with necessary configuration parameters. Requires the Zoom Video SDK headers and defines. Sets up memory modes and logging. Returns a success or error code. ```cpp #include "zoom_video_sdk_api.h" #include "zoom_video_sdk_def.h" #include "zoom_video_sdk_interface.h" USING_ZOOM_VIDEO_SDK_NAMESPACE IZoomVideoSDK* video_sdk_obj = nullptr; // Create SDK instance video_sdk_obj = CreateZoomVideoSDKObj(); if (video_sdk_obj) { // Configure initialization parameters ZoomVideoSDKInitParams init_params; init_params.domain = "https://zoom.us"; init_params.enableLog = false; init_params.logFilePrefix = ""; init_params.videoRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap; init_params.shareRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap; init_params.audioRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap; init_params.enableIndirectRawdata = false; // Initialize SDK ZoomVideoSDKErrors err = video_sdk_obj->initialize(init_params); if (err == ZoomVideoSDKErrors_Success) { printf("SDK initialized successfully\n"); } else { printf("Failed to initialize SDK: %d\n", (int)err); } } ``` -------------------------------- ### Creating Executables and Linking Libraries Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/src/CMakeLists.txt Defines two executables: `VideoSDKQtDemo` for the main GUI application and `simple_join` for a minimal utility. It links the required SDK, system, and Qt libraries to each target and sets runtime search paths (RPATH). ```cmake # Qt GUI sources set(GUI_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/QtVideoRenderer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/QtMainWindow.cpp ${CMAKE_CURRENT_SOURCE_DIR}/QtVideoWidget.cpp ${CMAKE_CURRENT_SOURCE_DIR}/QtPreviewVideoHandler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/QtRemoteVideoHandler.cpp ) add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/zoom_v-sdk_linux_bot_qt.cpp ${GUI_SOURCES} ) # Simple test executable without Qt GUI add_executable(simple_join ${CMAKE_CURRENT_SOURCE_DIR}/simple_join.cpp ) # Link libraries for simple_join (matching GTK order) target_link_libraries(simple_join PkgConfig::deps) target_link_libraries(simple_join videosdk) target_link_libraries(simple_join curl) target_link_libraries(simple_join ${GLIB_LIBRARIES} ${GIO_LIBRARIES}) target_link_libraries(simple_join ${ALSA_LIBRARIES}) # Set RPATH for simple_join too set_target_properties(simple_join PROPERTIES INSTALL_RPATH "${CMAKE_CURRENT_SOURCE_DIR}/lib/zoom_video_sdk/qt_libs/Qt/lib:${CMAKE_CURRENT_SOURCE_DIR}/lib/zoom_video_sdk" BUILD_WITH_INSTALL_RPATH TRUE ) # Link libraries (matching GTK order) target_link_libraries(${TARGET_NAME} PkgConfig::deps) target_link_libraries(${TARGET_NAME} videosdk) target_link_libraries(${TARGET_NAME} curl) target_link_libraries(${TARGET_NAME} ${GLIB_LIBRARIES} ${GIO_LIBRARIES}) target_link_libraries(${TARGET_NAME} ${ALSA_LIBRARIES}) # Link Qt5 libraries target_link_libraries(${TARGET_NAME} Qt5::Core Qt5::Widgets) # Try to suppress undefined symbol errors target_link_libraries(${TARGET_NAME} "-Wl,--allow-shlib-undefined") # Set RPATH so the executable finds the SDK libraries automatically set_target_properties(${TARGET_NAME} PROPERTIES INSTALL_RPATH "${CMAKE_CURRENT_SOURCE_DIR}/lib/zoom_video_sdk/qt_libs/Qt/lib:${CMAKE_CURRENT_SOURCE_DIR}/lib/zoom_video_sdk" BUILD_WITH_INSTALL_RPATH TRUE ) ``` -------------------------------- ### Check Process Status (Bash) Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/README.md This command checks if the `VideoSDKQtDemo` process is running after launching it with offscreen rendering. It uses `ps aux` to list all running processes and `grep` to filter for the specific executable name. This is useful for verifying background process startup. ```bash ps aux | grep VideoSDKQtDemo ``` -------------------------------- ### ALSA Audio Playback Initialization and Playback (C++) Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt Initializes ALSA for audio playback and provides a function to play received audio data. It handles ALSA device opening, hardware parameter configuration, and audio data writing. Includes cleanup for the ALSA PCM device. ```cpp #include class AudioPlayback { private: snd_pcm_t* pcm_handle; bool initialized; public: AudioPlayback() : pcm_handle(nullptr), initialized(false) {} bool init() { int err = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (err < 0) return false; snd_pcm_hw_params_t* hw_params; snd_pcm_hw_params_alloca(&hw_params); snd_pcm_hw_params_any(pcm_handle, hw_params); snd_pcm_hw_params_set_access(pcm_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(pcm_handle, hw_params, SND_PCM_FORMAT_S16_LE); unsigned int rate = 44100; snd_pcm_hw_params_set_rate_near(pcm_handle, hw_params, &rate, 0); snd_pcm_hw_params_set_channels(pcm_handle, hw_params, 2); snd_pcm_hw_params(pcm_handle, hw_params); snd_pcm_prepare(pcm_handle); initialized = true; return true; } void playAudio(const char* buffer, int buffer_len) { if (!initialized || !pcm_handle || !buffer) return; int frames = buffer_len / 4; // 16-bit stereo snd_pcm_sframes_t written = snd_pcm_writei(pcm_handle, buffer, frames); if (written == -EPIPE) { snd_pcm_prepare(pcm_handle); // Handle underrun } } void cleanup() { if (pcm_handle) { snd_pcm_close(pcm_handle); pcm_handle = nullptr; } initialized = false; } }; // Usage in delegate callback virtual void onMixedAudioRawDataReceived(AudioRawData* data_) override { if (data_ && g_audio_playback) { char* buffer = data_->GetBuffer(); if (buffer) { g_audio_audio_playback->playAudio(buffer, data_->GetBufferLen()); } } } ``` -------------------------------- ### Finding and Linking System Dependencies Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/src/CMakeLists.txt Locates necessary system libraries such as GLib, GIO, ALSA, and PkgConfig using `find_package` and `pkg_check_modules`. It then includes directories and links these libraries to the targets. ```cmake # Find required packages find_package(PkgConfig REQUIRED) pkg_check_modules(deps REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GIO REQUIRED gio-2.0) # Find ALSA library for audio playback find_package(ALSA REQUIRED) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/zoom_video_sdk) link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib/zoom_video_sdk) link_directories(${GLIB_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS}) include_directories(${GLIB_INCLUDE_DIRS} ${GIO_INCLUDE_DIRS}) add_definitions(${GLIB_CFLAGS_OTHER} ${GIO_CFLAGS_OTHER}) ``` -------------------------------- ### Implement Video Preview with Raw Data Pipe Delegate (C++) Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt This C++ code implements video preview functionality by utilizing the raw data pipe delegate for self video display. It requires the IZoomVideoSDKRawDataPipeDelegate interface and a QtVideoWidget for rendering. The handler starts and stops video preview, receiving raw YUV frames and rendering them. ```cpp #include "helpers/zoom_video_sdk_user_helper_interface.h" class QtPreviewVideoHandler : public QObject, private IZoomVideoSDKRawDataPipeDelegate { public: QtPreviewVideoHandler(QtVideoWidget* widget) : m_videoWidget(widget), m_isRunning(false) {} bool StartPreview() { if (!video_sdk_obj || !m_videoWidget) return false; IZoomVideoSDKVideoHelper* videoHelper = video_sdk_obj->getVideoHelper(); if (!videoHelper) return false; ZoomVideoSDKErrors err = videoHelper->startVideoPreview(this); if (err == ZoomVideoSDKErrors_Success) { m_isRunning = true; return true; } return false; } bool StopPreview() { if (!video_sdk_obj || !m_isRunning) return true; IZoomVideoSDKVideoHelper* videoHelper = video_sdk_obj->getVideoHelper(); if (videoHelper) { videoHelper->stopVideoPreview(this); } m_isRunning = false; return true; } private: // Called when raw video frame is received virtual void onRawDataFrameReceived(YUVRawDataI420* data) override { if (!data || !m_videoWidget) return; const int width = data->GetStreamWidth(); const int height = data->GetStreamHeight(); const char* y_data = reinterpret_cast(data->GetYBuffer()); const char* u_data = reinterpret_cast(data->GetUBuffer()); const char* v_data = reinterpret_cast(data->GetVBuffer()); // Render frame using QtVideoRenderer QtVideoRenderer renderer(m_videoWidget); renderer.renderVideoFrame(y_data, u_data, v_data, width, height, width, width/2, width/2); } virtual void onRawDataStatusChanged(RawDataStatus status) override { m_isRunning = (status == RawData_On); } QtVideoWidget* m_videoWidget; bool m_isRunning; }; ``` -------------------------------- ### File Management and Utility Operations Source: https://github.com/tanchunsiong/videosdk-linux-qt-quickstart/blob/main/src/CMakeLists.txt Handles copying configuration files, SDK libraries, and downloading external dependencies like `nlohmann/json.hpp`. It also ensures necessary directories and symbolic links are created for the SDK. ```cmake # Copy config file configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.json ${CMAKE_CURRENT_SOURCE_DIR}/bin/config.json COPYONLY) # Copy Zoom SDK libraries file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/lib/zoom_video_sdk/ DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) # Download nlohmann/json if not exists if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/include/json.hpp") execute_process(COMMAND wget -O ${CMAKE_CURRENT_SOURCE_DIR}/include/json.hpp https://raw.githubusercontent.com/nlohmann/json/refs/heads/develop/single_include/nlohmann/json.hpp) endif() # Create logs directory execute_process(COMMAND mkdir -p .zoom/logs WORKING_DIRECTORY $ENV{HOME}) # Create symbolic link for videosdk library if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lib/zoom_video_sdk/libvideosdk.so.1") execute_process(COMMAND ln -s libvideosdk.so libvideosdk.so.1 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib/zoom_video_sdk) endif() ``` -------------------------------- ### Join Zoom Video SDK Session C++ Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt Joins a Zoom Video SDK session using provided session details and configures audio/video options. Requires the video_sdk_obj to be initialized and session parameters to be available. Session joining status is handled via delegate callbacks. ```cpp void joinVideoSDKSession(const QString& session_name, const QString& session_psw, const QString& session_token) { if (!video_sdk_obj || session_name.isEmpty() || session_token.isEmpty()) { return; } // Store strings to prevent temporary destruction std::string session_name_str = session_name.toStdString(); std::string session_psw_str = session_psw.toStdString(); std::string session_token_str = session_token.toStdString(); // Prepare session context ZoomVideoSDKSessionContext session_context; session_context.sessionName = session_name_str.c_str(); session_context.userName = "Linux Qt Bot"; session_context.token = session_token_str.c_str(); if (!session_psw.isEmpty()) { session_context.sessionPassword = session_psw_str.c_str(); } // Configure video and audio options session_context.videoOption.localVideoOn = false; session_context.audioOption.connect = true; session_context.audioOption.mute = false; // Join session - success/failure comes through delegate callbacks IZoomVideoSDKSession* session = video_sdk_obj->joinSession(session_context); printf("Join session request sent\n"); } ``` -------------------------------- ### Subscribe to Remote User Video Streams with Raw Data Pipe (C++) Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt This C++ code demonstrates how to subscribe to remote user video streams using the raw data pipe. It requires the IZoomVideoSDKRawDataPipeDelegate interface and a QtVideoWidget. The handler subscribes and unsubscribes users, receiving and rendering their video frames. ```cpp class QtRemoteVideoHandler : public QObject, private IZoomVideoSDKRawDataPipeDelegate { public: QtRemoteVideoHandler(QtVideoWidget* widget) : m_videoWidget(widget), m_currentUser(nullptr), m_videoPipe(nullptr), m_isSubscribed(false) {} bool SubscribeToUser(IZoomVideoSDKUser* user, ZoomVideoSDKResolution resolution = ZoomVideoSDKResolution_90P) { if (!user || !m_videoWidget) return false; IZoomVideoSDKRawDataPipe* videoPipe = user->GetVideoPipe(); if (!videoPipe) return false; ZoomVideoSDKErrors err = videoPipe->subscribe(resolution, this); if (err == ZoomVideoSDKErrors_Success) { m_currentUser = user; m_videoPipe = videoPipe; m_isSubscribed = true; printf("Subscribed to user: %s\n", user->getUserName()); return true; } return false; } bool Unsubscribe() { if (m_videoPipe && m_isSubscribed) { m_videoPipe->unSubscribe(this); } m_isSubscribed = false; m_currentUser = nullptr; m_videoPipe = nullptr; return true; } private: virtual void onRawDataFrameReceived(YUVRawDataI420* data) override { if (!data || !m_videoWidget) return; QtVideoRenderer renderer(m_videoWidget); renderer.renderVideoFrame( data->GetYBuffer(), data->GetUBuffer(), data->GetVBuffer(), data->GetStreamWidth(), data->GetStreamHeight(), data->GetStreamWidth(), data->GetStreamWidth()/2, data->GetStreamWidth()/2); } QtVideoWidget* m_videoWidget; IZoomVideoSDKUser* m_currentUser; IZoomVideoSDKRawDataPipe* m_videoPipe; bool m_isSubscribed; }; ``` -------------------------------- ### Send Chat Messages to All Participants (C++) Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt Sends a chat message to all participants in a Zoom SDK session. It checks if chat is enabled and retrieves the chat helper interface to send the message. Error handling for disabled chat is included. ```cpp #include "helpers/zoom_video_sdk_chat_helper_interface.h" void sendChatMessage(const char* message) { if (!video_sdk_obj || !g_in_session) return; IZoomVideoSDKChatHelper* chatHelper = video_sdk_obj->getChatHelper(); if (chatHelper) { if (!chatHelper->isChatDisabled() && !chatHelper->isPrivateChatDisabled()) { ZoomVideoSDKErrors err = chatHelper->sendChatToAll(message); printf("Chat message sent, status: %d\n", (int)err); } else { printf("Chat is disabled\n"); } } } ``` -------------------------------- ### Convert YUV to RGB Video Frames for Qt Display (C++) Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt Converts YUV420 video frames to RGB32 format suitable for Qt's QImage. It uses the ITU-R BT.601 color conversion standard. This class requires a QtVideoWidget to display the converted frames. ```cpp class QtVideoRenderer { public: QtVideoRenderer(QtVideoWidget* widget) : m_videoWidget(widget) {} void renderVideoFrame(const char* y_data, const char* u_data, const char* v_data, int width, int height, int y_stride, int u_stride, int v_stride) { if (!m_videoWidget || !y_data || !u_data || !v_data) return; QImage rgbFrame = convertYUVtoRGB(y_data, u_data, v_data, width, height, y_stride, u_stride, v_stride); m_videoWidget->updateVideoFrame(rgbFrame); } private: QImage convertYUVtoRGB(const char* y_data, const char* u_data, const char* v_data, int width, int height, int y_stride, int u_stride, int v_stride) { QImage rgbImage(width, height, QImage::Format_RGB32); const uint8_t* y_plane = reinterpret_cast(y_data); const uint8_t* u_plane = reinterpret_cast(u_data); const uint8_t* v_plane = reinterpret_cast(v_data); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int y_val = y_plane[y * y_stride + x]; int u_val = u_plane[(y / 2) * u_stride + (x / 2)]; int v_val = v_plane[(y / 2) * v_stride + (x / 2)]; // BT.601 conversion int c = y_val - 16; int d = u_val - 128; int e = v_val - 128; int r = qBound(0, (298 * c + 409 * e + 128) >> 8, 255); int g = qBound(0, (298 * c - 100 * d - 208 * e + 128) >> 8, 255); int b = qBound(0, (298 * c + 516 * d + 128) >> 8, 255); rgbImage.setPixel(x, y, qRgb(r, g, b)); } } return rgbImage; } QtVideoWidget* m_videoWidget; }; ``` -------------------------------- ### Toggle Audio Mute/Unmute (C++) Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt This C++ function controls the audio mute/unmute state for the current user in a Zoom SDK session. It utilizes the IZoomVideoSDKAudioHelper interface and checks the global 'g_audio_muted' flag to determine the current state. It requires the SDK object and session information to be available. ```cpp void toggleAudioMute() { if (!video_sdk_obj || !g_in_session) return; IZoomVideoSDKAudioHelper* audioHelper = video_sdk_obj->getAudioHelper(); if (!audioHelper) return; IZoomVideoSDKSession* session = video_sdk_obj->getSessionInfo(); IZoomVideoSDKUser* currentUser = session ? session->getMyself() : nullptr; if (!currentUser) return; if (g_audio_muted) { ZoomVideoSDKErrors err = audioHelper->unMuteAudio(currentUser); if (err == ZoomVideoSDKErrors_Success) { g_audio_muted = false; printf("Audio unmuted\n"); } } else { ZoomVideoSDKErrors err = audioHelper->muteAudio(currentUser); if (err == ZoomVideoSDKErrors_Success) { g_audio_muted = true; printf("Audio muted\n"); } } } ``` -------------------------------- ### Implement IZoomVideoSDKDelegate for Session Events (C++) Source: https://context7.com/tanchunsiong/videosdk-linux-qt-quickstart/llms.txt This C++ code implements the IZoomVideoSDKDelegate interface to handle various session events and callbacks from the Zoom Video SDK. It includes methods for session join/leave, error handling, and user video status changes. It requires the 'zoom_video_sdk_delegate_interface.h' header and a QtMainWindow object for UI updates. ```cpp #include "zoom_video_sdk_delegate_interface.h" class ZoomVideoSDKDelegate : public IZoomVideoSDKDelegate { public: ZoomVideoSDKDelegate(QtMainWindow* mainWindow) : m_mainWindow(mainWindow) {} virtual void onSessionJoin() override { printf("Session joined successfully\n"); g_in_session = true; // Update UI on main thread using Qt QMetaObject::invokeMethod(m_mainWindow, "updateStatus", Qt::QueuedConnection, Q_ARG(QString, "Session joined successfully")); } virtual void onSessionLeave() override { printf("Left session\n"); g_in_session = false; } virtual void onSessionLeave(ZoomVideoSDKSessionLeaveReason eReason) override { printf("Left session with reason: %d\n", (int)eReason); g_in_session = false; } virtual void onError(ZoomVideoSDKErrors errorCode, int detailErrorCode) override { printf("Session error: %d, detail: %d\n", errorCode, detailErrorCode); } virtual void onUserVideoStatusChanged(IZoomVideoSDKVideoHelper* pVideoHelper, IVideoSDKVector* userList) override { // Handle video status changes for users if (userList && video_sdk_obj) { int count = userList->GetCount(); for (int i = 0; i < count; i++) { IZoomVideoSDKUser* user = userList->GetItem(i); if (user && user->GetVideoPipe()) { printf("Video available for user: %s\n", user->getUserName()); } } } } // Implement other delegate methods as needed... private: QtMainWindow* m_mainWindow; }; // Register delegate with SDK ZoomVideoSDKDelegate* delegate = new ZoomVideoSDKDelegate(&mainWindow); video_sdk_obj->addListener(dynamic_cast(delegate)); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.