diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index a4be68d3c..91203d319 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -51,7 +51,7 @@ body: render: shell - type: textarea attributes: - label: Python Code + label: Python Code(Optional) description: Share python code you're using(only if available) here or else leave this block empty. You can directly paste your python code here, no need for any backticks or formatting. render: python - type: input diff --git a/.github/ISSUE_TEMPLATE/question.yaml b/.github/ISSUE_TEMPLATE/question.yaml index d3b596c80..a41ed1fc2 100644 --- a/.github/ISSUE_TEMPLATE/question.yaml +++ b/.github/ISSUE_TEMPLATE/question.yaml @@ -27,6 +27,16 @@ body: description: Please describe your question thoroughly here. What are you trying to accomplish? validations: required: true + - type: textarea + attributes: + label: Terminal log output(Optional) + description: Copy and paste any relevant terminal log output(only if applicable) here or else leave this block empty. You can enable logging with `logging=True` in any Vidgear API for getting verbose terminal logs. + render: shell + - type: textarea + attributes: + label: Python Code(Optional) + description: Share python code you're using(only if available) here or else leave this block empty. You can directly paste your python code here, no need for any backticks or formatting. + render: python - type: input attributes: label: VidGear Version diff --git a/.github/workflows/ci_linux.yml b/.github/workflows/ci_linux.yml index ea2946ffe..6c748cefa 100644 --- a/.github/workflows/ci_linux.yml +++ b/.github/workflows/ci_linux.yml @@ -19,30 +19,30 @@ on: branches: - testing paths-ignore: - - '**/*.md' - - '**/*.html' - - '**/*.js' - - '**/*.css' - - 'docs/**/*' + - "**/*.md" + - "**/*.html" + - "**/*.js" + - "**/*.css" + - "docs/**/*" - README.md - mkdocs.yml pull_request: branches: - testing paths-ignore: - - '**/*.md' - - 'docs/**/*' + - "**/*.md" + - "docs/**/*" jobs: test: name: CI Test vidgear - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 strategy: matrix: - python-version: ['3.7', '3.8', '3.9', '3.10'] + python-version: ["3.7", "3.8", "3.9", "3.10"] steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: install apt_dependencies @@ -50,6 +50,7 @@ jobs: sudo apt-get update -qq sudo apt-get install -qq unzip wget -y sudo apt-get install -qq dos2unix -y + sudo apt-get install ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y - name: prepare bash_scripts run: | dos2unix scripts/bash/prepare_dataset.sh @@ -61,7 +62,9 @@ jobs: pip install -U pip wheel numpy pip install -U .[asyncio] pip uninstall opencv-python -y - pip install -U flake8 six codecov pytest pytest-asyncio pytest-cov yt_dlp mpegdash paramiko m3u8 async-asgi-testclient + pip install -U flake8 six codecov httpx pytest pytest-asyncio pytest-cov yt_dlp mpegdash paramiko m3u8 async-asgi-testclient + pip install -U deffcode + pip install cryptography==38.0.4 if: success() - name: run prepare_dataset_script run: bash scripts/bash/prepare_dataset.sh @@ -80,13 +83,17 @@ jobs: if: success() && matrix.python-version == 3.7 - name: pytest without_ENV run: | + sudo modprobe v4l2loopback devices=1 video_nr=0 exclusive_caps=1 card_label='VCamera' timeout 1200 pytest --verbose --cov=vidgear --cov-report=xml --cov-report term-missing vidgear/tests/ || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; else echo "EXIT_CODE=$code" >>$GITHUB_ENV; fi flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics if: success() && matrix.python-version != 3.7 + - name: Display exit code + run: echo "Exit code was = $EXIT_CODE" - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v3 with: name: ${{ matrix.python-version }} + token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: true verbose: true - if: ${{ env.EXIT_CODE != '124' }} \ No newline at end of file + if: ${{ env.EXIT_CODE != '124' }} diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml index f3f7c9a53..86aafbc09 100644 --- a/.github/workflows/deploy_docs.yml +++ b/.github/workflows/deploy_docs.yml @@ -34,10 +34,10 @@ jobs: if: github.event_name == 'release' && github.event.action == 'published' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} - name: install_vidgear @@ -75,10 +75,10 @@ jobs: if: github.event_name == 'push' && github.ref == 'refs/heads/master' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} - name: install_vidgear @@ -118,11 +118,11 @@ jobs: if: github.event_name == 'push' && github.ref == 'refs/heads/testing' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - run: git checkout testing - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} - name: install_vidgear diff --git a/README.md b/README.md index fd5ef55fc..8a48f26b4 100644 --- a/README.md +++ b/README.md @@ -19,26 +19,27 @@ limitations under the License. -->

- VidGear + VidGear

- VidGear tagline + VidGear tagline

[Releases][release]   |   [Gears][gears]   |   [Documentation][docs]   |   [Installation][installation]   |   [License](#copyright) -[![Build Status][github-cli]][github-flow] [![Codecov branch][codecov]][code] [![Azure DevOps builds (branch)][azure-badge]][azure-pipeline] +[![Build Status][github-cli]][github-flow] [![Codecov branch][codecov]][code] [![Azure DevOps builds (branch)][azure-badge]][azure-pipeline] -[![Glitter chat][gitter-bagde]][gitter] [![Build Status][appveyor]][app] [![PyPi version][pypi-badge]][pypi] +[![Glitter chat][gitter-bagde]][gitter] [![Build Status][appveyor]][app] [![PyPi version][pypi-badge]][pypi] [![Code Style][black-badge]][black] +
  -VidGear is a **High-Performance Video Processing Python Library** that provides an easy-to-use, highly extensible, thoroughly optimised **Multi-Threaded + Asyncio API Framework** on top of many state-of-the-art specialized libraries like *[OpenCV][opencv], [FFmpeg][ffmpeg], [ZeroMQ][zmq], [picamera][picamera], [starlette][starlette], [yt_dlp][yt_dlp], [pyscreenshot][pyscreenshot], [aiortc][aiortc] and [python-mss][mss]* serving at its backend, and enable us to flexibly exploit their internal parameters and methods, while silently delivering **robust error-handling and real-time performance 🔥** +VidGear is a **High-Performance Video Processing Python Library** that provides an easy-to-use, highly extensible, thoroughly optimised **Multi-Threaded + Asyncio API Framework** on top of many state-of-the-art specialized libraries like _[OpenCV][opencv], [FFmpeg][ffmpeg], [ZeroMQ][zmq], [picamera][picamera], [starlette][starlette], [yt_dlp][yt_dlp], [pyscreenshot][pyscreenshot], [aiortc][aiortc] and [python-mss][mss]_ serving at its backend, and enable us to flexibly exploit their internal parameters and methods, while silently delivering **robust error-handling and real-time performance 🔥** VidGear primarily focuses on simplicity, and thereby lets programmers and software developers to easily integrate and perform Complex Video Processing Tasks, in just a few lines of code. @@ -47,53 +48,50 @@ VidGear primarily focuses on simplicity, and thereby lets programmers and softwa The following **functional block diagram** clearly depicts the generalized functioning of VidGear APIs:

- @Vidgear Functional Block Diagram + @Vidgear Functional Block Diagram

  # Table of Contents -* [**TL;DR**](#tldr) -* [**Getting Started**](#getting-started) -* [**Gears: What are these?**](#gears-what-are-these) - * [**CamGear**](#camgear) - * [**PiGear**](#pigear) - * [**VideoGear**](#videogear) - * [**ScreenGear**](#screengear) - * [**WriteGear**](#writegear) - * [**StreamGear**](#streamgear) - * [**NetGear**](#netgear) - * [**WebGear**](#webgear) - * [**WebGear_RTC**](#webgear_rtc) - * [**NetGear_Async**](#netgear_async) -* [**Contributions**](#contributions) -* [**Donations**](#donations) -* [**Citation**](#citation) -* [**Copyright**](#copyright) - +- [**TL;DR**](#tldr) +- [**Getting Started**](#getting-started) +- [**Gears: What are these?**](#gears-what-are-these) + - [**CamGear**](#camgear) + - [**PiGear**](#pigear) + - [**VideoGear**](#videogear) + - [**ScreenGear**](#screengear) + - [**WriteGear**](#writegear) + - [**StreamGear**](#streamgear) + - [**NetGear**](#netgear) + - [**WebGear**](#webgear) + - [**WebGear_RTC**](#webgear_rtc) + - [**NetGear_Async**](#netgear_async) +- [**Contributions**](#contributions) +- [**Donations**](#donations) +- [**Citation**](#citation) +- [**Copyright**](#copyright)     - - ## TL;DR - + #### What is vidgear? -> *"VidGear is a cross-platform High-Performance Framework that provides an one-stop **Video-Processing** solution for building complex real-time media applications in python."* +> _"VidGear is a cross-platform High-Performance Framework that provides an one-stop **Video-Processing** solution for building complex real-time media applications in python."_ #### What does it do? -> *"VidGear can read, write, process, send & receive video files/frames/streams from/to various devices in real-time, and [**faster**][TQM-doc] than underline libraries."* +> _"VidGear can read, write, process, send & receive video files/frames/streams from/to various devices in real-time, and [**faster**][tqm-doc] than underline libraries."_ #### What is its purpose? -> *"Write Less and Accomplish More"* — **VidGear's Motto** +> _"Write Less and Accomplish More"_ — **VidGear's Motto** -> *"Built with simplicity in mind, VidGear lets programmers and software developers to easily integrate and perform **Complex Video-Processing Tasks** in their existing or newer applications without going through hefty documentation and in just a [**few lines of code**][switch_from_cv]. Beneficial for both, if you're new to programming with Python language or already a pro at it."* +> _"Built with simplicity in mind, VidGear lets programmers and software developers to easily integrate and perform **Complex Video-Processing Tasks** in their existing or newer applications without going through hefty documentation and in just a [**few lines of code**][switch_from_cv]. Beneficial for both, if you're new to programming with Python language or already a pro at it."_   @@ -103,7 +101,7 @@ The following **functional block diagram** clearly depicts the generalized funct If this is your first time using VidGear, head straight to the [Installation ➶][installation] to install VidGear. -Once you have VidGear installed, **Checkout its Well-Documented [Function-Specific Gears ➶][gears]** +Once you have VidGear installed, **Checkout its Well-Documented [Function-Specific Gears ➶][gears]** Also, if you're already familiar with [OpenCV][opencv] library, then see [Switching from OpenCV Library ➶][switch_from_cv] @@ -113,58 +111,55 @@ Or, if you're just getting started with OpenCV-Python programming, then refer th   - ## Gears: What are these? > **VidGear is built with multiple APIs a.k.a [Gears][gears], each with some unique functionality.** -Each API is designed exclusively to handle/control/process different data-specific & device-specific video streams, network streams, and media encoders/decoders. These APIs provides the user an easy-to-use, dynamic, extensible, and exposed Multi-Threaded + Asyncio optimized internal layer above state-of-the-art libraries to work with, while silently delivering robust error-handling. +Each API is designed exclusively to handle/control/process different data-specific & device-specific video streams, network streams, and media encoders/decoders. These APIs provides the user an easy-to-use, dynamic, extensible, and exposed Multi-Threaded + Asyncio optimized internal layer above state-of-the-art libraries to work with, while silently delivering robust error-handling. **These Gears can be classified as follows:** **A. Video-Capture Gears:** - * [**CamGear:**](#camgear) Multi-Threaded API targeting various IP-USB-Cameras/Network-Streams/Streaming-Sites-URLs. - * [**PiGear:**](#pigear) Multi-Threaded API targeting various Raspberry-Pi Camera Modules. - * [**ScreenGear:**](#screengear) Multi-Threaded API targeting ultra-fast Screencasting. - * [**VideoGear:**](#videogear) Common Video-Capture API with internal [Video Stabilizer](https://abhitronix.github.io/vidgear/latest/gears/stabilizer/overview/) wrapper. +- [**CamGear:**](#camgear) Multi-Threaded API targeting various IP-USB-Cameras/Network-Streams/Streaming-Sites-URLs. +- [**PiGear:**](#pigear) Multi-Threaded API targeting various Raspberry-Pi Camera Modules. +- [**ScreenGear:**](#screengear) Multi-Threaded API targeting ultra-fast Screencasting. +- [**VideoGear:**](#videogear) Common Video-Capture API with internal [Video Stabilizer](https://abhitronix.github.io/vidgear/latest/gears/stabilizer/overview/) wrapper. **B. Video-Writer Gears:** - * [**WriteGear:**](#writegear) Handles Lossless Video-Writer for file/stream/frames Encoding and Compression. +- [**WriteGear:**](#writegear) Handles Lossless Video-Writer for file/stream/frames Encoding and Compression. **C. Streaming Gears:** - * [**StreamGear**](#streamgear): Handles Transcoding of High-Quality, Dynamic & Adaptive Streaming Formats. +- [**StreamGear**](#streamgear): Handles Transcoding of High-Quality, Dynamic & Adaptive Streaming Formats. - * **Asynchronous I/O Streaming Gear:** +- **Asynchronous I/O Streaming Gear:** - * [**WebGear:**](#webgear) ASGI Video-Server that broadcasts Live MJPEG-Frames to any web-browser on the network. - * [**WebGear_RTC:**](#webgear_rtc) Real-time Asyncio WebRTC media server for streaming directly to peer clients over the network. + - [**WebGear:**](#webgear) ASGI Video-Server that broadcasts Live MJPEG-Frames to any web-browser on the network. + - [**WebGear_RTC:**](#webgear_rtc) Real-time Asyncio WebRTC media server for streaming directly to peer clients over the network. **D. Network Gears:** - * [**NetGear:**](#netgear) Handles High-Performance Video-Frames & Data Transfer between interconnecting systems over the network. - - * **Asynchronous I/O Network Gear:** +- [**NetGear:**](#netgear) Handles High-Performance Video-Frames & Data Transfer between interconnecting systems over the network. - * [**NetGear_Async:**](#netgear_async) Immensely Memory-Efficient Asyncio Video-Frames Network Messaging Framework. +- **Asynchronous I/O Network Gear:** + - [**NetGear_Async:**](#netgear_async) Immensely Memory-Efficient Asyncio Video-Frames Network Messaging Framework.     - ## CamGear

- CamGear Functional Block Diagram + CamGear Functional Block Diagram

-> *CamGear can grab ultra-fast frames from a diverse range of file-formats/devices/streams, which includes almost any IP-USB Cameras, multimedia video file-formats ([_upto 4k tested_][test-4k]), various network stream protocols such as `http(s), rtp, rstp, rtmp, mms, etc.`, and GStreamer's pipelines, plus direct support for live video streaming sites like YouTube, Twitch, LiveStream, Dailymotion etc.* +> _CamGear can grab ultra-fast frames from a diverse range of file-formats/devices/streams, which includes almost any IP-USB Cameras, multimedia video file-formats ([*upto 4k tested*][test-4k]), various network stream protocols such as `http(s), rtp, rtsp, rtmp, mms, etc.`, and GStreamer's pipelines, plus direct support for live video streaming sites like YouTube, Twitch, LiveStream, Dailymotion etc._ -CamGear provides a flexible, high-level, multi-threaded framework around OpenCV's [VideoCapture class][opencv-vc] with access almost all of its available parameters. CamGear internally implements [`yt_dlp`][yt_dlp] backend class for seamlessly pipelining live video-frames and metadata from various streaming services like [YouTube][youtube-doc], [Twitch][piping-live-videos], and [many more ➶](https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md#supported-sites). Furthermore, its framework relies exclusively on [**Threaded Queue mode**][TQM-doc] for ultra-fast, error-free, and synchronized video-frame handling. +CamGear provides a flexible, high-level, multi-threaded framework around OpenCV's [VideoCapture class][opencv-vc] with access almost all of its available parameters. CamGear internally implements [`yt_dlp`][yt_dlp] backend class for seamlessly pipelining live video-frames and metadata from various streaming services like [YouTube][youtube-doc], [Twitch][piping-live-videos], and [many more ➶](https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md#supported-sites). Furthermore, its framework relies exclusively on [**Threaded Queue mode**][tqm-doc] for ultra-fast, error-free, and synchronized video-frame handling. ### CamGear API Guide: @@ -174,20 +169,18 @@ CamGear provides a flexible, high-level, multi-threaded framework around OpenCV'   - ## VideoGear -> *VideoGear API provides a special internal wrapper around VidGear's exclusive [**Video Stabilizer**][stablizer-doc] class.* +> _VideoGear API provides a special internal wrapper around VidGear's exclusive [**Video Stabilizer**][stabilizer-doc] class._ VideoGear also acts as a Common Video-Capture API that provides internal access for both [CamGear](#camgear) and [PiGear](#pigear) APIs and their parameters with an exclusive `enablePiCamera` boolean flag. -VideoGear is ideal when you need to switch to different video sources without changing your code much. Also, it enables easy stabilization for various video-streams _(real-time or not)_ with minimum effort and writing way fewer lines of code. - +VideoGear is ideal when you need to switch to different video sources without changing your code much. Also, it enables easy stabilization for various video-streams _(real-time or not)_ with minimum effort and writing way fewer lines of code. -**Below is a snapshot of a VideoGear Stabilizer in action (_See its detailed usage [here][stablizer-doc-ex]_):** +**Below is a snapshot of a VideoGear Stabilizer in action (_See its detailed usage [here][stabilizer-doc-ex]_):**

- VideoGear Stabilizer in action! + VideoGear Stabilizer in action!
Original Video Courtesy @SIGGRAPH2013

@@ -266,20 +259,18 @@ stream_stab.stop()   - ## PiGear

- PiGear + PiGear

-> *PiGear is similar to CamGear but made to support various Raspberry Pi Camera Modules *(such as [OmniVision OV5647 Camera Module][OV5647-picam] and [Sony IMX219 Camera Module][IMX219-picam])*.* +> _PiGear is similar to CamGear but made to support various Raspberry Pi Camera Modules _(such as [OmniVision OV5647 Camera Module][ov5647-picam] and [Sony IMX219 Camera Module][imx219-picam])_._ PiGear provides a flexible multi-threaded framework around complete [picamera](https://picamera.readthedocs.io/en/release-1.13/index.html) python library, and provide us the ability to exploit almost all of its parameters like `brightness, saturation, sensor_mode, iso, exposure, etc.` effortlessly. Furthermore, PiGear also supports multiple camera modules, such as in the case of Raspberry-Pi Compute Module IO boards. Best of all, PiGear contains **Threaded Internal Timer** - that silently keeps active track of any frozen-threads/hardware-failures and exit safely, if any does occur. That means that if you're running PiGear API in your script and someone accidentally pulls the Camera-Module cable out, instead of going into possible kernel panic, API will exit safely to save resources. - **Code to open picamera stream with variable parameters in PiGear API:** ```python @@ -327,6 +318,7 @@ cv2.destroyAllWindows() stream.stop() ``` + ### PiGear API Guide: [**>>> Usage Guide**][pigear-doc] @@ -335,17 +327,16 @@ stream.stop()   - ## ScreenGear -> *ScreenGear is designed exclusively for ultra-fast Screencasting, which means it can grab frames from your monitor in real-time, either by defining an area on the computer screen or full-screen, at the expense of inconsiderable latency. ScreenGear also seamlessly support frame capturing from multiple monitors as well as supports multiple backends.* +> _ScreenGear is designed exclusively for ultra-fast Screencasting, which means it can grab frames from your monitor in real-time, either by defining an area on the computer screen or full-screen, at the expense of inconsiderable latency. ScreenGear also seamlessly support frame capturing from multiple monitors as well as supports multiple backends._ -ScreenGear implements a multi-threaded wrapper around [**pyscreenshot**][pyscreenshot] & [**python-mss**][mss] python library API and also supports an easy and flexible direct internal parameter manipulation. +ScreenGear implements a multi-threaded wrapper around [**pyscreenshot**][pyscreenshot] & [**python-mss**][mss] python library API and also supports an easy and flexible direct internal parameter manipulation. **Below is a snapshot of a ScreenGear API in action:**

- ScreenGear in action! + ScreenGear in action!

**Code to generate the above results:** @@ -389,24 +380,21 @@ stream.stop() [**>>> Usage Guide**][screengear-doc] -     - - ## WriteGear

- WriteGear Functional Block Diagram + WriteGear Functional Block Diagram

-> *WriteGear handles various powerful Video-Writer Tools that provide us the freedom to do almost anything imaginable with multimedia data.* +> _WriteGear handles various powerful Video-Writer Tools that provide us the freedom to do almost anything imaginable with multimedia data._ -WriteGear API provides a complete, flexible, and robust wrapper around [**FFmpeg**][ffmpeg], a leading multimedia framework. WriteGear can process real-time frames into a lossless compressed video-file with any suitable specifications _(such as`bitrate, codec, framerate, resolution, subtitles, etc.`)_. +WriteGear API provides a complete, flexible, and robust wrapper around [**FFmpeg**][ffmpeg], a leading multimedia framework. WriteGear can process real-time frames into a lossless compressed video-file with any suitable specifications _(such as`bitrate, codec, framerate, resolution, subtitles, etc.`)_. -WriteGear also supports streaming with traditional protocols such as [RTSP/RTP][rstp-ex], RTMP. It is powerful enough to perform complex tasks such as [Live-Streaming][live-stream] _(such as for Twitch, YouTube etc.)_ and [Multiplexing Video-Audio][live-audio-doc] with real-time frames in just few lines of code. +WriteGear also supports streaming with traditional protocols such as [RTSP/RTP][rtsp-ex], RTMP. It is powerful enough to perform complex tasks such as [Live-Streaming][live-stream] _(such as for Twitch, YouTube etc.)_ and [Multiplexing Video-Audio][live-audio-doc] with real-time frames in just few lines of code. Best of all, WriteGear grants users the complete freedom to play with any FFmpeg parameter with its exclusive **Custom Commands function** _(see this [doc][custom-command-doc])_ without relying on any third-party API. @@ -414,9 +402,9 @@ In addition to this, WriteGear also provides flexible access to [**OpenCV's Vide **WriteGear primarily operates in the following two modes:** - * **Compression Mode:** In this mode, WriteGear utilizes powerful [**FFmpeg**][ffmpeg] inbuilt encoders to encode lossless multimedia files. This mode provides us the ability to exploit almost any parameter available within FFmpeg, effortlessly and flexibly, and while doing that it robustly handles all errors/warnings quietly. **You can find more about this mode [here ➶][cm-writegear-doc]** +- **Compression Mode:** In this mode, WriteGear utilizes powerful [**FFmpeg**][ffmpeg] inbuilt encoders to encode lossless multimedia files. This mode provides us the ability to exploit almost any parameter available within FFmpeg, effortlessly and flexibly, and while doing that it robustly handles all errors/warnings quietly. **You can find more about this mode [here ➶][cm-writegear-doc]** - * **Non-Compression Mode:** In this mode, WriteGear utilizes basic [**OpenCV's inbuilt VideoWriter API**][opencv-vw] tools. This mode also supports all parameter transformations available within OpenCV's VideoWriter API, but it lacks the ability to manipulate encoding parameters and other important features like video compression, audio encoding, etc. **You can learn about this mode [here ➶][ncm-writegear-doc]** +- **Non-Compression Mode:** In this mode, WriteGear utilizes basic [**OpenCV's inbuilt VideoWriter API**][opencv-vw] tools. This mode also supports all parameter transformations available within OpenCV's VideoWriter API, but it lacks the ability to manipulate encoding parameters and other important features like video compression, audio encoding, etc. **You can learn about this mode [here ➶][ncm-writegear-doc]** ### WriteGear API Guide: @@ -426,30 +414,27 @@ In addition to this, WriteGear also provides flexible access to [**OpenCV's Vide   - ## StreamGear

- NetGear API + NetGear API

- - -> *StreamGear automates transcoding workflow for generating Ultra-Low Latency, High-Quality, Dynamic & Adaptive Streaming Formats (such as MPEG-DASH and Apple HLS) in just few lines of python code.* +> _StreamGear automates transcoding workflow for generating Ultra-Low Latency, High-Quality, Dynamic & Adaptive Streaming Formats (such as MPEG-DASH and Apple HLS) in just few lines of python code._ StreamGear provides a standalone, highly extensible, and flexible wrapper around [**FFmpeg**][ffmpeg] multimedia framework for generating chunked-encoded media segments of the content. SteamGear is an out-of-the-box solution for transcoding source videos/audio files & real-time video frames and breaking them into a sequence of multiple smaller chunks/segments of suitable lengths. These segments make it possible to stream videos at different quality levels _(different bitrates or spatial resolutions)_ and can be switched in the middle of a video from one quality level to another – if bandwidth permits – on a per-segment basis. A user can serve these segments on a web server that makes it easier to download them through HTTP standard-compliant GET requests. -SteamGear currently supports [**MPEG-DASH**](https://www.encoding.com/mpeg-dash/) _(Dynamic Adaptive Streaming over HTTP, ISO/IEC 23009-1)_ and [**Apple HLS**](https://developer.apple.com/documentation/http_live_streaming) _(HTTP Live Streaming)_. But, Multiple DRM support is yet to be implemented. +SteamGear currently supports [**MPEG-DASH**](https://www.encoding.com/mpeg-dash/) _(Dynamic Adaptive Streaming over HTTP, ISO/IEC 23009-1)_ and [**Apple HLS**](https://developer.apple.com/documentation/http_live_streaming) _(HTTP Live Streaming)_. But, Multiple DRM support is yet to be implemented. SteamGear also creates a Manifest file _(such as MPD in-case of DASH)_ or a Master Playlist _(such as M3U8 in-case of Apple HLS)_ besides segments that describe these segment information _(timing, URL, media characteristics like video resolution and bit rates)_ and is provided to the client before the streaming session. **StreamGear primarily works in two Independent Modes for transcoding which serves different purposes:** - * **Single-Source Mode:** In this mode, StreamGear **transcodes entire video file** _(as opposed to frame-by-frame)_ into a sequence of multiple smaller chunks/segments for streaming. This mode works exceptionally well when you're transcoding long-duration lossless videos(with audio) for streaming that required no interruptions. But on the downside, the provided source cannot be flexibly manipulated or transformed before sending onto FFmpeg Pipeline for processing. ***Learn more about this mode [here ➶][ss-mode-doc]*** +- **Single-Source Mode:** In this mode, StreamGear **transcodes entire video file** _(as opposed to frame-by-frame)_ into a sequence of multiple smaller chunks/segments for streaming. This mode works exceptionally well when you're transcoding long-duration lossless videos(with audio) for streaming that required no interruptions. But on the downside, the provided source cannot be flexibly manipulated or transformed before sending onto FFmpeg Pipeline for processing. **_Learn more about this mode [here ➶][ss-mode-doc]_** - * **Real-time Frames Mode:** In this mode, StreamGear directly **transcodes frame-by-frame** _(as opposed to a entire video file)_, into a sequence of multiple smaller chunks/segments for streaming. This mode works exceptionally well when you desire to flexibility manipulate or transform [`numpy.ndarray`](https://numpy.org/doc/1.18/reference/generated/numpy.ndarray.html#numpy-ndarray) frames in real-time before sending them onto FFmpeg Pipeline for processing. But on the downside, audio has to added manually _(as separate source)_ for streams. ***Learn more about this mode [here ➶][rtf-mode-doc]*** +- **Real-time Frames Mode:** In this mode, StreamGear directly **transcodes frame-by-frame** _(as opposed to a entire video file)_, into a sequence of multiple smaller chunks/segments for streaming. This mode works exceptionally well when you desire to flexibility manipulate or transform [`numpy.ndarray`](https://numpy.org/doc/1.18/reference/generated/numpy.ndarray.html#numpy-ndarray) frames in real-time before sending them onto FFmpeg Pipeline for processing. But on the downside, audio has to added manually _(as separate source)_ for streams. **_Learn more about this mode [here ➶][rtf-mode-doc]_** ### StreamGear API Guide: @@ -462,14 +447,14 @@ SteamGear also creates a Manifest file _(such as MPD in-case of DASH)_ or a Mast ## NetGear

- NetGear API + NetGear API

-> *NetGear is exclusively designed to transfer video-frames & data synchronously between interconnecting systems over the network in real-time.* +> _NetGear is exclusively designed to transfer video-frames & data synchronously between interconnecting systems over the network in real-time._ NetGear implements a high-level wrapper around [**PyZmQ**][pyzmq] python library that contains python bindings for [**ZeroMQ**][zmq] - a high-performance asynchronous distributed messaging library. -NetGear seamlessly supports additional [**bidirectional data transmission**][netgear_bidata_doc] between receiver(client) and sender(server) while transferring video-frames all in real-time. +NetGear seamlessly supports additional [**bidirectional data transmission**][netgear_bidata_doc] between receiver(client) and sender(server) while transferring video-frames all in real-time. NetGear can also robustly handle [**Multiple Server-Systems**][netgear_multi_server_doc] and [**Multiple Client-Systems**][netgear_multi_client_doc] and at once, thereby providing access to a seamless exchange of video-frames & data between multiple devices across the network at the same time. @@ -481,9 +466,9 @@ For security, NetGear implements easy access to ZeroMQ's powerful, smart & secur **NetGear as of now seamlessly supports three ZeroMQ messaging patterns:** -* [**`zmq.PAIR`**][zmq-pair] _(ZMQ Pair Pattern)_ -* [**`zmq.REQ/zmq.REP`**][zmq-req-rep] _(ZMQ Request/Reply Pattern)_ -* [**`zmq.PUB/zmq.SUB`**][zmq-pub-sub] _(ZMQ Publish/Subscribe Pattern)_ +- [**`zmq.PAIR`**][zmq-pair] _(ZMQ Pair Pattern)_ +- [**`zmq.REQ/zmq.REP`**][zmq-req-rep] _(ZMQ Request/Reply Pattern)_ +- [**`zmq.PUB/zmq.SUB`**][zmq-pub-sub] _(ZMQ Publish/Subscribe Pattern)_ Whereas supported protocol are: `tcp` and `ipc`. @@ -495,12 +480,11 @@ Whereas supported protocol are: `tcp` and `ipc`.   - ## WebGear -> *WebGear is a powerful [ASGI](https://asgi.readthedocs.io/en/latest/) Video-Broadcaster API ideal for transmitting [Motion-JPEG](https://en.wikipedia.org/wiki/Motion_JPEG)-frames from a single source to multiple recipients via the browser.* +> _WebGear is a powerful [ASGI](https://asgi.readthedocs.io/en/latest/) Video-Broadcaster API ideal for transmitting [Motion-JPEG](https://en.wikipedia.org/wiki/Motion_JPEG)-frames from a single source to multiple recipients via the browser._ -WebGear API works on [**Starlette**](https://www.starlette.io/)'s ASGI application and provides a highly extensible and flexible async wrapper around its complete framework. WebGear can flexibly interact with Starlette's ecosystem of shared middleware, mountable applications, [Response classes](https://www.starlette.io/responses/), [Routing tables](https://www.starlette.io/routing/), [Static Files](https://www.starlette.io/staticfiles/), [Templating engine(with Jinja2)](https://www.starlette.io/templates/), etc. +WebGear API works on [**Starlette**](https://www.starlette.io/)'s ASGI application and provides a highly extensible and flexible async wrapper around its complete framework. WebGear can flexibly interact with Starlette's ecosystem of shared middleware, mountable applications, [Response classes](https://www.starlette.io/responses/), [Routing tables](https://www.starlette.io/routing/), [Static Files](https://www.starlette.io/staticfiles/), [Templating engine(with Jinja2)](https://www.starlette.io/templates/), etc. WebGear API uses an intraframe-only compression scheme under the hood where the sequence of video-frames are first encoded as JPEG-DIB (JPEG with Device-Independent Bit compression) and then streamed over HTTP using Starlette's Multipart [Streaming Response](https://www.starlette.io/responses/#streamingresponse) and a [Uvicorn](https://www.uvicorn.org/#quickstart) ASGI Server. This method imposes lower processing and memory requirements, but the quality is not the best, since JPEG compression is not very efficient for motion video. @@ -509,7 +493,7 @@ In layman's terms, WebGear acts as a powerful **Video Broadcaster** that transmi **Below is a snapshot of a WebGear Video Server in action on Chrome browser:**

- WebGear in action! + WebGear in action!
WebGear Video Server at http://localhost:8000/ address.

@@ -543,29 +527,26 @@ web.shutdown() [**>>> Usage Guide**][webgear-doc] -     - ## WebGear_RTC -> *WebGear_RTC is similar to [WeGear API](#webgear) in many aspects but utilizes [WebRTC][webrtc] technology under the hood instead of Motion JPEG, which makes it suitable for building powerful video-streaming solutions for all modern browsers as well as native clients available on all major platforms.* +> _WebGear_RTC is similar to [WeGear API](#webgear) in many aspects but utilizes [WebRTC][webrtc] technology under the hood instead of Motion JPEG, which makes it suitable for building powerful video-streaming solutions for all modern browsers as well as native clients available on all major platforms._ WebGear_RTC is implemented with the help of [**aiortc**][aiortc] library which is built on top of asynchronous I/O framework for Web Real-Time Communication (WebRTC) and Object Real-Time Communication (ORTC) and supports many features like SDP generation/parsing, Interactive Connectivity Establishment with half-trickle and mDNS support, DTLS key and certificate generation, DTLS handshake, etc. WebGear_RTC can handle [multiple consumers][webgear_rtc-mc] seamlessly and provides native support for ICE _(Interactive Connectivity Establishment)_ protocol, STUN _(Session Traversal Utilities for NAT)_, and TURN _(Traversal Using Relays around NAT)_ servers that help us to seamlessly establish direct media connection with the remote peers for uninterrupted data flow. It also allows us to define our custom streaming class with suitable source to transform frames easily before sending them across the network(see this [doc][webgear_rtc-cs] example). -WebGear_RTC API works in conjunction with [**Starlette**][starlette]'s ASGI application and provides easy access to its complete framework. WebGear_RTC can also flexibly interact with Starlette's ecosystem of shared middleware, mountable applications, [Response classes](https://www.starlette.io/responses/), [Routing tables](https://www.starlette.io/routing/), [Static Files](https://www.starlette.io/staticfiles/), [Templating engine(with Jinja2)](https://www.starlette.io/templates/), etc. +WebGear_RTC API works in conjunction with [**Starlette**][starlette]'s ASGI application and provides easy access to its complete framework. WebGear_RTC can also flexibly interact with Starlette's ecosystem of shared middleware, mountable applications, [Response classes](https://www.starlette.io/responses/), [Routing tables](https://www.starlette.io/routing/), [Static Files](https://www.starlette.io/staticfiles/), [Templating engine(with Jinja2)](https://www.starlette.io/templates/), etc. Additionally, WebGear_RTC API also provides a special internal wrapper around [VideoGear](#videogear), which itself provides internal access to both [CamGear](#camgear) and [PiGear](#pigear) APIs. - **Below is a snapshot of a WebGear_RTC Media Server in action on Chrome browser:**

- WebGear_RTC in action! + WebGear_RTC in action!
WebGear_RTC Video Server at http://localhost:8000/ address.

@@ -596,31 +577,31 @@ web.shutdown() [**>>> Usage Guide**][webgear_rtc-doc] -     -## NetGear_Async +## NetGear_Async

- WebGear in action! + WebGear in action!

. > _NetGear_Async can generate the same performance as [NetGear API](#netgear) at about one-third the memory consumption, and also provide complete server-client handling with various options to use variable protocols/patterns similar to NetGear, but lacks in term of flexibility as it supports only a few [NetGear's Exclusive Modes][netgear-exm]._ -NetGear_Async is built on [`zmq.asyncio`][asyncio-zmq], and powered by a high-performance asyncio event loop called [**`uvloop`**][uvloop] to achieve unmatchable high-speed and lag-free video streaming over the network with minimal resource constraints. NetGear_Async can transfer thousands of frames in just a few seconds without causing any significant load on your system. +NetGear_Async is built on [`zmq.asyncio`][asyncio-zmq], and powered by a high-performance asyncio event loop called [**`uvloop`**][uvloop] to achieve unmatchable high-speed and lag-free video streaming over the network with minimal resource constraints. NetGear_Async can transfer thousands of frames in just a few seconds without causing any significant load on your system. -NetGear_Async provides complete server-client handling and options to use variable protocols/patterns similar to [NetGear API](#netgear). Furthermore, NetGear_Async allows us to define our custom Server as source to transform frames easily before sending them across the network(see this [doc][netgear_Async-cs] example). +NetGear_Async provides complete server-client handling and options to use variable protocols/patterns similar to [NetGear API](#netgear). Furthermore, NetGear_Async allows us to define our custom Server as source to transform frames easily before sending them across the network(see this [doc][netgear_async-cs] example). NetGear_Async now supports additional [**bidirectional data transmission**][btm_netgear_async] between receiver(client) and sender(server) while transferring video-frames. Users can easily build complex applications such as like [Real-Time Video Chat][rtvc] in just few lines of code. NetGear_Async as of now supports all four ZeroMQ messaging patterns: -* [**`zmq.PAIR`**][zmq-pair] _(ZMQ Pair Pattern)_ -* [**`zmq.REQ/zmq.REP`**][zmq-req-rep] _(ZMQ Request/Reply Pattern)_ -* [**`zmq.PUB/zmq.SUB`**][zmq-pub-sub] _(ZMQ Publish/Subscribe Pattern)_ -* [**`zmq.PUSH/zmq.PULL`**][zmq-pull-push] _(ZMQ Push/Pull Pattern)_ + +- [**`zmq.PAIR`**][zmq-pair] _(ZMQ Pair Pattern)_ +- [**`zmq.REQ/zmq.REP`**][zmq-req-rep] _(ZMQ Request/Reply Pattern)_ +- [**`zmq.PUB/zmq.SUB`**][zmq-pub-sub] _(ZMQ Publish/Subscribe Pattern)_ +- [**`zmq.PUSH/zmq.PULL`**][zmq-pull-push] _(ZMQ Push/Pull Pattern)_ Whereas supported protocol are: `tcp` and `ipc`. @@ -628,7 +609,6 @@ Whereas supported protocol are: `tcp` and `ipc`. [**>>> Usage Guide**][netgear_async-doc] -     @@ -651,11 +631,10 @@ We're offering support for VidGear on [**Gitter Community Channel**](https://git   - # Donations
- PiGear + PiGear

VidGear is free and open source and will always remain so. ❤️

@@ -663,18 +642,15 @@ It is something I am doing with my own free time. But so much more needs to be d Buy Me a Coffee at ko-fi.com -     - - # Citation Here is a Bibtex entry you can use to cite this project in a publication: -[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6046843.svg)](https://doi.org/10.5281/zenodo.6046843) +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6926196.svg)](https://doi.org/10.5281/zenodo.6926196) ```BibTeX @software{vidgear, @@ -682,17 +658,20 @@ Here is a Bibtex entry you can use to cite this project in a publication: Zoe Papakipos and Christian Clauss and Christian Hollinger and + Ian Max Andolina and Vincent Boivin and + enarche-ahn and + freol35241 and Benjamin Lowe and Mickaël Schoentgen and Renaud Bouckenooghe}, - title = {abhiTronix/vidgear: VidGear v0.2.5}, - month = feb, + title = {abhiTronix/vidgear: VidGear v0.2.6}, + month = jul, year = 2022, publisher = {Zenodo}, - version = {vidgear-0.2.5}, - doi = {10.5281/zenodo.6046843}, - url = {https://doi.org/10.5281/zenodo.6046843} + version = {vidgear-0.2.6}, + doi = {10.5281/zenodo.6926196}, + url = {https://doi.org/10.5281/zenodo.6926196} } ``` @@ -700,93 +679,86 @@ Here is a Bibtex entry you can use to cite this project in a publication:   - # Copyright **Copyright © abhiTronix 2019** This library is released under the **[Apache 2.0 License][license]**. - - - -[appveyor]:https://img.shields.io/appveyor/ci/abhitronix/vidgear.svg?style=for-the-badge&logo=appveyor -[codecov]:https://img.shields.io/codecov/c/gh/abhiTronix/vidgear?logo=codecov&style=for-the-badge&token=zrES4mwVKe -[github-cli]:https://img.shields.io/github/workflow/status/abhiTronix/vidgear/Run%20Linux%20CI-Tests%20for%20vidgear?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTAgMWE5IDkgMCAwMTkgOSA5IDkgMCAwMS05IDkgOSA5IDAgMDEtOS05IDkgOSAwIDAxOS05ek0yMyAxOWE2IDYgMCAxMTAgMTIgNiA2IDAgMDEwLTEyek0yMyAzNWE2IDYgMCAxMTAgMTIgNiA2IDAgMDEwLTEyeiIgc3Ryb2tlPSJ2YXIoLS1jb2xvci1tYXJrZXRpbmctaWNvbi1wcmltYXJ5LCAjMjA4OEZGKSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00MSAzNWE2IDYgMCAxMTAgMTIgNiA2IDAgMDEwLTEyeiIgc3Ryb2tlPSJ2YXIoLS1jb2xvci1tYXJrZXRpbmctaWNvbi1zZWNvbmRhcnksICM3OUI4RkYpIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxwYXRoIGQ9Ik0yNS4wMzcgMjMuNjA3bC0zLjA3IDMuMDY1LTEuNDktMS40ODUiIHN0cm9rZT0idmFyKC0tY29sb3ItbWFya2V0aW5nLWljb24tcHJpbWFyeSwgIzIwODhGRikiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNDEgMTlhNiA2IDAgMTEwIDEyIDYgNiAwIDAxMC0xMnoiIHN0cm9rZT0idmFyKC0tY29sb3ItbWFya2V0aW5nLWljb24tcHJpbWFyeSwgIzIwODhGRikiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PHBhdGggZD0iTTQzLjAzNiAyMy42MDdsLTMuMDY5IDMuMDY1LTEuNDktMS40ODVNNyA2LjgxMmExIDEgMCAwMTEuNTMzLS44NDZsNS4xMTMgMy4yMmExIDEgMCAwMS0uMDA2IDEuNjk3bC01LjExMyAzLjE3QTEgMSAwIDAxNyAxMy4yMDNWNi44MTN6TTkgMTl2MTVjMCAzLjg2NiAzLjE3NyA3IDcgN2gxIiBzdHJva2U9InZhcigtLWNvbG9yLW1hcmtldGluZy1pY29uLXByaW1hcnksICMyMDg4RkYpIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxwYXRoIGQ9Ik0xNi45NDkgMjZhMSAxIDAgMTAwLTJ2MnpNOCAxOS4wMzVBNi45NjUgNi45NjUgMCAwMDE0Ljk2NSAyNnYtMkE0Ljk2NSA0Ljk2NSAwIDAxMTAgMTkuMDM1SDh6TTE0Ljk2NSAyNmgxLjk4NHYtMmgtMS45ODR2MnoiIGZpbGw9InZhcigtLWNvbG9yLW1hcmtldGluZy1pY29uLXByaW1hcnksICMyMDg4RkYpIi8+PHBhdGggZD0iTTI5LjA1NSAyNWg1Ljk0NCIgc3Ryb2tlPSJ2YXIoLS1jb2xvci1tYXJrZXRpbmctaWNvbi1wcmltYXJ5LCAjMjA4OEZGKSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTIxIDQwYTEgMSAwIDExLS4wMDEgMi4wMDFBMSAxIDAgMDEyMSA0MHpNMjUgNDBhMSAxIDAgMTEtLjAwMSAyLjAwMUExIDEgMCAwMTI1IDQweiIgZmlsbD0idmFyKC0tY29sb3ItbWFya2V0aW5nLWljb24tc2Vjb25kYXJ5LCAjNzlCOEZGKSIvPjxwYXRoIGQ9Ik0zNC4wMDUgNDEuMDA3bC0xLjAxMy4wMzMiIHN0cm9rZT0idmFyKC0tY29sb3ItbWFya2V0aW5nLWljb24tc2Vjb25kYXJ5LCAjNzlCOEZGKSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48L3N2Zz4= -[prs-badge]:https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABC0lEQVRYhdWVPQoCMRCFX6HY2ghaiZUXsLW0EDyBrbWtN/EUHsHTWFnYyCL4gxibVZZlZzKTnWz0QZpk5r0vIdkF/kBPAMOKeddE+CQPKoc5Yt5cTjBMdQSwDQToWgBJAn3jmhqgltapAV6E6b5U17MGGAUaUj07TficMfIBZDV6vxowBm1BP9WbSQE4o5h9IjPJmy73TEPDDxVmoZdQrQ5jRhly9Q8tgMUXkIIWn0oG4GYQfAXQzz1PGoCiQndM7b4RgJay/h7zBLT3hASgoKjamQJMreKf0gfuAGyYtXEIAKcL/Dss15iq6ohXghozLYiAMxPuACwtIT4yeQUxAaLrZwAoqGRKGk7qDSYTfYQ8LuYnAAAAAElFTkSuQmCC -[twitter-badge]:https://img.shields.io/badge/Tweet-Now-blue.svg?style=for-the-badge&logo=twitter -[azure-badge]:https://img.shields.io/azure-devops/build/abhiuna12/942b3b13-d745-49e9-8d7d-b3918ff43ac2/2/testing?logo=azure-pipelines&style=for-the-badge -[pypi-badge]:https://img.shields.io/pypi/v/vidgear.svg?style=for-the-badge&logo=pypi -[gitter-bagde]:https://img.shields.io/badge/Chat-Gitter-blueviolet.svg?style=for-the-badge&logo=gitter -[Coffee-badge]:https://abhitronix.github.io/img/vidgear/orange_img.png -[kofi-badge]:https://www.ko-fi.com/img/githubbutton_sm.svg -[black-badge]:https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge&logo=github - +[appveyor]: https://img.shields.io/appveyor/ci/abhitronix/vidgear.svg?style=for-the-badge&logo=appveyor +[codecov]: https://img.shields.io/codecov/c/github/abhiTronix/vidgear/testing?logo=codecov&style=for-the-badge +[github-cli]: https://img.shields.io/github/actions/workflow/status/abhiTronix/vidgear/.github/workflows/ci_linux.yml?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTAgMWE5IDkgMCAwMTkgOSA5IDkgMCAwMS05IDkgOSA5IDAgMDEtOS05IDkgOSAwIDAxOS05ek0yMyAxOWE2IDYgMCAxMTAgMTIgNiA2IDAgMDEwLTEyek0yMyAzNWE2IDYgMCAxMTAgMTIgNiA2IDAgMDEwLTEyeiIgc3Ryb2tlPSJ2YXIoLS1jb2xvci1tYXJrZXRpbmctaWNvbi1wcmltYXJ5LCAjMjA4OEZGKSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00MSAzNWE2IDYgMCAxMTAgMTIgNiA2IDAgMDEwLTEyeiIgc3Ryb2tlPSJ2YXIoLS1jb2xvci1tYXJrZXRpbmctaWNvbi1zZWNvbmRhcnksICM3OUI4RkYpIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxwYXRoIGQ9Ik0yNS4wMzcgMjMuNjA3bC0zLjA3IDMuMDY1LTEuNDktMS40ODUiIHN0cm9rZT0idmFyKC0tY29sb3ItbWFya2V0aW5nLWljb24tcHJpbWFyeSwgIzIwODhGRikiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNDEgMTlhNiA2IDAgMTEwIDEyIDYgNiAwIDAxMC0xMnoiIHN0cm9rZT0idmFyKC0tY29sb3ItbWFya2V0aW5nLWljb24tcHJpbWFyeSwgIzIwODhGRikiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+PHBhdGggZD0iTTQzLjAzNiAyMy42MDdsLTMuMDY5IDMuMDY1LTEuNDktMS40ODVNNyA2LjgxMmExIDEgMCAwMTEuNTMzLS44NDZsNS4xMTMgMy4yMmExIDEgMCAwMS0uMDA2IDEuNjk3bC01LjExMyAzLjE3QTEgMSAwIDAxNyAxMy4yMDNWNi44MTN6TTkgMTl2MTVjMCAzLjg2NiAzLjE3NyA3IDcgN2gxIiBzdHJva2U9InZhcigtLWNvbG9yLW1hcmtldGluZy1pY29uLXByaW1hcnksICMyMDg4RkYpIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxwYXRoIGQ9Ik0xNi45NDkgMjZhMSAxIDAgMTAwLTJ2MnpNOCAxOS4wMzVBNi45NjUgNi45NjUgMCAwMDE0Ljk2NSAyNnYtMkE0Ljk2NSA0Ljk2NSAwIDAxMTAgMTkuMDM1SDh6TTE0Ljk2NSAyNmgxLjk4NHYtMmgtMS45ODR2MnoiIGZpbGw9InZhcigtLWNvbG9yLW1hcmtldGluZy1pY29uLXByaW1hcnksICMyMDg4RkYpIi8+PHBhdGggZD0iTTI5LjA1NSAyNWg1Ljk0NCIgc3Ryb2tlPSJ2YXIoLS1jb2xvci1tYXJrZXRpbmctaWNvbi1wcmltYXJ5LCAjMjA4OEZGKSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTIxIDQwYTEgMSAwIDExLS4wMDEgMi4wMDFBMSAxIDAgMDEyMSA0MHpNMjUgNDBhMSAxIDAgMTEtLjAwMSAyLjAwMUExIDEgMCAwMTI1IDQweiIgZmlsbD0idmFyKC0tY29sb3ItbWFya2V0aW5nLWljb24tc2Vjb25kYXJ5LCAjNzlCOEZGKSIvPjxwYXRoIGQ9Ik0zNC4wMDUgNDEuMDA3bC0xLjAxMy4wMzMiIHN0cm9rZT0idmFyKC0tY29sb3ItbWFya2V0aW5nLWljb24tc2Vjb25kYXJ5LCAjNzlCOEZGKSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48L3N2Zz4= +[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABC0lEQVRYhdWVPQoCMRCFX6HY2ghaiZUXsLW0EDyBrbWtN/EUHsHTWFnYyCL4gxibVZZlZzKTnWz0QZpk5r0vIdkF/kBPAMOKeddE+CQPKoc5Yt5cTjBMdQSwDQToWgBJAn3jmhqgltapAV6E6b5U17MGGAUaUj07TficMfIBZDV6vxowBm1BP9WbSQE4o5h9IjPJmy73TEPDDxVmoZdQrQ5jRhly9Q8tgMUXkIIWn0oG4GYQfAXQzz1PGoCiQndM7b4RgJay/h7zBLT3hASgoKjamQJMreKf0gfuAGyYtXEIAKcL/Dss15iq6ohXghozLYiAMxPuACwtIT4yeQUxAaLrZwAoqGRKGk7qDSYTfYQ8LuYnAAAAAElFTkSuQmCC +[twitter-badge]: https://img.shields.io/badge/Tweet-Now-blue.svg?style=for-the-badge&logo=twitter +[azure-badge]: https://img.shields.io/azure-devops/build/abhiuna12/942b3b13-d745-49e9-8d7d-b3918ff43ac2/2/testing?logo=azure-pipelines&style=for-the-badge +[pypi-badge]: https://img.shields.io/pypi/v/vidgear.svg?style=for-the-badge&logo=pypi +[gitter-bagde]: https://img.shields.io/badge/Chat-Gitter-blueviolet.svg?style=for-the-badge&logo=gitter +[coffee-badge]: https://abhitronix.github.io/img/vidgear/orange_img.png +[kofi-badge]: https://www.ko-fi.com/img/githubbutton_sm.svg +[black-badge]: https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge&logo=github -[release]:https://github.com/abhiTronix/vidgear/releases/latest -[pypi]:https://pypi.org/project/vidgear/ -[gitter]:https://gitter.im/vidgear/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge -[twitter-intent]:https://twitter.com/intent/tweet?url=https%3A%2F%2Fabhitronix.github.io%2Fvidgear&via%20%40abhi_una12&text=Checkout%20VidGear%20-%20A%20High-Performance%20Video-Processing%20Python%20Framework.&hashtags=vidgear%20%23videoprocessing%20%23python%20%23threaded%20%23asyncio -[coffee]:https://www.buymeacoffee.com/2twOXFvlA +[release]: https://github.com/abhiTronix/vidgear/releases/latest +[pypi]: https://pypi.org/project/vidgear/ +[gitter]: https://gitter.im/vidgear/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge +[twitter-intent]: https://twitter.com/intent/tweet?url=https%3A%2F%2Fabhitronix.github.io%2Fvidgear&via%20%40abhi_una12&text=Checkout%20VidGear%20-%20A%20High-Performance%20Video-Processing%20Python%20Framework.&hashtags=vidgear%20%23videoprocessing%20%23python%20%23threaded%20%23asyncio +[coffee]: https://www.buymeacoffee.com/2twOXFvlA [kofi]: https://ko-fi.com/W7W8WTYO -[license]:https://github.com/abhiTronix/vidgear/blob/master/LICENSE -[github-flow]:https://github.com/abhiTronix/vidgear/actions?query=workflow%3A%22Run+Linux+CI-Tests+for+vidgear%22 -[azure-pipeline]:https://dev.azure.com/abhiuna12/public/_build?definitionId=2 -[app]:https://ci.appveyor.com/project/abhiTronix/vidgear -[code]:https://codecov.io/gh/abhiTronix/vidgear +[license]: https://github.com/abhiTronix/vidgear/blob/master/LICENSE +[github-flow]: https://github.com/abhiTronix/vidgear/actions?query=workflow%3A%22Run+Linux+CI-Tests+for+vidgear%22 +[azure-pipeline]: https://dev.azure.com/abhiuna12/public/_build?definitionId=2 +[app]: https://ci.appveyor.com/project/abhiTronix/vidgear +[code]: https://codecov.io/gh/abhiTronix/vidgear [btm_netgear_async]: https://abhitronix.github.io/vidgear/latest/gears/netgear_async/advanced/bidirectional_mode/ [rtvc]: https://abhitronix.github.io/vidgear/latest/gears/netgear_async/advanced/bidirectional_mode/#using-bidirectional-mode-for-video-frames-transfer - -[test-4k]:https://github.com/abhiTronix/vidgear/blob/e0843720202b0921d1c26e2ce5b11fadefbec892/vidgear/tests/benchmark_tests/test_benchmark_playback.py#L65 -[bs_script_dataset]:https://github.com/abhiTronix/vidgear/blob/testing/scripts/bash/prepare_dataset.sh - -[faq]:https://abhitronix.github.io/vidgear/latest/help/get_help/#frequently-asked-questions -[contribute]:https://abhitronix.github.io/vidgear/latest/contribution -[rstp-ex]:https://abhitronix.github.io/vidgear/latest/help/writegear_ex/#using-writegears-compression-mode-for-rstprtp-live-streaming -[doc-vidgear-purpose]:https://abhitronix.github.io/vidgear/latest/help/motivation/#why-is-vidgear-a-thing -[live-stream]:https://abhitronix.github.io/vidgear/latest/gears/writegear/compression/usage/#using-compression-mode-for-live-streaming -[live-audio-doc]:https://abhitronix.github.io/vidgear/latest/gears/writegear/compression/usage/#using-compression-mode-with-live-audio-input -[piping-live-videos]:https://abhitronix.github.io/vidgear/latest/gears/camgear/usage/#using-camgear-with-streaming-websites -[ffmpeg-doc]:https://abhitronix.github.io/vidgear/latest/gears/writegear/compression/advanced/ffmpeg_install/ -[youtube-doc]:https://abhitronix.github.io/vidgear/latest/gears/camgear/usage/#using-camgear-with-youtube-videos -[TQM-doc]:https://abhitronix.github.io/vidgear/latest/bonus/TQM/#threaded-queue-mode -[camgear-doc]:https://abhitronix.github.io/vidgear/latest/gears/camgear/overview/ -[stablizer-doc]:https://abhitronix.github.io/vidgear/latest/gears/stabilizer/overview/ -[stablizer-doc-ex]:https://abhitronix.github.io/vidgear/latest/gears/videogear/usage/#using-videogear-with-video-stabilizer-backend -[videogear-doc]:https://abhitronix.github.io/vidgear/latest/gears/videogear/overview/ -[pigear-doc]:https://abhitronix.github.io/vidgear/latest/gears/pigear/overview/ -[cm-writegear-doc]:https://abhitronix.github.io/vidgear/latest/gears/writegear/compression/overview/ -[ncm-writegear-doc]:https://abhitronix.github.io/vidgear/latest/gears/writegear/non_compression/overview/ -[screengear-doc]:https://abhitronix.github.io/vidgear/latest/gears/screengear/overview/ -[streamgear-doc]:https://abhitronix.github.io/vidgear/latest/gears/streamgear/introduction/ -[writegear-doc]:https://abhitronix.github.io/vidgear/latest/gears/writegear/introduction/ -[netgear-doc]:https://abhitronix.github.io/vidgear/latest/gears/netgear/overview/ -[webgear-doc]:https://abhitronix.github.io/vidgear/latest/gears/webgear/overview/ -[webgear_rtc-doc]:https://abhitronix.github.io/vidgear/latest/gears/webgear_rtc/overview/ -[netgear_async-doc]:https://abhitronix.github.io/vidgear/latest/gears/netgear_async/overview/ -[drop35]:https://github.com/abhiTronix/vidgear/issues/99 -[custom-command-doc]:https://abhitronix.github.io/vidgear/latest/gears/writegear/compression/advanced/cciw/ -[advanced-webgear-doc]:https://abhitronix.github.io/vidgear/latest/gears/webgear/advanced/ -[netgear_bidata_doc]:https://abhitronix.github.io/vidgear/latest/gears/netgear/advanced/bidirectional_mode/ -[netgear_compression_doc]:https://abhitronix.github.io/vidgear/latest/gears/netgear/advanced/compression/ -[netgear_security_doc]:https://abhitronix.github.io/vidgear/latest/gears/netgear/advanced/secure_mode/ -[netgear_multi_server_doc]:https://abhitronix.github.io/vidgear/latest/gears/netgear/advanced/multi_server/ -[netgear_multi_client_doc]:https://abhitronix.github.io/vidgear/latest/gears/netgear/advanced/multi_client/ -[netgear_sshtunnel_doc]:https://abhitronix.github.io/vidgear/latest/gears/netgear/advanced/ssh_tunnel/ +[test-4k]: https://github.com/abhiTronix/vidgear/blob/e0843720202b0921d1c26e2ce5b11fadefbec892/vidgear/tests/benchmark_tests/test_benchmark_playback.py#L65 +[bs_script_dataset]: https://github.com/abhiTronix/vidgear/blob/testing/scripts/bash/prepare_dataset.sh +[faq]: https://abhitronix.github.io/vidgear/latest/help/get_help/#frequently-asked-questions +[contribute]: https://abhitronix.github.io/vidgear/latest/contribution +[rtsp-ex]: https://abhitronix.github.io/vidgear/latest/help/writegear_ex/#using-writegears-compression-mode-for-rtsprtp-live-streaming +[doc-vidgear-purpose]: https://abhitronix.github.io/vidgear/latest/help/motivation/#why-is-vidgear-a-thing +[live-stream]: https://abhitronix.github.io/vidgear/latest/gears/writegear/compression/usage/#using-compression-mode-for-live-streaming +[live-audio-doc]: https://abhitronix.github.io/vidgear/latest/gears/writegear/compression/usage/#using-compression-mode-with-live-audio-input +[piping-live-videos]: https://abhitronix.github.io/vidgear/latest/gears/camgear/usage/#using-camgear-with-streaming-websites +[ffmpeg-doc]: https://abhitronix.github.io/vidgear/latest/gears/writegear/compression/advanced/ffmpeg_install/ +[youtube-doc]: https://abhitronix.github.io/vidgear/latest/gears/camgear/usage/#using-camgear-with-youtube-videos +[tqm-doc]: https://abhitronix.github.io/vidgear/latest/bonus/TQM/#threaded-queue-mode +[camgear-doc]: https://abhitronix.github.io/vidgear/latest/gears/camgear/overview/ +[stabilizer-doc]: https://abhitronix.github.io/vidgear/latest/gears/stabilizer/overview/ +[stabilizer-doc-ex]: https://abhitronix.github.io/vidgear/latest/gears/videogear/usage/#using-videogear-with-video-stabilizer-backend +[videogear-doc]: https://abhitronix.github.io/vidgear/latest/gears/videogear/overview/ +[pigear-doc]: https://abhitronix.github.io/vidgear/latest/gears/pigear/overview/ +[cm-writegear-doc]: https://abhitronix.github.io/vidgear/latest/gears/writegear/compression/overview/ +[ncm-writegear-doc]: https://abhitronix.github.io/vidgear/latest/gears/writegear/non_compression/overview/ +[screengear-doc]: https://abhitronix.github.io/vidgear/latest/gears/screengear/overview/ +[streamgear-doc]: https://abhitronix.github.io/vidgear/latest/gears/streamgear/introduction/ +[writegear-doc]: https://abhitronix.github.io/vidgear/latest/gears/writegear/introduction/ +[netgear-doc]: https://abhitronix.github.io/vidgear/latest/gears/netgear/overview/ +[webgear-doc]: https://abhitronix.github.io/vidgear/latest/gears/webgear/overview/ +[webgear_rtc-doc]: https://abhitronix.github.io/vidgear/latest/gears/webgear_rtc/overview/ +[netgear_async-doc]: https://abhitronix.github.io/vidgear/latest/gears/netgear_async/overview/ +[drop35]: https://github.com/abhiTronix/vidgear/issues/99 +[custom-command-doc]: https://abhitronix.github.io/vidgear/latest/gears/writegear/compression/advanced/cciw/ +[advanced-webgear-doc]: https://abhitronix.github.io/vidgear/latest/gears/webgear/advanced/ +[netgear_bidata_doc]: https://abhitronix.github.io/vidgear/latest/gears/netgear/advanced/bidirectional_mode/ +[netgear_compression_doc]: https://abhitronix.github.io/vidgear/latest/gears/netgear/advanced/compression/ +[netgear_security_doc]: https://abhitronix.github.io/vidgear/latest/gears/netgear/advanced/secure_mode/ +[netgear_multi_server_doc]: https://abhitronix.github.io/vidgear/latest/gears/netgear/advanced/multi_server/ +[netgear_multi_client_doc]: https://abhitronix.github.io/vidgear/latest/gears/netgear/advanced/multi_client/ +[netgear_sshtunnel_doc]: https://abhitronix.github.io/vidgear/latest/gears/netgear/advanced/ssh_tunnel/ [netgear-exm]: https://abhitronix.github.io/vidgear/latest/gears/netgear/overview/#modes-of-operation -[stabilize_webgear_doc]:https://abhitronix.github.io/vidgear/latest/gears/webgear/advanced/#using-webgear-with-real-time-video-stabilization-enabled -[netgear_Async-cs]: https://abhitronix.github.io/vidgear/latest/gears/netgear_async/usage/#using-netgear_async-with-a-custom-sourceopencv -[installation]:https://abhitronix.github.io/vidgear/latest/installation/ -[gears]:https://abhitronix.github.io/vidgear/latest/gears -[switch_from_cv]:https://abhitronix.github.io/vidgear/latest/switch_from_cv/ +[stabilize_webgear_doc]: https://abhitronix.github.io/vidgear/latest/gears/webgear/advanced/#using-webgear-with-real-time-video-stabilization-enabled +[netgear_async-cs]: https://abhitronix.github.io/vidgear/latest/gears/netgear_async/usage/#using-netgear_async-with-a-custom-sourceopencv +[installation]: https://abhitronix.github.io/vidgear/latest/installation/ +[gears]: https://abhitronix.github.io/vidgear/latest/gears +[switch_from_cv]: https://abhitronix.github.io/vidgear/latest/switch_from_cv/ [ss-mode-doc]: https://abhitronix.github.io/vidgear/latest/gears/streamgear/ssm/#overview [rtf-mode-doc]: https://abhitronix.github.io/vidgear/latest/gears/streamgear/rtfm/#overview [webgear-cs]: https://abhitronix.github.io/vidgear/latest/gears/webgear/advanced/#using-webgear-with-a-custom-sourceopencv @@ -797,41 +769,42 @@ Internal URLs -[asyncio-zmq]:https://pyzmq.readthedocs.io/en/latest/api/zmq.asyncio.html + +[asyncio-zmq]: https://pyzmq.readthedocs.io/en/latest/api/zmq.asyncio.html [uvloop]: https://github.com/MagicStack/uvloop -[streamlink]:https://streamlink.github.io/ -[aiortc]:https://aiortc.readthedocs.io/en/latest/ -[pyscreenshot]:https://github.com/ponty/pyscreenshot +[streamlink]: https://streamlink.github.io/ +[aiortc]: https://aiortc.readthedocs.io/en/latest/ +[pyscreenshot]: https://github.com/ponty/pyscreenshot [uvloop-ns]: https://github.com/MagicStack/uvloop/issues/14 -[ffmpeg]:https://www.ffmpeg.org/ +[ffmpeg]: https://www.ffmpeg.org/ [flake8]: https://flake8.pycqa.org/en/latest/ [black]: https://github.com/psf/black -[pytest]:https://docs.pytest.org/en/latest/ -[opencv-writer]:https://docs.opencv.org/master/dd/d9e/classcv_1_1VideoWriter.html#ad59c61d8881ba2b2da22cff5487465b5 -[OpenCV-windows]:https://www.learnopencv.com/install-opencv3-on-windows/ -[OpenCV-linux]:https://www.pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv/ -[OpenCV-pi]:https://www.pyimagesearch.com/2018/09/26/install-opencv-4-on-your-raspberry-pi/ -[starlette]:https://www.starlette.io/ -[uvicorn]:http://www.uvicorn.org/ -[daphne]:https://github.com/django/daphne/ -[hypercorn]:https://pgjones.gitlab.io/hypercorn/ -[prs]:http://makeapullrequest.com -[opencv]:https://github.com/opencv/opencv -[picamera]:https://github.com/waveform80/picamera -[pafy]:https://github.com/mps-youtube/pafy -[pyzmq]:https://github.com/zeromq/pyzmq -[zmq]:https://zeromq.org/ -[mss]:https://github.com/BoboTiG/python-mss -[pip]:https://pip.pypa.io/en/stable/installing/ -[opencv-vc]:https://docs.opencv.org/master/d8/dfe/classcv_1_1VideoCapture.html#a57c0e81e83e60f36c83027dc2a188e80 -[OV5647-picam]:https://github.com/techyian/MMALSharp/doc/OmniVision-OV5647-Camera-Module -[IMX219-picam]:https://github.com/techyian/MMALSharp/doc/Sony-IMX219-Camera-Module -[opencv-vw]:https://docs.opencv.org/3.4/d8/dfe/classcv_1_1VideoCapture.html -[yt_dlp]:https://github.com/yt-dlp/yt-dlp -[numpy]:https://github.com/numpy/numpy -[zmq-pair]:https://learning-0mq-with-pyzmq.readthedocs.io/en/latest/pyzmq/patterns/pair.html -[zmq-req-rep]:https://learning-0mq-with-pyzmq.readthedocs.io/en/latest/pyzmq/patterns/client_server.html -[zmq-pub-sub]:https://learning-0mq-with-pyzmq.readthedocs.io/en/latest/pyzmq/patterns/pubsub.html +[pytest]: https://docs.pytest.org/en/latest/ +[opencv-writer]: https://docs.opencv.org/master/dd/d9e/classcv_1_1VideoWriter.html#ad59c61d8881ba2b2da22cff5487465b5 +[opencv-windows]: https://www.learnopencv.com/install-opencv3-on-windows/ +[opencv-linux]: https://www.pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv/ +[opencv-pi]: https://www.pyimagesearch.com/2018/09/26/install-opencv-4-on-your-raspberry-pi/ +[starlette]: https://www.starlette.io/ +[uvicorn]: http://www.uvicorn.org/ +[daphne]: https://github.com/django/daphne/ +[hypercorn]: https://pgjones.gitlab.io/hypercorn/ +[prs]: http://makeapullrequest.com +[opencv]: https://github.com/opencv/opencv +[picamera]: https://github.com/waveform80/picamera +[pafy]: https://github.com/mps-youtube/pafy +[pyzmq]: https://github.com/zeromq/pyzmq +[zmq]: https://zeromq.org/ +[mss]: https://github.com/BoboTiG/python-mss +[pip]: https://pip.pypa.io/en/stable/installing/ +[opencv-vc]: https://docs.opencv.org/master/d8/dfe/classcv_1_1VideoCapture.html#a57c0e81e83e60f36c83027dc2a188e80 +[ov5647-picam]: https://github.com/techyian/MMALSharp/doc/OmniVision-OV5647-Camera-Module +[imx219-picam]: https://github.com/techyian/MMALSharp/doc/Sony-IMX219-Camera-Module +[opencv-vw]: https://docs.opencv.org/3.4/d8/dfe/classcv_1_1VideoCapture.html +[yt_dlp]: https://github.com/yt-dlp/yt-dlp +[numpy]: https://github.com/numpy/numpy +[zmq-pair]: https://learning-0mq-with-pyzmq.readthedocs.io/en/latest/pyzmq/patterns/pair.html +[zmq-req-rep]: https://learning-0mq-with-pyzmq.readthedocs.io/en/latest/pyzmq/patterns/client_server.html +[zmq-pub-sub]: https://learning-0mq-with-pyzmq.readthedocs.io/en/latest/pyzmq/patterns/pubsub.html [zmq-pull-push]: https://learning-0mq-with-pyzmq.readthedocs.io/en/latest/pyzmq/patterns/pushpull.html#push-pull -[picamera-setting]:https://picamera.readthedocs.io/en/release-1.13/quickstart.html -[webrtc]:https://webrtc.org/ \ No newline at end of file +[picamera-setting]: https://picamera.readthedocs.io/en/release-1.13/quickstart.html +[webrtc]: https://webrtc.org/ diff --git a/appveyor.yml b/appveyor.yml index 07464a4ad..779f0e4e6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -34,7 +34,7 @@ environment: build: off -version: '{branch}-{build}' +version: "{branch}-{build}" cache: - '%LOCALAPPDATA%\pip\Cache' @@ -45,22 +45,24 @@ branches: skip_commits: files: - - '**/*.md' - - '**/*.html' - - '**/*.js' - - '**/*.css' + - "**/*.md" + - "**/*.html" + - "**/*.js" + - "**/*.css" - docs/**/* - mkdocs.yml - README.md matrix: - fast_finish: true + fast_finish: true install: - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" - "python --version" - "python -m pip install --upgrade pip wheel" - - "python -m pip install --upgrade .[asyncio] six codecov pytest pytest-cov pytest-asyncio yt_dlp aiortc paramiko m3u8 async-asgi-testclient" + - "python -m pip install .[asyncio] six codecov httpx pytest-cov pytest-asyncio yt_dlp aiortc paramiko m3u8 async-asgi-testclient" + - "python -m pip install --upgrade deffcode" + - "python -m pip install cryptography==38.0.4" - "python -m pip install https://github.com/abhiTronix/python-mpegdash/releases/download/0.3.0-dev2/mpegdash-0.3.0.dev2-py3-none-any.whl" - cmd: chmod +x scripts/bash/prepare_dataset.sh - cmd: bash scripts/bash/prepare_dataset.sh @@ -68,5 +70,6 @@ install: test_script: - cmd: python -m pytest --verbose --capture=no --cov-report term-missing --cov=vidgear vidgear/tests/ + after_test: - - cmd: python -m codecov \ No newline at end of file + - cmd: python -m codecov \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5978a1750..28b2112b2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -14,82 +14,83 @@ # specific path build trigger: - branches: - include: - - testing - paths: - exclude: - - docs/**/* - - README.md - - mkdocs.yml - - '**/*.md' - - '**/*.html' - - '**/*.js' - - '**/*.css' + branches: + include: + - testing + paths: + exclude: + - docs/**/* + - README.md + - mkdocs.yml + - "**/*.md" + - "**/*.html" + - "**/*.js" + - "**/*.css" pr: - testing pool: - vmImage: 'macOS-latest' + vmImage: "macOS-latest" strategy: matrix: Python37: - python.version: '3.7' + python.version: "3.7" Python38: - python.version: '3.8' + python.version: "3.8" Python39: - python.version: '3.9' + python.version: "3.9" Python310: - python.version: '3.10' + python.version: "3.10" steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(python.version)' - displayName: 'Using Python $(python.version)' + - task: UsePythonVersion@0 + inputs: + versionSpec: "$(python.version)" + displayName: "Using Python $(python.version)" -- bash: | - brew install swig - brew install ffmpeg - brew reinstall openssl - brew install unzip - brew install dos2unix - brew install coreutils - dos2unix scripts/bash/prepare_dataset.sh - chmod +x scripts/bash/prepare_dataset.sh - displayName: 'Install brew dependencies' + - bash: | + brew install swig + brew install ffmpeg + brew reinstall openssl + brew install unzip + brew install dos2unix + brew install coreutils + dos2unix scripts/bash/prepare_dataset.sh + chmod +x scripts/bash/prepare_dataset.sh + displayName: "Install brew dependencies" -- bash: | - bash scripts/bash/prepare_dataset.sh - displayName: 'Prepare dataset' + - bash: | + bash scripts/bash/prepare_dataset.sh + displayName: "Prepare dataset" -- script: | - python -m pip install --upgrade pip wheel - pip install --upgrade .[asyncio] six codecov yt_dlp mpegdash paramiko m3u8 async-asgi-testclient - pip install --upgrade pytest pytest-asyncio pytest-cov pytest-azurepipelines - displayName: 'Install pip dependencies' + - script: | + python -m pip install --upgrade pip wheel + pip install --upgrade .[asyncio] six codecov yt_dlp httpx mpegdash paramiko m3u8 async-asgi-testclient + pip install --upgrade deffcode + pip install cryptography==38.0.4 + pip install --upgrade pytest pytest-asyncio pytest-cov pytest-azurepipelines + displayName: "Install pip dependencies" -- script: | - timeout 1500 pytest --verbose --cov=vidgear --cov-report=xml --cov-report=html --cov-report term-missing vidgear/tests/ || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; else echo "##vso[task.setvariable variable=exit_code]$code"; fi - displayName: 'pytest' - -- bash: | - echo "Exit Code was: $(exit_code)" - curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import - curl -Os https://uploader.codecov.io/latest/macos/codecov - curl -Os https://uploader.codecov.io/latest/macos/codecov.SHA256SUM - curl -Os https://uploader.codecov.io/latest/macos/codecov.SHA256SUM.sig - gpgv codecov.SHA256SUM.sig codecov.SHA256SUM - shasum -a 256 -c codecov.SHA256SUM - chmod +x codecov - if [ "$(exit_code)" != "124" ]; then - ./codecov -t $CODECOV_TOKEN -f coverage.xml -C $(Build.SourceVersion) -B $(Build.SourceBranch) -b $(Build.BuildNumber); - else - echo "Timeout test - Skipped Codecov!"; - fi - env: - CODECOV_TOKEN: $(TOKEN) - displayName: Upload coverage to CodeCov - \ No newline at end of file + - script: | + timeout 1500 pytest --verbose --cov=vidgear --cov-report=xml --cov-report=html --cov-report term-missing vidgear/tests/ || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; else echo "##vso[task.setvariable variable=exit_code]$code"; fi + displayName: "pytest" + + - bash: | + echo "Exit Code was: $(exit_code)" + curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import + curl -Os https://uploader.codecov.io/latest/macos/codecov + curl -Os https://uploader.codecov.io/latest/macos/codecov.SHA256SUM + curl -Os https://uploader.codecov.io/latest/macos/codecov.SHA256SUM.sig + gpgv codecov.SHA256SUM.sig codecov.SHA256SUM + shasum -a 256 -c codecov.SHA256SUM + chmod +x codecov + if [ "$(exit_code)" != "124" ]; then + ./codecov -t $CODECOV_TOKEN -f coverage.xml -C $(Build.SourceVersion) -B $(Build.SourceBranch) -b $(Build.BuildNumber); + else + echo "Timeout test - Skipped Codecov!"; + fi + env: + CODECOV_TOKEN: $(TOKEN) + displayName: Upload coverage to CodeCov diff --git a/docs/changelog.md b/docs/changelog.md index 4383d3dba..b233102b5 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -20,11 +20,192 @@ limitations under the License. # Release Notes +## v0.3.0 (2023-01-26) + +??? tip "New Features" + - [x] **WriteGear:** + * Added support for user-defined and higher than 8-bit depth input frames pixel-format. + + Added support for higher than 8-bit depth frames with datatypes of unsigned integer(`uint`) kind and element size `2`. + + Added `dtype` parameter to internal `Preprocess` method for passing input frames datatype. + + Implemented auto-calculation of input pixel-format based on number of channels in higher than 8-bit depth frames. + + Added various known working pixel-formats(based on number of channels), supported by all prominent computer vision libraries. + + Added support for up to 1-channel(`gray16-le/be`) to all the way up to 4-channels(`bgra64-le/be`) in input frames. + + Added endianness little(`le`) or big(`be`) at the suffix of pixel-format based on byte-order of input frames datatypes. + + Extended support for higher RGB 8-bit depth frames through RGB mode. + * Added support for user-defined custom input pixel-format. + + Added new `-input_pixfmt` attribute to `output_params` dictionary parameter for easily specifying custom input pixel-format. + + Added newly implemented `get_supported_pixfmts` method import for verifying user-defined input pixel-format against Installed FFmpeg supported pixel-formats. Unsupported values will be discarded. + + Implemented runtime datatype validation check, such that all input frames must have same datatype. + * Added support for Context Managers for proper handling of resources via `with` statement for allocating and releasing resources precisely. (Suggested by @sueskind) + + Implement the `__enter__()` and `__exit__()` methods. + + Added `__enter__` method that returns reference to the WriteGear Class. + + Added `__exit__` method that automatically executes `close()` for performing the cleanup operations and handling exception gracefully. + - [x] **StreamGear:** + * Added support for Context Managers for proper handling of resources via `with` statement for allocating and releasing resources precisely. (Suggested by @sueskind) + + Implement the `__enter__()` and `__exit__()` methods. + + Added `__enter__` method that returns reference to the StreamGear Class. + + Added `__exit__` method that automatically executes `close()` for performing the cleanup operations and handling exception gracefully. + - [x] **WebGear:** + * Added way to completely disable Data-Files Auto-Generation WorkFlow. + + Added new `skip_generate_webdata` boolean optional attribute(`False` by default) to completely disable Data-Files Auto-Generation WorkFlow. + + This flag enables only `/video` route for disabled Data-Files Auto-Generation WorkFlow. + + Implemented JSONResponse as placeholder response instead of Index, `404` and `500` HTML pages, when workflow is disabled. _(Note: Index HTML page will throw `404` status code.)_ + + Added necessary imports. + - [x] **Helper:** + * Added more robust implementation of validate_audio method. + + Added new more robust regex pattern for extracting audio-samplerate. + + Added new `validate_audio` method for calculating accurate bitrate(in kbps) from audio samplerate, channels, bit-depth values. + + Implemented new patterns and logic for accurately extracting audio channels and bit-depth from given metadata. + * Added support for Linux video device path _(such as `/dev/video0`)_. + - [x] **Maintenance:** + * Logging current vidgear version when vidgear APIs are called, not at import. + + Added `logcurr_vidgear_ver` helper function to facilitate logging current vidgear version, when called within a API. + + Implemented `ver_is_logged` global variable in helper to log version only once, which can modifiable with `logcurr_vidgear_ver` method only. Followed recommendation given in official python docs: https://docs.python.org/3/faq/programming.html#how-do-i-share-global-variables-across-modules + + Current version can only be logged by VidGear APIs with the logging turned on _(i.e. `logging=True`)_. + - [x] **Docs:** + * Added new WriteGear Bonus Example: + + Added "Using WriteGear's Compression Mode with `v4l2loopback` Virtual Cameras bonus python example. + + Added related prerequisites and dependencies for creating `v4l2loopback` Virtual Cameras on Linux machines. + + Added both With/Without-Audio cases for "Using WriteGear's Compression Mode for YouTube-Live Streaming". + * Added `content.code.copy` and `content.tabs.link` features. + * Added docs related to `skip_generate_webdata` optional attribute. + * Added feedback features to mkdocs.yml. + * Added `404.html` static template to `mkdocs.yml`. + - [x] **CI:** + * Added v4l2loopback support for testing `/dev/video0` device on Linux machines. + * Added test cases for newer implementation of `validate_audio` method. + * Added `test_skip_generate_webdata` to test `skip_generate_webdata` optional attribute. + * Added tests for user-defined and higher than 8-bit depth input frames pixel-format. + + +??? success "Updates/Improvements" + - [x] WriteGear: + * Completely revamped code structure and comments. + + Updated comments, description, and logging messages to more sensible and developer friendly. + + Implemented operator short-circuiting to cleanup code as much as possible. + + Renamed `startFFmpeg_Process` internal class method to `start_FFProcess`. + + Renamed `Preprocess` internal class method to `PreprocessFFParams`. + + Renamed `startCV_Process` internal class method to `start_CVProcess`. + + Renamed `initiate` internal class parameter to `initiate_process`. + + Renamed `force_termination` internal class parameter to `forced_termination`. + + Enabled `output_params` parameters logging in both modes. + + Improved `compression` and `logging` parameters boolean value handling. + + Impelemented `stdout` closing to cleanup pipeline before terminating. + - [x] Helper: + * Updated `validate_audio` method with improved and more robust regex patterns for identifying audio bitrate in ay audio file. + - [x] Setup.py: + * Bumped version to `0.3.0`. + * Replaced `>=` comparsion operator with more flexible `~=`. + * Replaced `distutils.version.LooseVersion` with `pkg_resources.parse_version`. + - [x] Maintenance: + * Replaced depreciated `LooseVersion` with `parse_version`. + * Updated `Retry` package to be imported from `requests.adapters`. + * Moved terminal and python code text area to Question GitHub Form Schema. + * Removed unnecessary imports. + * Removed redundant code. + * Improved logging messages. + * Updated code comments. + * Updated method descriptions. + * Refactored code. + * Increased coverage. + - [x] Bash Script: + * Updated FFmpeg Static Binaries links to latest date/version tag to `12-07-2022`. + * Removed depreciated binaries download links and code. + - [x] Docs: + * Replaced all `raw.githubusercontent.com` GIF URLs with `user-images.githubusercontent.com`. + * Reformatted `custom.css` and added missing comments. + * Updated sponsor block. + * Enabled Code Highlights. + * Updated announcement bar. + * Updated `changelog.md`. + * Reduced `webgear_rtc.gif` size. + * Updated Zenodo badge and the BibTeX entry. + - [x] CI: + * Added more flexible formats to `return_testvideo_path` function. + * Updated `test_write` test for higher than 8-bit depth input frames pixel-format in WriteGear's Compression Mode. + * Updated `actions/checkout` to `v3`. + * Updated `actions/setup-python` to `v4`. + * Updated `codecov/codecov-action` to `v3`. + * Moved `test_colorspaces` test to CamGear tests. + * Added deffcode library import. + * Re-stuctured yaml code. + +??? danger "Breaking Updates/Changes" + - [ ] WriteGear: + * Renamed `output_filename` string parameter to `output`. + + Since WriteGear API accepts all sorts of streams _(such as valid filename/path/URL)_ for encoding, thereby changing parameter name to `output` will be more true to its purpose. + + Renaming `output_filename` to `output` in WriteGear API will also help user to not accidentally assume WriteGear supports only encoding of video files. + + It matches the `output` parameter in StreamGear which basically does the same thing. + * Renamed `cmd` parameter in `execute_ffmpeg_cmd()` class method to more sensible `command`. + * `ValueError` will be raised if datatype of input frames mismatches Writegear API + +??? bug "Bug-fixes" + - [x] Camgear: + * Fixed `CamGear.read()` blocked unnecessarily. + + 💬 When `THREADED_QUEUE_MODE` is enabled `CamGear.read()` blocks for an excessive duration when attempting to read past the end of a stream. + + Added `None` frame to the queue at the end to signal we're done. + + Added `terminate` Event check before continuing. + * Fixed deadlock on exit. + + 💬 The deadlock is due to `self.__queue.get(timeout=self.__thread_timeout)` line in `read()` method, which still waits for timeout(thread_timeout) to happen when main `update()` thread was already terminated on exit and queue was empty. Since there was no way to signal queue that stream is already ended, the blocking `queue.get()` keeps on waiting until timeout occurs. + + The solution was to signal `queue.get()` that stream is already ended by putting `None` in queue on exiting the main `update()` thread. + - [x] ScreenGear: + * Fixed `ScreenGear.read()` blocked during cold startup. + + 💬 During startup, `ScreenGear.read()` doesn't checks if queue is empty before continuing. + - [x] WriteGear: + * Fixed gstpipeline_mode not activating when wrongly assuming `output` value as valid path. + * Fixed name 'compression' is not defined bug. + * Fixed `AttributeError`. + - [x] Helper: + * Fixed `fltp` keyword in regex pattern causing non-ftlp streams to be not recognized. + * Fixed response.headers returning `content-length` as Nonetype since it may not necessarily have the Content-Legth header set. + + Reason: The response from gitlab.com contains a Transfer-Encoding field as `'Transfer-Encoding': 'chunked'`, which means data is sent in a series of chunks, so the Content-Length header is emitted. More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding#Directives + * Fixed Linux video device paths still not working. + + Moved `helper.py` logic to WriteGear and StreamGear APIs resp. + * Fixed KeyError for empty metadata. + - [x] Setup: + * Pinned `pyzmq==24.0.1` working version. + * Removed redundant patch for the issue. + - [x] Maintaince: + * Fixed missing pkg name `import_dependency_safe` functions calls. + - [x] Bash Script: + * Fixed gstreamer installation. + - [x] CI: + * Fixed missing v4l2loopback apt dependency on Linux envs. + * Added fix for RTCPeerConnection fails to create RTCDtlsTransport (Related issue: aiortc/aiortc#804) + + Pinned `cryptography==38.0.4` in dependencies. + * Pinned Linux image to `ubuntu-20.04` in github actions. + * Fixed No module named 'httpx' bug. + + Added `httpx` library import. + * Fixed F821 undefined name bug. + * Fixed Gstreamer bug. + - [x] Docs: + * Fixed hyperlinks to new GitHub's form schemas. + * Fixed non-rendering images in README.md + + Replaced all relative image/gifs paths with absolute URLs in README.md. + * Fixed badges/shields#8671 badge issue in README.md + * Fixed GitLab CDN links throwing blocked by CORS policy bug. + + Replaced gitlab GitHack CDN links with with bitbucket. + * Fixed DASH playback failing by setting the `maxAttempts` to Infinity. + * Removed `x-sign` glow-text effect CSS. + * Fixed several typos (suggested by @timgates42) + * Fixed coverage badge. + +??? question "Pull Requests" + * PR #346 + * PR #348 + * PR #349 + * PR #350 + * PR #351 + +  + +  + ## v0.2.6 (2022-07-05) ??? tip "New Features" - [x] **Docs:** - * Added new bonus example for RSTP/RTP Live-Streaming using WriteGear's Compression Mode. + * Added new bonus example for RTSP/RTP Live-Streaming using WriteGear's Compression Mode. * Added "How to resolve zmq.error.ZMQError" FAQ for NetGear API.(PR by @iandol) * Added new ko-fi button to README.md * Added new contributors block to changelog.md @@ -72,7 +253,7 @@ limitations under the License. + Fixed debug logs even when `logging=False` in StreamGear's Real-time Mode. (patch suggested by @enarche-ahn) + Added length check to `-video_source` attribute to correctly infers it as empty(or invalid). - [x] CI: - * Xfailed RSTP CamGear CI test. + * Xfailed RTSP CamGear CI test. * Fixed pinned version syntax bug in docs_deployer workflow. * Fixed typos in Github forms and its context. * Added missing dependency. @@ -764,7 +945,7 @@ limitations under the License. * Fixed bug with `create_blank_frame` that throws error with gray frames: + Implemented automatic output channel correction inside `create_blank_frame` function. + Extended automatic output channel correction support to asyncio package. - * Implemented `RSTP` protocol validation as _demuxer_, since it's not a protocol but a demuxer. + * Implemented `RTSP` protocol validation as _demuxer_, since it's not a protocol but a demuxer. * Removed redundant `logger_handler`, `mkdir_safe`, `retrieve_best_interpolation`, `capPropId` helper functions from asyncio package. Relatively imported helper functions from non-asyncio package. * Removed unused `aiohttp` dependency. * Removed `asctime` formatting from logging. @@ -1020,7 +1201,7 @@ limitations under the License. * Update Tests docs and other minor tweaks to increase overall coverage. * Enabled debugging and disabled exit 1 on error in azure pipeline. * Removed redundant benchmark tests. - - [x] Helper: Added missing RSTP URL scheme to `is_valid_url` method. + - [x] Helper: Added missing RTSP URL scheme to `is_valid_url` method. - [x] NetGear_Async: Added fix for uvloop only supporting python>=3.7 legacies. - [x] Extended WebGear's Video-Handler scope to `https`. - [x] CI: Remove all redundant 32-bit Tests from Appveyor: diff --git a/docs/contribution/issue.md b/docs/contribution/issue.md index 18571fc53..78dc78f81 100644 --- a/docs/contribution/issue.md +++ b/docs/contribution/issue.md @@ -51,6 +51,6 @@ If you've found a new bug or you've come up with some new feature which can impr * Add a brief but descriptive title for your issue. * Keep the issue phrasing in context of the problem. * Attach source-code/screenshots if you have one. -* Finally, raise it by choosing the appropriate Issue Template: [Bug report](https://github.com/abhiTronix/vidgear/issues/new?labels=issue%3A+bug&template=bug_report.md), [Proposal](https://github.com/abhiTronix/vidgear/issues/new?labels=issue%3A+proposal&template=proposal.md), [Question](https://github.com/abhiTronix/vidgear/issues/new?labels=issue%3A+question&template=question.md). +* Finally, raise it by choosing the appropriate Issue Template: [**Bug report 🐛**](https://github.com/abhiTronix/vidgear/issues/new?assignees=abhiTronix&labels=BUG+%3Abug%3A%2CNEED+TRIAGE+%3Apolice_car%3A&template=bug_report.yaml&title=%5BBug%5D%3A+), [Proposal 💡](https://github.com/abhiTronix/vidgear/issues/new?assignees=&labels=PROPOSAL+%3Aenvelope_with_arrow%3A&template=proposal.yaml&title=%5BProposal%5D%3A+), [Question ❔](https://github.com/abhiTronix/vidgear/issues/new?assignees=&labels=QUESTION+%3Aquestion%3A&template=question.yaml&title=%5BQuestion%5D%3A+).   \ No newline at end of file diff --git a/docs/gears/camgear/overview.md b/docs/gears/camgear/overview.md index 9beec3efd..b7cdadbed 100644 --- a/docs/gears/camgear/overview.md +++ b/docs/gears/camgear/overview.md @@ -27,7 +27,7 @@ limitations under the License. ## Overview -> CamGear supports a diverse range of video streams which can handle/control video stream almost any IP/USB Cameras, multimedia video file format ([_upto 4k tested_](https://github.com/abhiTronix/vidgear/blob/62f32ad6663c871ec6aa4890ca1b55cd1286511a/vidgear/tests/benchmark_tests/test_benchmark_playback.py#L31-L71)), any network stream URL such as `http(s), rtp, rstp, rtmp, mms, etc.` In addition to this, it also supports [Gstreamer's RAW pipelines](https://gstreamer.freedesktop.org/documentation/frequently-asked-questions/using.html) and various live video streaming sites like YouTube, Twitch, Dailymotion etc. +> CamGear supports a diverse range of video streams which can handle/control video stream almost any IP/USB Cameras, multimedia video file format ([_upto 4k tested_](https://github.com/abhiTronix/vidgear/blob/62f32ad6663c871ec6aa4890ca1b55cd1286511a/vidgear/tests/benchmark_tests/test_benchmark_playback.py#L31-L71)), any network stream URL such as `http(s), rtp, rtsp, rtmp, mms, etc.` In addition to this, it also supports [Gstreamer's RAW pipelines](https://gstreamer.freedesktop.org/documentation/frequently-asked-questions/using.html) and various live video streaming sites like YouTube, Twitch, Dailymotion etc. CamGear API provides a flexible, high-level multi-threaded wrapper around OpenCV's *[VideoCapture API](https://docs.opencv.org/master/d8/dfe/classcv_1_1VideoCapture.html#a57c0e81e83e60f36c83027dc2a188e80)* with direct access to almost all of its available [*parameters*](../advanced/source_params/). It relies on [**Threaded Queue mode**](../../../bonus/TQM/) for threaded, error-free and synchronized frame handling. diff --git a/docs/gears/camgear/params.md b/docs/gears/camgear/params.md index 3fc42a947..398494562 100644 --- a/docs/gears/camgear/params.md +++ b/docs/gears/camgear/params.md @@ -63,7 +63,7 @@ Its valid input can be one of the following: CamGear(source='https://www.twitch.tv/shroud', stream_mode=True) ``` -- [x] **Network Address (*string*):** _Valid (`http(s)`, `rtp`, `rstp`, `rtmp`, `mms`, etc.) incoming network stream address such as `'rtsp://192.168.31.163:554/'` as input:_ +- [x] **Network Address (*string*):** _Valid (`http(s)`, `rtp`, `rtsp`, `rtmp`, `mms`, etc.) incoming network stream address such as `'rtsp://192.168.31.163:554/'` as input:_ ```python CamGear(source='rtsp://192.168.31.163:554/') diff --git a/docs/gears/netgear/advanced/bidirectional_mode.md b/docs/gears/netgear/advanced/bidirectional_mode.md index e6b2a1ef0..dfb99fd5f 100644 --- a/docs/gears/netgear/advanced/bidirectional_mode.md +++ b/docs/gears/netgear/advanced/bidirectional_mode.md @@ -261,7 +261,7 @@ while True: # {do something with the extracted frame and data here} - # lets print recieved server data + # lets print received server data if not (server_data is None): print(server_data) diff --git a/docs/gears/netgear/advanced/multi_client.md b/docs/gears/netgear/advanced/multi_client.md index d25b50d71..7f1ea5fba 100644 --- a/docs/gears/netgear/advanced/multi_client.md +++ b/docs/gears/netgear/advanced/multi_client.md @@ -85,7 +85,7 @@ The supported patterns for this mode are Publish/Subscribe (`zmq.PUB/zmq.SUB`) a ### Bare-Minimum Usage -In this example, we will capturing live video-frames from a source _(a.k.a Server)_ with a webcam connected to it. Afterwards, those captured frame will be sent over the network to two independent system _(a.k.a Clients)_ using this Multi-Clients Mode in NetGear API. Finally, both Clients will be displaying recieved frames in Output Windows in real time. +In this example, we will capturing live video-frames from a source _(a.k.a Server)_ with a webcam connected to it. Afterwards, those captured frame will be sent over the network to two independent system _(a.k.a Clients)_ using this Multi-Clients Mode in NetGear API. Finally, both Clients will be displaying received frames in Output Windows in real time. !!! tip "This example is useful for building applications like Real-Time Video Broadcasting to multiple clients in local network." @@ -145,7 +145,7 @@ while True: # send frame and also receive data from Client(s) recv_data = server.send(frame) - # check if valid data recieved + # check if valid data received if not (recv_data is None): # extract unique port address and its respective data unique_address, data = recv_data @@ -343,7 +343,7 @@ while True: # send frame and also receive data from Client(s) recv_data = server.send(frame) - # check if valid data recieved + # check if valid data received if not (recv_data is None): # extract unique port address and its respective data unique_address, data = recv_data @@ -555,7 +555,7 @@ while True: # send frame and also receive data from Client(s) recv_data = server.send(frame) - # check if valid data recieved + # check if valid data received if not (recv_data is None): # extract unique port address and its respective data unique_address, data = recv_data @@ -786,7 +786,7 @@ while True: # send frame & data and also receive data from Client(s) recv_data = server.send(frame, message=target_data) # (1) - # check if valid data recieved + # check if valid data received if not (recv_data is None): # extract unique port address and its respective data unique_address, data = recv_data diff --git a/docs/gears/netgear/advanced/multi_server.md b/docs/gears/netgear/advanced/multi_server.md index 5a70ea1f1..761ad0823 100644 --- a/docs/gears/netgear/advanced/multi_server.md +++ b/docs/gears/netgear/advanced/multi_server.md @@ -76,7 +76,7 @@ The supported patterns for this mode are Publish/Subscribe (`zmq.PUB/zmq.SUB`) a * All of Servers will be transferring frames to a single Client system at the same time, which will be displaying received frames as a live montage _(multiple frames concatenated together)_. - * For building Frames Montage at Client's end, We are going to use `imutils` python library function to build montages, by concatenating together frames recieved from different servers. Therefore, Kindly install this library with `pip install imutils` terminal command. + * For building Frames Montage at Client's end, We are going to use `imutils` python library function to build montages, by concatenating together frames received from different servers. Therefore, Kindly install this library with `pip install imutils` terminal command.   diff --git a/docs/gears/netgear_async/params.md b/docs/gears/netgear_async/params.md index 52589a90c..2abdcbf1f 100644 --- a/docs/gears/netgear_async/params.md +++ b/docs/gears/netgear_async/params.md @@ -285,7 +285,7 @@ Its valid input can be one of the following: CamGear(source='https://www.twitch.tv/shroud', stream_mode=True) ``` -- [x] **Network Address (*string*):** _Valid (`http(s)`, `rtp`, `rstp`, `rtmp`, `mms`, etc.) incoming network stream address such as `'rtsp://192.168.31.163:554/'` as input:_ +- [x] **Network Address (*string*):** _Valid (`http(s)`, `rtp`, `rtsp`, `rtmp`, `mms`, etc.) incoming network stream address such as `'rtsp://192.168.31.163:554/'` as input:_ ```python NetGear_Async(source='rtsp://192.168.31.163:554/') diff --git a/docs/gears/netgear_async/usage.md b/docs/gears/netgear_async/usage.md index db6654961..fb31159de 100644 --- a/docs/gears/netgear_async/usage.md +++ b/docs/gears/netgear_async/usage.md @@ -392,7 +392,7 @@ import cv2, asyncio # define and launch Client with `receive_mode=True` client = NetGear_Async(receive_mode=True).launch() # Define writer with output filename 'Output.mp4' -writer = WriteGear(output_filename="Output.mp4", logging=True) +writer = WriteGear(output="Output.mp4", logging=True) # Create a async function where you want to show/manipulate your received frames diff --git a/docs/gears/pigear/usage.md b/docs/gears/pigear/usage.md index 2eb67e987..69621a168 100644 --- a/docs/gears/pigear/usage.md +++ b/docs/gears/pigear/usage.md @@ -236,7 +236,7 @@ output_params = {"-vcodec": "libx264", "-crf": 0, "-preset": "fast"} stream = PiGear(resolution=(640, 480), framerate=60, logging=True, **options).start() # Define writer with defined parameters and suitable output filename for e.g. `Output.mp4` -writer = WriteGear(output_filename="Output.mp4", logging=True, **output_params) +writer = WriteGear(output="Output.mp4", logging=True, **output_params) # loop over while True: diff --git a/docs/gears/screengear/usage.md b/docs/gears/screengear/usage.md index e52dc1ad9..9ce8d7ca5 100644 --- a/docs/gears/screengear/usage.md +++ b/docs/gears/screengear/usage.md @@ -299,7 +299,7 @@ output_params = {"-vcodec": "libx264", "-crf": 0, "-preset": "fast"} stream = ScreenGear(monitor=1, logging=True, **options).start() # Define writer with defined parameters and suitable output filename for e.g. `Output.mp4` -writer = WriteGear(output_filename="Output.mp4", logging=True, **output_params) +writer = WriteGear(output="Output.mp4", logging=True, **output_params) # loop over while True: diff --git a/docs/gears/stabilizer/usage.md b/docs/gears/stabilizer/usage.md index 00e7b7389..c11233a53 100644 --- a/docs/gears/stabilizer/usage.md +++ b/docs/gears/stabilizer/usage.md @@ -222,7 +222,7 @@ stream = CamGear(source="unstabilized_stream.mp4").start() stab = Stabilizer() # Define writer with default parameters and suitable output filename for e.g. `Output.mp4` -writer = WriteGear(output_filename="Output.mp4") +writer = WriteGear(output="Output.mp4") # loop over while True: diff --git a/docs/gears/streamgear/rtfm/usage.md b/docs/gears/streamgear/rtfm/usage.md index e3d2aec09..b57656fc5 100644 --- a/docs/gears/streamgear/rtfm/usage.md +++ b/docs/gears/streamgear/rtfm/usage.md @@ -971,7 +971,7 @@ The complete example is as follows: - [x] **Identify Sound Card:** Then, You can locate your soundcard using `avfoundation` as follows: ```sh - ffmpeg -f qtkit -list_devices true -i "" + ffmpeg -f avfoundation -list_devices true -i "" ffmpeg version N-45279-g6b86dd5... --enable-runtime-cpudetect libavutil 51. 74.100 / 51. 74.100 libavcodec 54. 65.100 / 54. 65.100 diff --git a/docs/gears/videogear/params.md b/docs/gears/videogear/params.md index efbcd1cc9..fc5b3a5f0 100644 --- a/docs/gears/videogear/params.md +++ b/docs/gears/videogear/params.md @@ -151,7 +151,7 @@ Its valid input can be one of the following: CamGear(source='https://www.twitch.tv/shroud', stream_mode=True) ``` -- [x] **Network Address (*string*):** _Valid (`http(s)`, `rtp`, `rstp`, `rtmp`, `mms`, etc.) incoming network stream address such as `'rtsp://192.168.31.163:554/'` as input:_ +- [x] **Network Address (*string*):** _Valid (`http(s)`, `rtp`, `rtsp`, `rtmp`, `mms`, etc.) incoming network stream address such as `'rtsp://192.168.31.163:554/'` as input:_ ```python VideoGear(source='rtsp://192.168.31.163:554/') diff --git a/docs/gears/webgear/overview.md b/docs/gears/webgear/overview.md index 7ef43c517..881cfe9bc 100644 --- a/docs/gears/webgear/overview.md +++ b/docs/gears/webgear/overview.md @@ -18,7 +18,7 @@ limitations under the License. =============================================== --> -# WebGear API +# WebGear API
WebGear in action! @@ -27,9 +27,9 @@ limitations under the License. ## Overview -> *WebGear is a powerful [ASGI](https://asgi.readthedocs.io/en/latest/) Video-Broadcaster API ideal for transmitting [Motion-JPEG](https://en.wikipedia.org/wiki/Motion_JPEG)-frames from a single source to multiple recipients via the browser.* +> _WebGear is a powerful [ASGI](https://asgi.readthedocs.io/en/latest/) Video-Broadcaster API ideal for transmitting [Motion-JPEG](https://en.wikipedia.org/wiki/Motion_JPEG)-frames from a single source to multiple recipients via the browser._ -WebGear API works on [**Starlette**](https://www.starlette.io/)'s ASGI application and provides a highly extensible and flexible async wrapper around its complete framework. WebGear can flexibly interact with Starlette's ecosystem of shared middleware, mountable applications, [Response classes](https://www.starlette.io/responses/), [Routing tables](https://www.starlette.io/routing/), [Static Files](https://www.starlette.io/staticfiles/), [Templating engine(with Jinja2)](https://www.starlette.io/templates/), etc. +WebGear API works on [**Starlette**](https://www.starlette.io/)'s ASGI application and provides a highly extensible and flexible async wrapper around its complete framework. WebGear can flexibly interact with Starlette's ecosystem of shared middleware, mountable applications, [Response classes](https://www.starlette.io/responses/), [Routing tables](https://www.starlette.io/routing/), [Static Files](https://www.starlette.io/staticfiles/), [Templating engine(with Jinja2)](https://www.starlette.io/templates/), etc. WebGear API uses an intraframe-only compression scheme under the hood where the sequence of video-frames are first encoded as JPEG-DIB (JPEG with Device-Independent Bit compression) and then streamed over HTTP using Starlette's Multipart [Streaming Response](https://www.starlette.io/responses/#streamingresponse) and a [Uvicorn](https://www.uvicorn.org/#quickstart) ASGI Server. This method imposes lower processing and memory requirements, but the quality is not the best, since JPEG compression is not very efficient for motion video. @@ -39,56 +39,60 @@ In layman's terms, WebGear acts as a powerful ==**Video Broadcaster**== that tra ## Data-Files Auto-Generation WorkFlow for WebGear -On initializing WebGear API, it automatically checks for three critical **data files**(i.e `index.html`, `404.html` & `500.html`) inside the `templates` folder of the `webgear` directory at the [*default location*](#default-location) which gives rise to the following two possible scenario: +??? tip "Disabling Auto-Generation process in WebGear" + + Starting with vidgear `v0.3.0`, you can now completely disable Auto-Generation process in WebGear API using [`skip_generate_webdata`](../params/#webgear-specific-attributes) dictionary boolean attribute. When `{skip_generate_webdata:True}`, no default data files will be downloaded or validated during initialization. + + !!! warning "Only `/video` route is available when `{skip_generate_webdata:True}` in WebGear API. All other default routes will be JSONResponses with `404`/`500` status codes." + +On initializing WebGear API, it automatically checks for three critical **data files**(i.e `index.html`, `404.html` & `500.html`) inside the `templates` folder of the `webgear` directory at the [_default location_](#default-location) which gives rise to the following two possible scenario: - [x] **If data-files found:** it will proceed normally for instantiating the Starlette application. - [ ] **If data-files not found:** it will trigger the [**Auto-Generation process**](#auto-generation-process) ### Default Location -* A _default location_ is the path of the directory where data files/folders are downloaded/generated/saved. -* By default, the `.vidgear` the folder at the home directory of your machine _(for e.g `/home/foo/.vidgear` on Linux)_ serves as the _default location_. -* But you can also use WebGear's [`custom_data_location`](../params/#webgear-specific-attributes) dictionary attribute to change/alter *default location* path to somewhere else. +- A _default location_ is the path of the directory where data files/folders are downloaded/generated/saved. +- By default, the `.vidgear` the folder at the home directory of your machine _(for e.g `/home/foo/.vidgear` on Linux)_ serves as the _default location_. +- But you can also use WebGear's [`custom_data_location`](../params/#webgear-specific-attributes) dictionary attribute to change/alter _default location_ path to somewhere else. !!! tip - You can set [`logging=True`](../params/#logging) during initialization, for easily identifying the selected _default location_, which will be something like this _(on a Linux machine)_: + You can set [`logging=True`](../params/#logging) during initialization, for easily identifying the selected _default location_, which will be something like this _(on a Linux machine)_ - ```sh - WebGear :: DEBUG :: `/home/foo/.vidgear` is the default location for saving WebGear data-files. - ``` + ```sh + WebGear :: DEBUG :: `/home/foo/.vidgear` is the default location for saving WebGear data-files. + ``` ### Auto-Generation process !!! info - * You can also force trigger the Auto-generation process to overwrite existing data-files using [`overwrite_default_files`](../params/#webgear-specific-attributes) dictionary attribute. Remember, only downloaded default data files(given above) will be overwritten in this process but any other file/folder will NOT be affected. + * You can also force trigger the Auto-generation process to overwrite existing data-files using [`overwrite_default_files`](../params/#webgear-specific-attributes) dictionary attribute. Remember, only downloaded default data files(given above) will be overwritten in this process but any other file/folder will NOT be affected. - * It is advised to enable logging(`logging=True`) on the first run for easily identifying any runtime errors + * It is advised to enable logging(`logging=True`) on the first run for easily identifying any runtime errors - -* On triggering this process, WebGear API creates `webgear` directory, and `templates` and `static` folders inside along with `js`, `css`, `img` sub-folders at the assigned [*default location*](#default-location). -* Thereby at this [*default location*](#default-location), the necessary default data files will be downloaded from a dedicated [**Github Server**](https://github.com/abhiTronix/vidgear-vitals) inside respective folders in the following order: +- On triggering this process, WebGear API creates `webgear` directory, and `templates` and `static` folders inside along with `js`, `css`, `img` sub-folders at the assigned [_default location_](#default-location). +- Thereby at this [_default location_](#default-location), the necessary default data files will be downloaded from a dedicated [**Github Server**](https://github.com/abhiTronix/vidgear-vitals) inside respective folders in the following order: ```sh - .vidgear - └── webgear - ├── static - │   ├── css - │   │   └── custom.css - │   ├── img - │   │   └── favicon-32x32.png - │   └── js - │   └── custom.js - └── templates - ├── 404.html - ├── 500.html - ├── base.html - └── index.html - 6 directories, 7 files + .vidgear + └── webgear + ├── static + │   ├── css + │   │   └── custom.css + │   ├── img + │   │   └── favicon-32x32.png + │   └── js + │   └── custom.js + └── templates + ├── 404.html + ├── 500.html + ├── base.html + └── index.html + 6 directories, 7 files ``` -* Finally these downloaded files thereby are verified for errors and API proceeds for instantiating the Starlette application normally. - +- Finally these downloaded files thereby are verified for errors and API proceeds for instantiating the Starlette application normally.   @@ -108,32 +112,30 @@ from vidgear.gears.asyncio import WebGear ## WebGear's Default Template -??? new "New in v0.2.1" - New Standalone **WebGear's Default Theme** was added in `v0.2.1`. +??? new "New in v0.2.1" +New Standalone **WebGear's Default Theme** was added in `v0.2.1`. The WebGear API by default uses simple & elegant [**WebGear's Default Theme**](https://github.com/abhiTronix/vidgear-vitals#webgear-default-theme) which looks like something as follows: ### Index.html -*Can be accessed by visiting WebGear app server, running at http://localhost:8000/:* +_Can be accessed by visiting WebGear app server, running at http://localhost:8000/:_

WebGear default Index page

- ### 404.html -*Appears when respective URL is not found, for example http://localhost:8000/ok:* +_Appears when respective URL is not found, for example http://localhost:8000/ok:_

WebGear default 404 page

- ### 500.html -*Appears when an API Error is encountered:* +_Appears when an API Error is encountered:_ !!! warning "If [`logging`](../params/#logging) is enabled and an error occurs, then instead of displaying this 500 handler, WebGear will respond with a traceback response." @@ -151,7 +153,6 @@ The WebGear API by default uses simple & elegant [**WebGear's Default Theme**](h !!! example "After going through WebGear Usage Examples, Checkout more bonus examples [here ➶](../../../help/webgear_ex/)" - ## Parameters
@@ -164,11 +165,10 @@ The WebGear API by default uses simple & elegant [**WebGear's Default Theme**](h See here 🚀
- ## FAQs
See here 🚀
-  \ No newline at end of file +  diff --git a/docs/gears/webgear/params.md b/docs/gears/webgear/params.md index 3d0fe3aa9..25a46ca7e 100644 --- a/docs/gears/webgear/params.md +++ b/docs/gears/webgear/params.md @@ -134,7 +134,7 @@ This parameter can be used to pass user-defined parameter to WebGear API by form WebGear(logging=True, **options) ``` -* **`enable_infinite_frames`** _(boolean)_ : Can be used to continue streaming _(instead of terminating immediately)_ with emulated blank frames with text "No Input", whenever the input source disconnects. Its default value is `False`. Its usage is as follows +* **`enable_infinite_frames`** _(boolean)_ : Can be used to continue streaming _(instead of terminating immediately)_ with emulated blank frames with text "No Input", whenever the input source disconnects. Its default value is `False`. Its usage is as follows: ??? new "New in v0.2.1" `enable_infinite_frames` attribute was added in `v0.2.1`. @@ -146,6 +146,18 @@ This parameter can be used to pass user-defined parameter to WebGear API by form WebGear(logging=True, **options) ``` +* **`skip_generate_webdata`** _(boolean)_ : Can be used to completely disable Data-Files Auto-Generation WorkFlow in WebGear API, and thereby no default data files will be downloaded or validated during its initialization. Its default value is `False`. Its usage is as follows: + + ??? new "New in v0.3.0" + `skip_generate_webdata` attribute was added in `v0.3.0`. + + ```python + # completely disable Data-Files Auto-Generation WorkFlow + options = {"skip_generate_webdata": True} + # assign it + WebGear(logging=True, **options) + ``` +     @@ -255,7 +267,7 @@ Its valid input can be one of the following: WebGear(source='https://www.twitch.tv/shroud', stream_mode=True) ``` -- [x] **Network Address (*string*):** _Valid (`http(s)`, `rtp`, `rstp`, `rtmp`, `mms`, etc.) incoming network stream address such as `'rtsp://192.168.31.163:554/'` as input:_ +- [x] **Network Address (*string*):** _Valid (`http(s)`, `rtp`, `rtsp`, `rtmp`, `mms`, etc.) incoming network stream address such as `'rtsp://192.168.31.163:554/'` as input:_ ```python WebGear(source='rtsp://192.168.31.163:554/') diff --git a/docs/gears/webgear_rtc/params.md b/docs/gears/webgear_rtc/params.md index 1cb24e228..8abfaa666 100644 --- a/docs/gears/webgear_rtc/params.md +++ b/docs/gears/webgear_rtc/params.md @@ -249,7 +249,7 @@ Its valid input can be one of the following: CamGear(source='https://www.twitch.tv/shroud', stream_mode=True) ``` -- [x] **Network Address (*string*):** _Valid (`http(s)`, `rtp`, `rstp`, `rtmp`, `mms`, etc.) incoming network stream address such as `'rtsp://192.168.31.163:554/'` as input:_ +- [x] **Network Address (*string*):** _Valid (`http(s)`, `rtp`, `rtsp`, `rtmp`, `mms`, etc.) incoming network stream address such as `'rtsp://192.168.31.163:554/'` as input:_ ```python WebGear_RTC(source='rtsp://192.168.31.163:554/') diff --git a/docs/gears/writegear/compression/advanced/cciw.md b/docs/gears/writegear/compression/advanced/cciw.md index 03b1445b1..9580e43da 100644 --- a/docs/gears/writegear/compression/advanced/cciw.md +++ b/docs/gears/writegear/compression/advanced/cciw.md @@ -92,7 +92,7 @@ url_to_stream = ( ) # Define writer with default parameters -writer = WriteGear(output_filename="Output.mp4", logging=True) +writer = WriteGear(output="Output.mp4", logging=True) # format command to convert stream audio as 'output_audio.aac' as list ffmpeg_command_to_save_audio = [ @@ -145,7 +145,7 @@ output_params = { } # output framerate must match source framerate # Define writer with defined parameters and suitable output filename for e.g. `Output.mp4` -writer = WriteGear(output_filename="Output.mp4", **output_params) +writer = WriteGear(output="Output.mp4", **output_params) # loop over while True: diff --git a/docs/gears/writegear/compression/params.md b/docs/gears/writegear/compression/params.md index 781a07e87..f81393aa3 100644 --- a/docs/gears/writegear/compression/params.md +++ b/docs/gears/writegear/compression/params.md @@ -23,13 +23,13 @@ limitations under the License.   -## **`output_filename`** +## **`output`** This parameter sets the valid filename/path/URL for the video output. !!! warning - WriteGear API will throw `ValueError` if `output_filename` provided is empty or invalid. + WriteGear API will throw `ValueError` if `output` provided is empty or invalid. **Data-Type:** String @@ -40,13 +40,13 @@ Its valid input can be one of the following: * **Path to directory**: Valid path of the directory to save the output video file. In this case, WriteGear API will automatically assign a unique filename (_with a default extension i.e.`.mp4`_) as follows: ```python - writer = WriteGear(output_filename = '/home/foo/foo1') #Define writer + writer = WriteGear(output = '/home/foo/foo1') #Define writer ``` * **Filename** _(with/without path)_: Valid filename(_with valid extension_) of the output video file. In case filename is provided without path, then current working directory will be used. ```python - writer = WriteGear(output_filename = 'output.mp4') #Define writer + writer = WriteGear(output = 'output.mp4') #Define writer ``` !!! danger "Make sure to provide valid filename with valid file-extension based on the encoder in use." @@ -55,7 +55,7 @@ Its valid input can be one of the following: * **URL**: Valid URL of a network stream with a protocol supported by installed FFmpeg _(verify with command `ffmpeg -protocols`)_ only. This is useful for building a [**Video-Streaming Server**](https://trac.ffmpeg.org/wiki/StreamingGuide) with FFmpeg in WriteGear API. For example, you can stream on a `rtmp` protocol URL as follows: ```python - writer = WriteGear(output_filename = 'rtmp://localhost/live/test') #Define writer + writer = WriteGear(output = 'rtmp://localhost/live/test') #Define writer ```   @@ -72,7 +72,7 @@ This parameter selects the WriteGear's Primary [Mode of Operation](../../introdu **Usage:** ```python -WriteGear(output_filename = 'output.mp4', compression_mode=True) +WriteGear(output = 'output.mp4', compression_mode=True) ```   @@ -94,7 +94,7 @@ This parameter assigns the custom _path/directory_ where the custom FFmpeg execu ```python # if ffmpeg executables are located at "/foo/foo1/FFmpeg" -WriteGear(output_filename = 'output.mp4', custom_ffmpeg="/foo/foo1/FFmpeg") +WriteGear(output = 'output.mp4', custom_ffmpeg="/foo/foo1/FFmpeg") ```   @@ -208,7 +208,7 @@ This parameter enables logging _(if `True`)_, essential for debugging. **Usage:** ```python -WriteGear(output_filename = 'output.mp4', logging=True) +WriteGear(output = 'output.mp4', logging=True) ```   diff --git a/docs/gears/writegear/compression/usage.md b/docs/gears/writegear/compression/usage.md index 33c26dbe7..b263d06a0 100644 --- a/docs/gears/writegear/compression/usage.md +++ b/docs/gears/writegear/compression/usage.md @@ -57,7 +57,7 @@ import cv2 stream = CamGear(source="myvideo.avi").start() # Define writer with default parameters and suitable output filename for e.g. `Output.mp4` -writer = WriteGear(output_filename="Output.mp4") +writer = WriteGear(output="Output.mp4") # loop over while True: @@ -110,7 +110,7 @@ import cv2 stream = VideoGear(source=0).start() # Define writer with default parameters and suitable output filename for e.g. `Output.mp4` -writer = WriteGear(output_filename="Output.mp4") +writer = WriteGear(output="Output.mp4") # loop over while True: @@ -160,7 +160,7 @@ WriteGear API provides [`-input_framerate`](../params/#supported-parameters) at # set output constant framerate to (say 60 fps) output_params = {"-input_framerate":60, "-r":60} # assign that to WriteGear - writer = WriteGear(output_filename="out.mp4", logging =True, **output_params) + writer = WriteGear(output="out.mp4", logging =True, **output_params) ``` But make sure you ==MUST set value of `-r` and `-input_framerate` parameter less than or equal to your input source framerate.== @@ -181,7 +181,7 @@ stream = CamGear(source=0).start() output_params = {"-input_framerate": stream.framerate} # Define writer with defined parameters and suitable output filename for e.g. `Output.mp4` -writer = WriteGear(output_filename="Output.mp4", **output_params) +writer = WriteGear(output="Output.mp4", **output_params) # loop over while True: @@ -221,11 +221,11 @@ writer.close() ## Using Compression Mode for live streaming -In Compression Mode, WriteGear also allows URL strings _(as output)_ for live streaming realtime frames with its [`output_filename`](../params/#output_filename) parameter. +In Compression Mode, WriteGear also allows URL strings _(as output)_ for live streaming realtime frames with its [`output`](../params/#output) parameter. In this example, we will stream live camera frames directly to Twitch :fontawesome-brands-twitch:: -!!! tip "For streaming with traditional protocols such as :material-video-wireless: RTSP/RTP, Checkout this [WriteGear's Bonus Examples ➶](../../../../help/writegear_ex/#using-writegears-compression-mode-for-rstprtp-live-streaming)." +!!! tip "For streaming with traditional protocols such as :material-video-wireless: RTSP/RTP, Checkout this [WriteGear's Bonus Examples ➶](../../../../help/writegear_ex/#using-writegears-compression-mode-for-rtsprtp-live-streaming)." !!! example ":fontawesome-brands-youtube: YouTube-Live Streaming example code also available in [WriteGear's Bonus Examples ➶](../../../../help/writegear_ex/#using-writegears-compression-mode-for-youtube-live-streaming)" @@ -257,7 +257,7 @@ TWITCH_KEY = "live_XXXXXXXXXX~XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # Define writer with defined parameters and writer = WriteGear( - output_filename="rtmp://live.twitch.tv/app/{}".format(TWITCH_KEY), + output="rtmp://live.twitch.tv/app/{}".format(TWITCH_KEY), logging=True, **output_params ) @@ -341,7 +341,7 @@ output_params = { } # Define writer with defined parameters and suitable output filename for e.g. `Output.mp4` -writer = WriteGear(output_filename="Output.mp4", **output_params) +writer = WriteGear(output="Output.mp4", **output_params) # loop over while True: @@ -394,7 +394,7 @@ output_params = {"-vcodec": "libx264", "-crf": 0, "-preset": "fast"} stream = cv2.VideoCapture(0) # Define writer with defined parameters and suitable output filename for e.g. `Output.mp4` -writer = WriteGear(output_filename="Output.mp4", logging=True, **output_params) +writer = WriteGear(output="Output.mp4", logging=True, **output_params) # loop over while True: @@ -475,7 +475,7 @@ In this example code, we will merging the audio from a Audio Device _(for e.g. W ``` - - [x] **Specify Sound Card:** Then, you can specify your located soundcard in StreamGear as follows: + - [x] **Specify Sound Card:** Then, you can specify your located soundcard in WriteGear as follows: ```python # assign appropriate input audio-source @@ -546,7 +546,7 @@ In this example code, we will merging the audio from a Audio Device _(for e.g. W - [x] **Identify Sound Card:** Then, You can locate your soundcard using `avfoundation` as follows: ```sh - ffmpeg -f qtkit -list_devices true -i "" + ffmpeg -f avfoundation -list_devices true -i "" ffmpeg version N-45279-g6b86dd5... --enable-runtime-cpudetect libavutil 51. 74.100 / 51. 74.100 libavcodec 54. 65.100 / 54. 65.100 @@ -564,7 +564,7 @@ In this example code, we will merging the audio from a Audio Device _(for e.g. W ``` - - [x] **Specify Sound Card:** Then, you can specify your located soundcard in StreamGear as follows: + - [x] **Specify Sound Card:** Then, you can specify your located soundcard in WriteGear as follows: ```python # assign appropriate input audio-source @@ -604,7 +604,7 @@ output_params = { } # Define writer with defined parameters and suitable output filename for e.g. `Output.mp4 -writer = WriteGear(output_filename="Output.mp4", logging=True, **output_params) +writer = WriteGear(output="Output.mp4", logging=True, **output_params) # loop over while True: diff --git a/docs/gears/writegear/introduction.md b/docs/gears/writegear/introduction.md index faee5c9b9..3649ccc05 100644 --- a/docs/gears/writegear/introduction.md +++ b/docs/gears/writegear/introduction.md @@ -31,7 +31,7 @@ limitations under the License. WriteGear API provides a complete, flexible, and robust wrapper around [**FFmpeg**](https://ffmpeg.org/), a leading multimedia framework. WriteGear can process real-time frames into a lossless compressed video-file with any suitable specifications _(such as`bitrate, codec, framerate, resolution, subtitles, etc.`)_. -WriteGear also supports streaming with traditional protocols such as [RTSP/RTP](../../../help/writegear_ex/#using-writegears-compression-mode-for-rstprtp-live-streaming), RTMP. It is powerful enough to perform complex tasks such as [Live-Streaming](../compression/usage/#using-compression-mode-for-live-streaming) _(such as for Twitch, YouTube etc.)_ and [Multiplexing Video-Audio](../compression/usage/#using-compression-mode-with-live-audio-input) with real-time frames in just few lines of code. +WriteGear also supports streaming with traditional protocols such as [RTSP/RTP](../../../help/writegear_ex/#using-writegears-compression-mode-for-rtsprtp-live-streaming), RTMP. It is powerful enough to perform complex tasks such as [Live-Streaming](../compression/usage/#using-compression-mode-for-live-streaming) _(such as for Twitch, YouTube etc.)_ and [Multiplexing Video-Audio](../compression/usage/#using-compression-mode-with-live-audio-input) with real-time frames in just few lines of code. Best of all, WriteGear grants users the complete freedom to play with any FFmpeg parameter with its exclusive ==Custom Commands function== _(see this [doc](../compression/advanced/cciw/))_ without relying on any third-party API. diff --git a/docs/gears/writegear/non_compression/params.md b/docs/gears/writegear/non_compression/params.md index 5d17adeb4..b9ae65f2a 100644 --- a/docs/gears/writegear/non_compression/params.md +++ b/docs/gears/writegear/non_compression/params.md @@ -22,11 +22,11 @@ limitations under the License.   -## **`output_filename`** +## **`output`** This parameter sets the valid output Video filename/path for the output video. -!!! warning "WriteGear API will throw `RuntimeError` if `output_filename` provided is empty or invalid." +!!! warning "WriteGear API will throw `RuntimeError` if `output` provided is empty or invalid." **Data-Type:** String @@ -41,18 +41,18 @@ Its valid input can be one of the following: * **Path to directory**: Valid path of the directory to save the output video file. In this case, WriteGear API will automatically assign a unique filename (_with a default extension i.e.`.mp4`_) as follows: ```python - writer = WriteGear(output_filename = '/home/foo/foo1', compression_mode=False) # Define writer + writer = WriteGear(output = '/home/foo/foo1', compression_mode=False) # Define writer ``` * **Filename** _(with/without path)_: Valid filename(_with valid extension_) of the output video file. In case filename is provided without path, then current working directory will be used. ```python - writer = WriteGear(output_filename = 'output.mp4', compression_mode=False) # Define writer + writer = WriteGear(output = 'output.mp4', compression_mode=False) # Define writer ``` * **GStreamer Pipeline:** - WriteGear API also supports GStreamer Pipeline as input to its `output_filename` parameter in Non-Compression Mode, when [GStreamer Pipeline Mode](#b-exclusive-parameters) is enabled. It can be used as follows: + WriteGear API also supports GStreamer Pipeline as input to its `output` parameter in Non-Compression Mode, when [GStreamer Pipeline Mode](#b-exclusive-parameters) is enabled. It can be used as follows: !!! warning "Requirement for GStreamer Pipelining" @@ -67,7 +67,7 @@ Its valid input can be one of the following: output_params = {"-gst_pipeline_mode": True} # Define writer writer = WriteGear( - output_filename="appsrc ! videoconvert ! avenc_mpeg4 bitrate=100000 ! mp4mux ! filesink location=foo.mp4", compression_mode=False) + output="appsrc ! videoconvert ! avenc_mpeg4 bitrate=100000 ! mp4mux ! filesink location=foo.mp4", compression_mode=False) ```   @@ -84,7 +84,7 @@ This parameter selects the WriteGear's Primary [Mode of Operation](../../introdu **Usage:** ```python -WriteGear(output_filename = 'output.mp4', compression_mode=False) +WriteGear(output = 'output.mp4', compression_mode=False) ```   @@ -131,7 +131,7 @@ WriteGear provides access to all available [**OpenCV's VideoWriter API**](https: In addition to OpenCV Parameters, WriteGear API also provides few exclusive attribute, which are as follows: -* **`-gst_pipeline_mode`**: a boolean attribute to enable **GStreamer Pipeline Mode** to supports GStreamer Pipeline as input to its `output_filename` parameter in Non-Compression Mode. +* **`-gst_pipeline_mode`**: a boolean attribute to enable **GStreamer Pipeline Mode** to supports GStreamer Pipeline as input to its `output` parameter in Non-Compression Mode. !!! note "Enabling `-gst_pipeline_mode` will enforce `-backend` parameter value to `"CAP_GSTREAMER"`" @@ -149,7 +149,7 @@ To assign desired parameters in Non-Compression Mode, you can format it as dicti # format parameter as dictionary attribute output_params = {"-fps":30} # and then, assign it -WriteGear(output_filename = 'output.mp4', **output_params) +WriteGear(output = 'output.mp4', **output_params) ``` !!! example "Its usage example can be found [here ➶](../usage/#using-non-compression-mode-with-videocapture-gears)." @@ -170,7 +170,7 @@ To select desired FOURCC codec in Non-Compression Mode, you can format it as dic # format codec as dictionary attribute output_params = {"-fourcc":"MJPG"} # and then, assign it -WriteGear(output_filename = 'output.mp4', **output_params) +WriteGear(output = 'output.mp4', **output_params) ``` !!! example "Its usage example can be found [here ➶](../usage/#using-non-compression-mode-with-videocapture-gears)." @@ -188,7 +188,7 @@ This parameter enables logging _(if `True`)_, essential for debugging. **Usage:** ```python -WriteGear(output_filename = 'output.mp4', logging=True) +WriteGear(output = 'output.mp4', logging=True) ```   diff --git a/docs/gears/writegear/non_compression/usage.md b/docs/gears/writegear/non_compression/usage.md index 8430c9a0f..71c4c5dce 100644 --- a/docs/gears/writegear/non_compression/usage.md +++ b/docs/gears/writegear/non_compression/usage.md @@ -50,7 +50,7 @@ import cv2 stream = CamGear(source="myvideo.avi").start() # Define writer with Non-compression mode and suitable output filename for e.g. `Output.mp4` -writer = WriteGear(output_filename="Output.mp4", compression_mode=False) +writer = WriteGear(output="Output.mp4", compression_mode=False) # loop over while True: @@ -111,7 +111,7 @@ stream = VideoGear(source=0, logging=True).start() # Define writer with defined parameters and suitable output filename for e.g. `Output.mp4` writer = WriteGear( - output_filename="Output.mp4", compression_mode=False, logging=True, **output_params + output="Output.mp4", compression_mode=False, logging=True, **output_params ) @@ -172,7 +172,7 @@ stream = cv2.VideoCapture(0) # Define writer with defined parameters and suitable output filename for e.g. `Output.mp4` writer = WriteGear( - output_filename="Output.mp4", compression_mode=False, logging=True, **output_params + output="Output.mp4", compression_mode=False, logging=True, **output_params ) # loop over @@ -217,7 +217,7 @@ writer.close() ## Using Non-Compression Mode with GStreamer Pipeline - WriteGear API's Non-Compression Mode also supports GStreamer Pipeline as input to its `output_filename` parameter, when [GStreamer Pipeline Mode](../params/#b-exclusive-parameters) is enabled. This provides flexible way to write video frames to file or network stream with controlled framerate and bitrate. The complete usage example is as follows: + WriteGear API's Non-Compression Mode also supports GStreamer Pipeline as input to its `output` parameter, when [GStreamer Pipeline Mode](../params/#b-exclusive-parameters) is enabled. This provides flexible way to write video frames to file or network stream with controlled framerate and bitrate. The complete usage example is as follows: !!! warning "Requirement for GStreamer Pipelining" GStreamer Pipelining in WriteGear requires your OpenCV to be built with GStreamer support. Checkout [this FAQ](../../../../help/camgear_faqs/#how-to-compile-opencv-with-gstreamer-support) for compiling OpenCV with GStreamer support. @@ -245,7 +245,7 @@ GSTPipeline = "appsrc ! videoconvert ! avenc_mpeg4 bitrate=100000 ! mp4mux ! fil # Define writer with defined parameters and with our Gstreamer pipeline writer = WriteGear( - output_filename=GSTPipeline, compression_mode=False, logging=True, **output_params + output=GSTPipeline, compression_mode=False, logging=True, **output_params ) # loop over diff --git a/docs/help.md b/docs/help.md index a7884f87a..08b1874fa 100644 --- a/docs/help.md +++ b/docs/help.md @@ -26,7 +26,7 @@ limitations under the License. > Liked VidGear? Would you like to help VidGear, other users, and the author? -There are very simple ways to help us: +There are many simple ways to help us:   @@ -91,11 +91,14 @@ Thanks a million! :blush: You can connect with me, the author 👋: +![Author Image](https://avatars.githubusercontent.com/u/34266896?v=4){ align=left width="160" loading=lazy } + * Follow author on GitHub: [![GitHub follow](https://img.shields.io/github/followers/abhiTronix?label=Follow%20%40abhiTronix&logo=github&style=flat-square)](https://github.com/abhiTronix) * Follow author on Twitter: Follow @abhi_una12 * Get in touch with author on Linkedin: [![Linkedin follow](https://img.shields.io/badge/Follow-@Abhishek Thakur-orange.svg?logo=linkedin&style=flat-square)](https://in.linkedin.com/in/abhishek-abhitronix?trk=profile-badge) - + + diff --git a/docs/help/camgear_ex.md b/docs/help/camgear_ex.md index 0ca67e8cc..af72f74d2 100644 --- a/docs/help/camgear_ex.md +++ b/docs/help/camgear_ex.md @@ -134,7 +134,7 @@ stream.stop()   -## Using CamGear for capturing RSTP/RTMP URLs +## Using CamGear for capturing RTSP/RTMP URLs You can open any network stream _(such as RTSP/RTMP)_ just by providing its URL directly to CamGear's [`source`](../../gears/camgear/params/#source) parameter. @@ -145,7 +145,7 @@ Here's a high-level wrapper code around CamGear API to enable auto-reconnection ??? tip "Enforcing UDP stream" - You can easily enforce UDP for RSTP streams inplace of default TCP, by putting following lines of code on the top of your existing code: + You can easily enforce UDP for RTSP streams inplace of default TCP, by putting following lines of code on the top of your existing code: ```python # import required libraries diff --git a/docs/help/camgear_faqs.md b/docs/help/camgear_faqs.md index bfe2726e7..208094513 100644 --- a/docs/help/camgear_faqs.md +++ b/docs/help/camgear_faqs.md @@ -24,7 +24,7 @@ limitations under the License. ## What is CamGear API and what does it do? -**Answer:** CamGear supports a diverse range of video streams which can handle/control video stream almost any IP/USB Cameras, multimedia video file format (upto 4k tested), any network stream URL such as http(s), rtp, rstp, rtmp, mms, etc. In addition to this, it also supports live Gstreamer's RAW pipelines and YouTube video/livestreams URLs. _For more info. see [CamGear doc ➶](../../gears/camgear/overview/)._ +**Answer:** CamGear supports a diverse range of video streams which can handle/control video stream almost any IP/USB Cameras, multimedia video file format (upto 4k tested), any network stream URL such as http(s), rtp, rtsp, rtmp, mms, etc. In addition to this, it also supports live Gstreamer's RAW pipelines and YouTube video/livestreams URLs. _For more info. see [CamGear doc ➶](../../gears/camgear/overview/)._   @@ -74,9 +74,9 @@ limitations under the License.   -## How to open RSTP network streams with CamGear? +## How to open RTSP network streams with CamGear? -**Answer:** You can open any local network stream _(such as RTSP)_ just by providing its URL directly to CamGear's [`source`](../../gears/camgear/params/#source) parameter. See [this bonus example ➶](../camgear_ex/#using-camgear-for-capturing-rstprtmp-urls). +**Answer:** You can open any local network stream _(such as RTSP)_ just by providing its URL directly to CamGear's [`source`](../../gears/camgear/params/#source) parameter. See [this bonus example ➶](../camgear_ex/#using-camgear-for-capturing-rtsprtmp-urls).   diff --git a/docs/help/get_help.md b/docs/help/get_help.md index 8f9567e10..8db0f5ea2 100644 --- a/docs/help/get_help.md +++ b/docs/help/get_help.md @@ -27,8 +27,7 @@ limitations under the License. > Would you like to get help with VidGear? -There are several ways to get help with VidGear: - +There are several ways such as:   @@ -99,7 +98,7 @@ There you can ask quick questions, swiftly troubleshoot your problems, help othe   -## Reporting an issues +## Reporting an issues :fontawesome-regular-face-tired: > Want to report a bug? Suggest a new feature? @@ -109,7 +108,7 @@ Before you do, please read our [guidelines ➶](../../contribution/issue/)   -## Preparing a Pull Request +## Preparing a Pull Request :fontawesome-solid-code-pull-request: > Interested in contributing to VidGear? diff --git a/docs/help/screengear_ex.md b/docs/help/screengear_ex.md index b32eed4f1..ce0e1f26e 100644 --- a/docs/help/screengear_ex.md +++ b/docs/help/screengear_ex.md @@ -59,7 +59,7 @@ client = NetGear( ) # Define writer with default parameters and suitable output filename for e.g. `Output.mp4` -writer = WriteGear(output_filename="Output.mp4") +writer = WriteGear(output="Output.mp4") # loop over while True: diff --git a/docs/help/stabilizer_ex.md b/docs/help/stabilizer_ex.md index 36b03df4e..3e0e1aa72 100644 --- a/docs/help/stabilizer_ex.md +++ b/docs/help/stabilizer_ex.md @@ -24,7 +24,7 @@ limitations under the License. ## Saving Stabilizer Class output with Live Audio Input -In this example code, we will merging the audio from a Audio Device _(for e.g. Webcam inbuilt mic input)_ with Stablized frames incoming from the Stabilizer Class _(which is also using same Webcam video input through OpenCV)_, and save the final output as a compressed video file, all in real time: +In this example code, we will merging the audio from a Audio Device _(for e.g. Webcam inbuilt mic input)_ with Stabilized frames incoming from the Stabilizer Class _(which is also using same Webcam video input through OpenCV)_, and save the final output as a compressed video file, all in real time: ??? new "New in v0.2.2" This example was added in `v0.2.2`. @@ -197,7 +197,7 @@ output_params = { } # Define writer with defined parameters and suitable output filename for e.g. `Output.mp4 -writer = WriteGear(output_filename="Output.mp4", logging=True, **output_params) +writer = WriteGear(output="Output.mp4", logging=True, **output_params) # loop over while True: @@ -254,17 +254,17 @@ from vidgear.gears.stabilizer import Stabilizer import cv2 # Give suitable video file path to be stabilized -unstablized_videofile = "test.mp4" +unstabilized_videofile = "test.mp4" # open stream on given path -stream = cv2.VideoCapture(unstablized_videofile) +stream = cv2.VideoCapture(unstabilized_videofile) # initiate stabilizer object with defined parameters stab = Stabilizer(smoothing_radius=30, crop_n_zoom=True, border_size=5, logging=True) # define required FFmpeg optimizing parameters for your writer output_params = { - "-i": unstablized_videofile, + "-i": unstabilized_videofile, "-c:a": "aac", "-input_framerate": stream.get(cv2.CAP_PROP_FPS), "-clones": ["-shortest"], @@ -274,7 +274,7 @@ output_params = { # Define writer with defined parameters and suitable output filename for e.g. `Output.mp4 -writer = WriteGear(output_filename="Output.mp4", logging=True, **output_params) +writer = WriteGear(output="Output.mp4", logging=True, **output_params) # loop over while True: diff --git a/docs/help/videogear_ex.md b/docs/help/videogear_ex.md index ce31c0a70..e544cd237 100644 --- a/docs/help/videogear_ex.md +++ b/docs/help/videogear_ex.md @@ -108,7 +108,7 @@ if __name__ == "__main__":   -## Using VideoGear for capturing RSTP/RTMP URLs +## Using VideoGear for capturing RTSP/RTMP URLs Here's a high-level wrapper code around VideoGear API to enable auto-reconnection during capturing, plus stabilization is enabled _(`stabilize=True`)_ in order to stabilize captured frames on-the-go: @@ -117,7 +117,7 @@ Here's a high-level wrapper code around VideoGear API to enable auto-reconnectio ??? tip "Enforcing UDP stream" - You can easily enforce UDP for RSTP streams inplace of default TCP, by putting following lines of code on the top of your existing code: + You can easily enforce UDP for RTSP streams inplace of default TCP, by putting following lines of code on the top of your existing code: ```python # import required libraries @@ -240,14 +240,14 @@ from vidgear.gears import VideoGear import cv2 # Give suitable video file path to be stabilized -unstablized_videofile = "test.mp4" +unstabilized_videofile = "test.mp4" # open any valid video path with stabilization enabled(`stabilize = True`) -stream_stab = VideoGear(source=unstablized_videofile, stabilize=True, logging=True).start() +stream_stab = VideoGear(source=unstabilized_videofile, stabilize=True, logging=True).start() # define required FFmpeg optimizing parameters for your writer output_params = { - "-i": unstablized_videofile, + "-i": unstabilized_videofile, "-c:a": "aac", "-input_framerate": stream_stab.framerate, "-clones": ["-shortest"], @@ -256,7 +256,7 @@ output_params = { } # Define writer with defined parameters and suitable output filename for e.g. `Output.mp4 -writer = WriteGear(output_filename="Output.mp4", logging=True, **output_params) +writer = WriteGear(output="Output.mp4", logging=True, **output_params) # loop over while True: diff --git a/docs/help/writegear_ex.md b/docs/help/writegear_ex.md index 8b4ebdeba..63b73abef 100644 --- a/docs/help/writegear_ex.md +++ b/docs/help/writegear_ex.md @@ -23,19 +23,19 @@ limitations under the License.   -## Using WriteGear's Compression Mode for RSTP/RTP Live-Streaming +## Using WriteGear's Compression Mode for RTSP/RTP Live-Streaming -In Compression Mode, you can use WriteGear for livestreaming with traditional protocols such as RSTP/RTP. The example to achieve that is as follows: +In Compression Mode, you can use WriteGear for livestreaming with traditional protocols such as RTSP/RTP. The example to achieve that is as follows: ??? new "New in v0.2.6" This example was added in `v0.2.6`. -!!! alert "This example assume you already have a RSTP Server running at specified RSTP address with format *`rtsp://[RTSP_ADDRESS]:[RTSP_PORT]/[RTSP_PATH]`* for publishing video frames." +!!! alert "This example assume you already have a RTSP Server running at specified RTSP address with format *`rtsp://[RTSP_ADDRESS]:[RTSP_PORT]/[RTSP_PATH]`* for publishing video frames." -??? tip "Creating your own RSTP Server locally" - If you want to create your RSTP Server locally, then checkout [**rtsp-simple-server**](https://github.com/aler9/rtsp-simple-server) - a ready-to-use and zero-dependency server and proxy that allows users to publish, read and proxy live video and audio streams through various protocols such as RSTP, RTMP etc. +??? tip "Creating your own RTSP Server locally" + If you want to create your RTSP Server locally, then checkout [**rtsp-simple-server**](https://github.com/aler9/rtsp-simple-server) - a ready-to-use and zero-dependency server and proxy that allows users to publish, read and proxy live video and audio streams through various protocols such as RTSP, RTMP etc. -!!! danger "Make sure to change RSTP address `rtsp://localhost:8554/mystream` with yours in following code before running!" +!!! danger "Make sure to change RTSP address `rtsp://localhost:8554/mystream` with yours in following code before running!" ```python hl_lines="10 15" @@ -50,10 +50,10 @@ stream = CamGear(source="foo.mp4").start() # define required FFmpeg parameters for your writer output_params = {"-f": "rtsp", "-rtsp_transport": "tcp"} -# Define writer with defined parameters and RSTP address -# [WARNING] Change your RSTP address `rtsp://localhost:8554/mystream` with yours! +# Define writer with defined parameters and RTSP address +# [WARNING] Change your RTSP address `rtsp://localhost:8554/mystream` with yours! writer = WriteGear( - output_filename="rtsp://localhost:8554/mystream", logging=True, **output_params + output="rtsp://localhost:8554/mystream", logging=True, **output_params ) # loop over @@ -80,6 +80,7 @@ writer.close()   + ## Using WriteGear's Compression Mode for YouTube-Live Streaming In Compression Mode, you can also use WriteGear for Youtube-Livestreaming. The example is as follows: @@ -91,42 +92,199 @@ In Compression Mode, you can also use WriteGear for Youtube-Livestreaming. The e !!! danger "Make sure to change [_YouTube-Live Stream Key_](https://support.google.com/youtube/answer/2907883#zippy=%2Cstart-live-streaming-now) with yours in following code before running!" -```python hl_lines="15-24 28 32" +=== "Without Audio" + + ```python hl_lines="11-17 21 25" + # import required libraries + from vidgear.gears import CamGear + from vidgear.gears import WriteGear + import cv2 + + # define and open video source + stream = CamGear(source="/home/foo/foo.mp4", logging=True).start() + + # define required FFmpeg parameters for your writer + output_params = { + "-clones": ["-f", "lavfi", "-i", "anullsrc"], + "-vcodec": "libx264", + "-preset": "medium", + "-b:v": "4500k", + "-bufsize": "512k", + "-pix_fmt": "yuv420p", + "-f": "flv", + } + + # [WARNING] Change your YouTube-Live Stream Key here: + YOUTUBE_STREAM_KEY = "xxxx-xxxx-xxxx-xxxx-xxxx" + + # Define writer with defined parameters + writer = WriteGear( + output="rtmp://a.rtmp.youtube.com/live2/{}".format(YOUTUBE_STREAM_KEY), + logging=True, + **output_params + ) + + # loop over + while True: + + # read frames from stream + frame = stream.read() + + # check for frame if Nonetype + if frame is None: + break + + # {do something with the frame here} + + # write frame to writer + writer.write(frame) + + # safely close video stream + stream.stop() + + # safely close writer + writer.close() + ``` + +=== "With Audio" + + !!! warning "This code assume given input video source contains valid audio stream." + + ```python hl_lines="7 15-24 28 32" + # import required libraries + from vidgear.gears import CamGear + from vidgear.gears import WriteGear + import cv2 + + # define video source(with audio) here + VIDEO_SOURCE = "/home/foo/foo.mp4" + + # Open stream + stream = CamGear(source=VIDEO_SOURCE, logging=True).start() + + # define required FFmpeg parameters for your writer + # [NOTE]: Added VIDEO_SOURCE as audio-source + output_params = { + "-i": VIDEO_SOURCE, + "-acodec": "aac", + "-ar": 44100, + "-b:a": 712000, + "-vcodec": "libx264", + "-preset": "medium", + "-b:v": "4500k", + "-bufsize": "512k", + "-pix_fmt": "yuv420p", + "-f": "flv", + } + + # [WARNING] Change your YouTube-Live Stream Key here: + YOUTUBE_STREAM_KEY = "xxxx-xxxx-xxxx-xxxx-xxxx" + + # Define writer with defined parameters + writer = WriteGear( + output="rtmp://a.rtmp.youtube.com/live2/{}".format(YOUTUBE_STREAM_KEY), + logging=True, + **output_params + ) + + # loop over + while True: + + # read frames from stream + frame = stream.read() + + # check for frame if Nonetype + if frame is None: + break + + # {do something with the frame here} + + # write frame to writer + writer.write(frame) + + # safely close video stream + stream.stop() + + # safely close writer + writer.close() + ``` + +  + + +## Using WriteGear's Compression Mode with v4l2loopback Virtual Cameras + +With WriteGear's Compression Mode, you can directly feed video-frames to [`v4l2loopback`](https://github.com/umlaeute/v4l2loopback) generated Virtual Camera devices on Linux Machines. The complete usage example is as follows: + +??? new "New in v0.3.0" + This example was added in `v0.3.0`. + +???+ danger "Example Assumptions" + + * ==You're running are a Linux machine.== + * ==WriteGear API's backend FFmpeg binaries are compiled with `v4l2/v4l2loopback` demuxer support.== + * You already have `v4l2loopback` Virtual Camera device running at address: `/dev/video0` + +??? tip "Creating your own Virtual Camera device with `v4l2loopback` module." + + To install and create a v4l2loopback virtual camera device on Linux Mint OS/Ubuntu _(may slightly differ for other distros)_, run following two terminal commands: + + ```sh + $ sudo apt-get install v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) + + $ sudo modprobe v4l2loopback devices=1 video_nr=0 exclusive_caps=1 card_label='VCamera' + ``` + + !!! note "For further information on parameters used, checkout [v4l2loopback](https://github.com/umlaeute/v4l2loopback#v4l2loopback---a-kernel-module-to-create-v4l2-loopback-devices) docs" + + Finally, You can check the loopback device you just created by listing contents of `/sys/devices/virtual/video4linux` directory with terminal command: + + ```sh + $ sudo ls -1 /sys/devices/virtual/video4linux + + video0 + ``` + + Now you can use `/dev/video0` Virtual Camera device path in WriteGear API. + +??? fail "v4l2: open /dev/videoX: Permission denied" + + If you got this error, then you must add your username to the `video` group by running following commands: + ```sh + $ sudo adduser $(whoami) video + $ sudo usermod -a -G video $(whoami) + ``` + Afterwards, restart your computer to finialize these changes. + + **Note:** If the problem still persists, then try to run your python script as superuser with `sudo` command. + + +??? warning "Default `libx264` encoder is incompatible with `v4l2loopback` module." + + Kindly use other encoders such as `libxvid`, `mpeg4` etc. + + + +```python hl_lines="12-15 19" # import required libraries from vidgear.gears import CamGear from vidgear.gears import WriteGear import cv2 -# define video source -VIDEO_SOURCE = "/home/foo/foo.mp4" - -# Open stream -stream = CamGear(source=VIDEO_SOURCE, logging=True).start() +# open any valid video stream(for e.g `foo.mp4` file) +stream = CamGear(source="foo.mp4").start() # define required FFmpeg parameters for your writer -# [NOTE]: Added VIDEO_SOURCE as audio-source, since YouTube rejects audioless streams! +# also retrieve framerate from CamGear Stream and pass it as `-input_framerate` parameter output_params = { - "-i": VIDEO_SOURCE, - "-acodec": "aac", - "-ar": 44100, - "-b:a": 712000, - "-vcodec": "libx264", - "-preset": "medium", - "-b:v": "4500k", - "-bufsize": "512k", + "-input_framerate": stream.framerate, + "-vcodec": "libxvid", + "-f": "v4l2", "-pix_fmt": "yuv420p", - "-f": "flv", } -# [WARNING] Change your YouTube-Live Stream Key here: -YOUTUBE_STREAM_KEY = "xxxx-xxxx-xxxx-xxxx-xxxx" - -# Define writer with defined parameters -writer = WriteGear( - output_filename="rtmp://a.rtmp.youtube.com/live2/{}".format(YOUTUBE_STREAM_KEY), - logging=True, - **output_params -) +# Define writer with "/dev/video0" as source and user-defined parameters +writer = WriteGear(output="/dev/video0", logging=True, **output_params) # loop over while True: @@ -134,7 +292,7 @@ while True: # read frames from stream frame = stream.read() - # check for frame if Nonetype + # check for frame if None-type if frame is None: break @@ -143,6 +301,9 @@ while True: # write frame to writer writer.write(frame) +# close output window +cv2.destroyAllWindows() + # safely close video stream stream.stop() @@ -150,7 +311,9 @@ stream.stop() writer.close() ``` -  +!!! success "The data sent to the v4l2loopback device `/dev/video0` in this example with WriteGear API, can then be read by any v4l2-capable application _(such as OpenCV, VLC, ffplay etc.)_" + +  ## Using WriteGear's Compression Mode for creating MP4 segments @@ -184,7 +347,7 @@ output_params = { } # Define writer with defined parameters -writer = WriteGear(output_filename="output%03d.mp4", logging=True, **output_params) +writer = WriteGear(output="output%03d.mp4", logging=True, **output_params) # loop over while True: @@ -247,7 +410,7 @@ stream_params = { } # Define writer with defined parameters -writer = WriteGear(output_filename="Output.mp4", logging=True, **stream_params) +writer = WriteGear(output="Output.mp4", logging=True, **stream_params) # loop over while True: @@ -302,7 +465,7 @@ In this example we are capturing video from desktop screen in a Timely Accurate from vidgear.gears import WriteGear # Define writer with defined parameters and with some dummy name - writer = WriteGear(output_filename="Output.mp4", logging=True) + writer = WriteGear(output="Output.mp4", logging=True) # format FFmpeg command to generate time accurate video ffmpeg_command = [ @@ -330,7 +493,7 @@ In this example we are capturing video from desktop screen in a Timely Accurate from vidgear.gears import WriteGear # Define writer with defined parameters and with some dummy name - writer = WriteGear(output_filename="Output.mp4", logging=True) + writer = WriteGear(output="Output.mp4", logging=True) # format FFmpeg command to generate time accurate video ffmpeg_command = [ @@ -358,7 +521,7 @@ In this example we are capturing video from desktop screen in a Timely Accurate from vidgear.gears import WriteGear # Define writer with defined parameters and with some dummy name - writer = WriteGear(output_filename="Output.mp4", logging=True) + writer = WriteGear(output="Output.mp4", logging=True) # format FFmpeg command to generate time accurate video ffmpeg_command = [ @@ -387,7 +550,7 @@ In this example we are capturing video from desktop screen in a Timely Accurate We will be using [`cv_bridge`](http://wiki.ros.org/cv_bridge/Tutorials/ConvertingBetweenROSImagesAndOpenCVImagesPython) to convert OpenCV frames to ROS image messages and vice-versa. -In this example, we'll create a node that listens to a ROS image message topic, converts the recieved images messages into OpenCV frames, draws a circle on it, and then process these frames into a lossless compressed file format in real-time. +In this example, we'll create a node that listens to a ROS image message topic, converts the received images messages into OpenCV frames, draws a circle on it, and then process these frames into a lossless compressed file format in real-time. ??? new "New in v0.2.2" This example was added in `v0.2.2`. @@ -411,16 +574,16 @@ from vidgear.gears import WriteGear # custom publisher class class image_subscriber: - def __init__(self, output_filename="Output.mp4"): + def __init__(self, output="Output.mp4"): # create CV bridge self.bridge = CvBridge() # define publisher topic self.image_pub = rospy.Subscriber("image_topic_sub", Image, self.callback) # Define writer with default parameters - self.writer = WriteGear(output_filename=output_filename) + self.writer = WriteGear(output=output) def callback(self, data): - # convert recieved data to frame + # convert received data to frame try: cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8") except CvBridgeError as e: @@ -446,7 +609,7 @@ class image_subscriber: def main(args): # define publisher with suitable output filename # such as `Output.mp4` for saving output - ic = image_subscriber(output_filename="Output.mp4") + ic = image_subscriber(output="Output.mp4") # initiate ROS node on publisher rospy.init_node("image_subscriber", anonymous=True) try: diff --git a/docs/help/writegear_faqs.md b/docs/help/writegear_faqs.md index a5007a9f9..56161915a 100644 --- a/docs/help/writegear_faqs.md +++ b/docs/help/writegear_faqs.md @@ -105,15 +105,15 @@ limitations under the License.   -## Is YouTube-Live Streaming possibe with WriteGear? +## Is YouTube-Live Streaming possible with WriteGear? **Answer:** Yes, See [this bonus example ➶](../writegear_ex/#using-writegears-compression-mode-for-youtube-live-streaming).   -## How to Live-Streaming using RSTP/RTP protocol with WriteGear? +## How to Live-Streaming using RTSP/RTP protocol with WriteGear? -**Answer:** See [this bonus example ➶](../writegear_ex/#using-writegears-compression-mode-for-rstprtp-live-streaming). +**Answer:** See [this bonus example ➶](../writegear_ex/#using-writegears-compression-mode-for-rtsprtp-live-streaming).   diff --git a/docs/index.md b/docs/index.md index 1ea3746e1..5543c06b3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -126,7 +126,7 @@ It is something I am doing with my own free time. But so much more needs to be d Here is a Bibtex entry you can use to cite this project in a publication: -[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6046843.svg)](https://doi.org/10.5281/zenodo.6046843) +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6926196.svg)](https://doi.org/10.5281/zenodo.6926196) ```BibTeX @software{vidgear, @@ -134,17 +134,20 @@ Here is a Bibtex entry you can use to cite this project in a publication: Zoe Papakipos and Christian Clauss and Christian Hollinger and + Ian Max Andolina and Vincent Boivin and + enarche-ahn and + freol35241 and Benjamin Lowe and Mickaël Schoentgen and Renaud Bouckenooghe}, - title = {abhiTronix/vidgear: VidGear v0.2.5}, - month = feb, + title = {abhiTronix/vidgear: VidGear v0.2.6}, + month = jul, year = 2022, publisher = {Zenodo}, - version = {vidgear-0.2.5}, - doi = {10.5281/zenodo.6046843}, - url = {https://doi.org/10.5281/zenodo.6046843} + version = {vidgear-0.2.6}, + doi = {10.5281/zenodo.6926196}, + url = {https://doi.org/10.5281/zenodo.6926196} } ``` diff --git a/docs/overrides/assets/gifs/webgear_rtc.gif b/docs/overrides/assets/gifs/webgear_rtc.gif index 5e8350dec..87fd3b8cf 100644 Binary files a/docs/overrides/assets/gifs/webgear_rtc.gif and b/docs/overrides/assets/gifs/webgear_rtc.gif differ diff --git a/docs/overrides/assets/javascripts/extra.js b/docs/overrides/assets/javascripts/extra.js index e76cef5ef..3348d73aa 100755 --- a/docs/overrides/assets/javascripts/extra.js +++ b/docs/overrides/assets/javascripts/extra.js @@ -20,7 +20,7 @@ limitations under the License. // DASH StreamGear demo var player_dash = new Clappr.Player({ - source: 'https://rawcdn.githack.com/abhiTronix/vidgear-docs-additionals/dca65250d95eeeb87d594686c2f2c2208a015486/streamgear_video_segments/DASH/streamgear_dash.mpd', + source: 'https://bbcdn.githack.com/abhi_uno/vidgear-docs-additionals/raw/abc0c193ab26e21f97fa30c9267de6beb8a72295/streamgear_video_segments/DASH/streamgear_dash.mpd', plugins: [DashShakaPlayback, LevelSelector], shakaConfiguration: { streaming: { @@ -44,13 +44,13 @@ var player_dash = new Clappr.Player({ width: '100%', height: '100%', parentId: '#player_dash', - poster: 'https://rawcdn.githack.com/abhiTronix/vidgear-docs-additionals/dca65250d95eeeb87d594686c2f2c2208a015486/streamgear_video_segments/DASH/hd_thumbnail.jpg', + poster: 'https://bbcdn.githack.com/abhi_uno/vidgear-docs-additionals/raw/abc0c193ab26e21f97fa30c9267de6beb8a72295/streamgear_video_segments/DASH/hd_thumbnail.jpg', preload: 'metadata', }); // HLS StremGear demo var player_hls = new Clappr.Player({ - source: 'https://rawcdn.githack.com/abhiTronix/vidgear-docs-additionals/abc0c193ab26e21f97fa30c9267de6beb8a72295/streamgear_video_segments/HLS/streamgear_hls.m3u8', + source: 'https://bbcdn.githack.com/abhi_uno/vidgear-docs-additionals/raw/abc0c193ab26e21f97fa30c9267de6beb8a72295/streamgear_video_segments/HLS/streamgear_hls.m3u8', plugins: [HlsjsPlayback, LevelSelector], hlsUseNextLevel: false, hlsMinimumDvrSize: 60, @@ -80,13 +80,13 @@ var player_hls = new Clappr.Player({ width: '100%', height: '100%', parentId: '#player_hls', - poster: 'https://rawcdn.githack.com/abhiTronix/vidgear-docs-additionals/abc0c193ab26e21f97fa30c9267de6beb8a72295/streamgear_video_segments/HLS/hd_thumbnail.jpg', + poster: 'https://bbcdn.githack.com/abhi_uno/vidgear-docs-additionals/raw/abc0c193ab26e21f97fa30c9267de6beb8a72295/streamgear_video_segments/HLS/hd_thumbnail.jpg', preload: 'metadata', }); // DASH Stabilizer demo var player_stab = new Clappr.Player({ - source: 'https://rawcdn.githack.com/abhiTronix/vidgear-docs-additionals/fbcf0377b171b777db5e0b3b939138df35a90676/stabilizer_video_chunks/stabilizer_dash.mpd', + source: 'https://bbcdn.githack.com/abhi_uno/vidgear-docs-additionals/raw/abc0c193ab26e21f97fa30c9267de6beb8a72295/stabilizer_video_chunks/stabilizer_dash.mpd', plugins: [DashShakaPlayback], shakaConfiguration: { streaming: { @@ -99,6 +99,6 @@ var player_stab = new Clappr.Player({ width: '100%', height: '100%', parentId: '#player_stab', - poster: 'https://rawcdn.githack.com/abhiTronix/vidgear-docs-additionals/94bf767c28bf2fe61b9c327625af8e22745f9fdf/stabilizer_video_chunks/hd_thumbnail_2.png', + poster: 'https://bbcdn.githack.com/abhi_uno/vidgear-docs-additionals/raw/abc0c193ab26e21f97fa30c9267de6beb8a72295/stabilizer_video_chunks/hd_thumbnail.png', preload: 'metadata', }); \ No newline at end of file diff --git a/docs/overrides/assets/stylesheets/custom.css b/docs/overrides/assets/stylesheets/custom.css index 1fcf73fe1..18580d4c6 100755 --- a/docs/overrides/assets/stylesheets/custom.css +++ b/docs/overrides/assets/stylesheets/custom.css @@ -36,21 +36,36 @@ limitations under the License. --md-admonition-icon--xadvance: url("data:image/svg+xml,%3C%3Fxml version='1.0' standalone='no'%3F%3E%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 20010904//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'%3E%3Csvg version='1.0' xmlns='http://www.w3.org/2000/svg' width='512.000000pt' height='512.000000pt' viewBox='0 0 512.000000 512.000000' preserveAspectRatio='xMidYMid meet'%3E%3Cg transform='translate(0.000000,512.000000) scale(0.100000,-0.100000)'%0Afill='%23000000' stroke='none'%3E%3Cpath d='M2372 5103 c-39 -19 -70 -59 -78 -102 -12 -57 4 -98 63 -162 l57 -60%0A-280 -278 -279 -278 -774 -329 c-426 -181 -797 -342 -824 -359 -57 -34 -111%0A-105 -128 -168 -17 -62 -7 -173 20 -227 16 -32 215 -237 679 -702 590 -590%0A663 -660 717 -684 144 -66 328 -6 396 129 12 22 167 391 345 821 l324 781 274%0A274 275 275 60 -57 c41 -37 73 -58 96 -63 130 -24 225 99 166 214 -24 46 -934%0A954 -978 976 -41 20 -89 20 -131 -1z m421 -701 l157 -157 -263 -263 -262 -262%0A-488 2 -488 3 293 124 293 124 295 293 c162 162 297 294 300 294 3 0 76 -71%0A163 -158z m-545 -999 c-3 -10 -132 -325 -288 -701 l-284 -683 -628 628 c-345%0A345 -628 631 -628 634 0 3 69 35 153 72 l152 66 764 0 c722 1 763 0 759 -16z'/%3E%3Cpath d='M3742 4560 c-42 -26 -76 -99 -68 -144 13 -68 65 -121 126 -126 62 -5%0A82 1 123 39 41 39 42 41 42 106 0 65 -1 67 -42 106 -38 35 -47 39 -95 39 -36%0A0 -64 -7 -86 -20z'/%3E%3Cpath d='M3980 3922 c-104 -57 -108 -201 -8 -262 95 -58 222 17 222 130 0 110%0A-120 184 -214 132z'/%3E%3Cpath d='M3052 3270 c-99 -61 -95 -203 8 -257 34 -18 59 -23 117 -23 l73 0 0%0A-419 0 -419 -57 -27 c-275 -135 -509 -401 -617 -703 -87 -243 -91 -546 -10%0A-799 33 -105 104 -246 170 -339 61 -87 217 -244 266 -267 33 -16 94 -17 753%0A-17 658 0 720 1 753 17 51 24 206 182 269 273 151 221 223 454 223 719 0 261%0A-68 485 -213 701 -102 152 -281 313 -448 403 l-79 42 0 418 0 417 62 0 c81 0%0A137 27 166 79 40 70 20 154 -47 198 l-34 23 -661 0 c-642 0 -662 -1 -694 -20z%0Am908 -763 c0 -600 -16 -546 182 -636 201 -91 332 -212 443 -407 25 -43 45 -82%0A45 -86 0 -5 -394 -8 -875 -8 -481 0 -875 2 -875 5 0 3 12 29 26 58 97 191 249%0A338 446 432 53 25 100 45 105 45 20 0 75 70 84 106 4 22 9 249 9 507 l0 467%0A205 0 205 0 0 -483z m737 -1554 c-10 -227 -95 -428 -251 -591 l-59 -62 -632 0%0A-632 0 -60 63 c-156 162 -240 359 -250 585 l-6 122 948 0 948 0 -6 -117z'/%3E%3C/g%3E%3C/svg%3E%0A"); } + +/* "Advance" admonition*/ .md-typeset .admonition.advance, .md-typeset details.advance { border-color: rgb(27, 77, 62); } +.md-typeset .advance > .admonition-title, +.md-typeset .advance > summary, +.md-typeset .experiment > .admonition-title, +.md-typeset .experiment > summary { + background-color: rgba(0, 57, 166, 0.1); + border-color: rgb(0, 57, 166); +} + +.md-typeset .advance > .admonition-title::before, +.md-typeset .advance > summary::before, +.md-typeset .experiment > .admonition-title::before, +.md-typeset .experiment > summary::before { + background-color: rgb(0, 57, 166); + -webkit-mask-image: var(--md-admonition-icon--xadvance); + mask-image: var(--md-admonition-icon--xadvance); +} + +/* "New" admonition*/ .md-typeset .admonition.new, .md-typeset details.new { border-color: rgb(57,255,20); } -.md-typeset .admonition.alert, -.md-typeset details.alert { - border-color: rgb(255, 0, 255); -} - .md-typeset .new > .admonition-title, .md-typeset .new > summary { background-color: rgb(57,255,20,0.1); @@ -64,6 +79,13 @@ limitations under the License. mask-image: var(--md-admonition-icon--new); } + +/* "Alert" admonition*/ +.md-typeset .admonition.alert, +.md-typeset details.alert { + border-color: rgb(255, 0, 255); +} + .md-typeset .alert > .admonition-title, .md-typeset .alert > summary { background-color: rgba(255, 0, 255, 0.1); @@ -77,23 +99,7 @@ limitations under the License. mask-image: var(--md-admonition-icon--alert); } -.md-typeset .advance > .admonition-title, -.md-typeset .advance > summary, -.md-typeset .experiment > .admonition-title, -.md-typeset .experiment > summary { - background-color: rgba(0, 57, 166, 0.1); - border-color: rgb(0, 57, 166); -} - -.md-typeset .advance > .admonition-title::before, -.md-typeset .advance > summary::before, -.md-typeset .experiment > .admonition-title::before, -.md-typeset .experiment > summary::before { - background-color: rgb(0, 57, 166); - -webkit-mask-image: var(--md-admonition-icon--xadvance); - mask-image: var(--md-admonition-icon--xadvance); -} - +/* Custom "Warning" admonition*/ .md-typeset .attention > .admonition-title::before, .md-typeset .attention > summary::before, .md-typeset .caution > .admonition-title::before, @@ -104,6 +110,7 @@ limitations under the License. mask-image: var(--md-admonition-icon--xwarning); } +/* Custom "Tip" admonition*/ .md-typeset .hint > .admonition-title::before, .md-typeset .hint > summary::before, .md-typeset .important > .admonition-title::before, @@ -114,6 +121,7 @@ limitations under the License. mask-image: var(--md-admonition-icon--xtip) !important; } +/* Custom "Info" admonition*/ .md-typeset .info > .admonition-title::before, .md-typeset .info > summary::before, .md-typeset .todo > .admonition-title::before, @@ -122,6 +130,7 @@ limitations under the License. mask-image: var(--md-admonition-icon--xinfo); } +/* Custom "Danger" admonition*/ .md-typeset .danger > .admonition-title::before, .md-typeset .danger > summary::before, .md-typeset .error > .admonition-title::before, @@ -130,12 +139,14 @@ limitations under the License. mask-image: var(--md-admonition-icon--xdanger); } +/* Custom "Note" admonition*/ .md-typeset .note > .admonition-title::before, .md-typeset .note > summary::before { -webkit-mask-image: var(--md-admonition-icon--xnote); mask-image: var(--md-admonition-icon--xnote); } +/* Custom "Abstract" admonition*/ .md-typeset .abstract > .admonition-title::before, .md-typeset .abstract > summary::before, .md-typeset .summary > .admonition-title::before, @@ -146,6 +157,7 @@ limitations under the License. mask-image: var(--md-admonition-icon--xabstract); } +/* Custom "Question" admonition*/ .md-typeset .faq > .admonition-title::before, .md-typeset .faq > summary::before, .md-typeset .help > .admonition-title::before, @@ -156,6 +168,7 @@ limitations under the License. mask-image: var(--md-admonition-icon--xquestion); } +/* Custom "Success" admonition*/ .md-typeset .check > .admonition-title::before, .md-typeset .check > summary::before, .md-typeset .done > .admonition-title::before, @@ -166,6 +179,7 @@ limitations under the License. mask-image: var(--md-admonition-icon--xsuccess); } +/* Custom "Fail" admonition*/ .md-typeset .fail > .admonition-title::before, .md-typeset .fail > summary::before, .md-typeset .failure > .admonition-title::before, @@ -176,18 +190,21 @@ limitations under the License. mask-image: var(--md-admonition-icon--xfail); } +/* Custom "bug" admonition*/ .md-typeset .bug > .admonition-title::before, .md-typeset .bug > summary::before { -webkit-mask-image: var(--md-admonition-icon--xbug); mask-image: var(--md-admonition-icon--xbug); } +/* Custom "Example" admonition*/ .md-typeset .example > .admonition-title::before, .md-typeset .example > summary::before { -webkit-mask-image: var(--md-admonition-icon--xexample); mask-image: var(--md-admonition-icon--xexample); } +/* Custom "Summary" admonition*/ .md-typeset .cite > .admonition-title::before, .md-typeset .cite > summary::before, .md-typeset .quote > .admonition-title::before, @@ -196,24 +213,19 @@ limitations under the License. mask-image: var(--md-admonition-icon--xquote); } + +/* Handles DeFFcode UI */ .md-nav__item--active > .md-nav__link { font-weight: bold; } - .center { display: block; margin-left: auto; margin-right: auto; width: 80%; } - -/* Handles Gitter Sidecard UI */ -.gitter-open-chat-button { - background-color: var(--md-primary-fg-color) !important; - font-family: inherit !important; - font-size: 12px; - -webkit-filter: none !important; - filter: none !important; +.doc-heading { + padding-top: 50px; } .center-small { @@ -246,6 +258,18 @@ limitations under the License. mask-image: var(--md-admonition-icon--failure); } + +/* Handles Gitter Sidecard UI */ +.gitter-open-chat-button { + background-color: var(--md-primary-fg-color) !important; + font-family: inherit !important; + font-size: 12px; + -webkit-filter: none !important; + filter: none !important; +} + + +/* Custom Blockquotes */ blockquote { padding: 0.5em 10px; quotes: "\201C""\201D""\2018""\2019"; @@ -268,8 +292,9 @@ blockquote:after { blockquote p { display: inline; } -/* Handles Responive Video tags (from bootstrap) */ + +/* Handles Responive Video (from bootstrap) */ .video { padding: 0; margin: 0; @@ -322,7 +347,6 @@ blockquote p { } /* Handles footer sponsorship block animation */ - footer.sponsorship { text-align: center; } @@ -343,10 +367,8 @@ footer.sponsorship:not(:hover) .twemoji.heart-throb-hover svg { color: var(--md-default-fg-color--lighter) !important; } -.doc-heading { - padding-top: 50px; -} +/* Custom Button UI */ .btn { z-index: 1; overflow: hidden; @@ -389,6 +411,8 @@ footer.sponsorship:not(:hover) .twemoji.heart-throb-hover svg { width: 100%; } + +/* Heart Animation */ @keyframes heart { 0%, 40%, 80%, 100% { transform: scale(1); @@ -401,6 +425,8 @@ footer.sponsorship:not(:hover) .twemoji.heart-throb-hover svg { animation: heart 1000ms infinite; } + +/* Footer Sponsorship Block */ footer.sponsorship { text-align: center; } @@ -418,12 +444,11 @@ footer.sponsorship { color: var(--md-default-fg-color--lighter) !important; } -/* Tweaks to body appearance */ - + +/* Dark Theme Changes */ [data-md-color-scheme="slate"] { --md-hue: 260; } - body[data-md-color-scheme="slate"] img[class="shadow"]{ -webkit-filter: drop-shadow(2px 2px 1px rgba(0, 0, 0, 0.5)); filter: drop-shadow(2px 2px 1px rgba(0, 0, 0, 0.5)); @@ -447,24 +472,4 @@ body[data-md-color-scheme="slate"] div[class^="admonition"]{ body[data-md-color-scheme="slate"] img[class="shadow2"]{ -webkit-filter: drop-shadow(1px 1px 0 black); filter: drop-shadow(1px 1px 0 black); -} - -/* Glow text effect */ - -x-sign { - color: white; - text-shadow: - 0 0 10px var(--md-code-hl-keyword-color), - 0 0 20px var(--md-code-hl-constant-color), - 0 0 40px var(--md-code-hl-function-color), - 0 0 80px var(--md-code-hl-special-color); - will-change: filter, color; - filter: saturate(60%); - animation: flicker steps(100) 1s 1s infinite; -} - -@keyframes flicker { - 50% { - filter: saturate(150%) hue-rotate(20deg); - } } \ No newline at end of file diff --git a/docs/overrides/main.html b/docs/overrides/main.html index df9f67005..5a5377738 100644 --- a/docs/overrides/main.html +++ b/docs/overrides/main.html @@ -24,7 +24,7 @@ {% endblock %} {% block announce %} - {% include ".icons/material/message-alert.svg" %} Hey, checkout our new Deffcode library that will replace OpenCV soon. We’d love to hear your feedback! + {% include ".icons/material/message-alert.svg" %} Hey, checkout our new Deffcode library which will added as vidgear backend soon. We’d love to hear your feedback! {% endblock %} {% block outdated %} You're not viewing the latest version. @@ -47,9 +47,9 @@ {% block libs %} - - - + + +