diff --git a/README.md b/README.md
index ac9429546..a0aa327d2 100644
--- a/README.md
+++ b/README.md
@@ -427,21 +427,21 @@ In addition to this, WriteGear also provides flexible access to [**OpenCV's Vide
-> _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 streamlines and simplifies the transcoding workflow to generate Ultra-Low Latency, High-Quality, Dynamic & Adaptive Streaming Formats like MPEG-DASH and Apple HLS with just a few lines of Python code, allowing developers to focus on their application logic rather than dealing with the complexities of transcoding and chunking media files._
-StreamGear provides a standalone, highly extensible, and flexible wrapper around [**FFmpeg**][ffmpeg] multimedia framework for generating chunked-encoded media segments of the content.
+StreamGear API provides a standalone, highly extensible, and flexible wrapper around the [**FFmpeg**](https://ffmpeg.org/) multimedia framework for generating chunk-encoded media segments from your multimedia content effortlessly.
-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.
+With StreamGear, you can transcode source video/audio files and real-time video frames into a sequence of multiple smaller chunks/segments of suitable lengths. These segments facilitate streaming at different quality levels _(bitrates or spatial resolutions)_ and allow for seamless switching between quality levels during playback based on available bandwidth. You can serve these segments on a web server, making them easily accessible via standard **HTTP 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 both [**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)_.
-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.
+Additionally, StreamGear generates a manifest file _(such as MPD for DASH)_ or a master playlist _(such as M3U8 for Apple HLS)_ alongside the segments. These files contain essential segment information, _including timing, URLs, and media characteristics like video resolution and adaptive bitrates_. They are provided to the client before the streaming session begins.
**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 :cd: :** 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 :film_frames: :** 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:
diff --git a/docs/gears/netgear/advanced/secure_mode.md b/docs/gears/netgear/advanced/secure_mode.md
index 2f1dddaed..51615363b 100644
--- a/docs/gears/netgear/advanced/secure_mode.md
+++ b/docs/gears/netgear/advanced/secure_mode.md
@@ -33,7 +33,6 @@ Secure Mode uses a new wire protocol, [**ZMTP 3.0**](http://zmtp.org/) that adds
Secure Mode can be easily activated in NetGear API through `secure_mode` attribute of its [`options`](../../params/#options) dictionary parameter, during initialization. Furthermore, for managing this mode, NetGear API provides additional `custom_cert_location` & `overwrite_cert` like attribute too.
-
## Supported ZMQ Security Layers
@@ -47,11 +46,12 @@ Secure mode supports the two most powerful ZMQ security layers:
-
!!! danger "Important Information regarding Secure Mode"
* The `secure_mode` attribute value at the Client's end **MUST** match exactly the Server's end _(i.e. **IronHouse** security layer is only compatible with **IronHouse**, and **NOT** with **StoneHouse**)_.
+ * In Secure Mode, The Client's end **MUST** run before the Server's end to establish a secure connection.
+
* The Public+Secret Keypairs generated at the Server end **MUST** be made available at the Client's end too for successful authentication. If mismatched, connection failure will occur.
* By Default, the Public+Secret Keypairs will be generated/stored at the `$HOME/.vidgear/keys` directory of your machine _(e.g. `/home/foo/.vidgear/keys` on Linux)_. But you can also use [`custom_cert_location`](../../params/#options) attribute to set your own Custom-Path for a directory to generate/store these Keypairs.
@@ -60,8 +60,11 @@ Secure mode supports the two most powerful ZMQ security layers:
* **IronHouse** is the strongest Security Layer available, but it involves certain security checks that lead to **ADDITIONAL LATENCY**.
+
* Secure Mode only supports `libzmq` library version `>= 4.0`.
+
+
@@ -125,10 +128,56 @@ For implementing Secure Mode, NetGear API currently provide following exclusive
Following is the bare-minimum code you need to get started with Secure Mode in NetGear API:
-#### Server's End
+!!! alert "In Secure Mode, Client's end MUST run before the Server's end to establish a secure connection!"
+
+#### Client's End
Open your favorite terminal and execute the following python code:
+!!! tip "You can terminate client anytime by pressing ++ctrl+"C"++ on your keyboard!"
+
+```python linenums="1" hl_lines="6"
+# import required libraries
+from vidgear.gears import NetGear
+import cv2
+
+# activate StoneHouse security mechanism
+options = {"secure_mode": 1}
+
+# define NetGear Client with `receive_mode = True` and defined parameter
+client = NetGear(pattern=1, receive_mode=True, logging=True, **options)
+
+# loop over
+while True:
+
+ # receive frames from network
+ frame = client.recv()
+
+ # check for received frame if Nonetype
+ if frame is None:
+ break
+
+ # {do something with the frame here}
+
+ # Show output window
+ cv2.imshow("Output Frame", frame)
+
+ # check for 'q' key if pressed
+ key = cv2.waitKey(1) & 0xFF
+ if key == ord("q"):
+ break
+
+# close output window
+cv2.destroyAllWindows()
+
+# safely close client
+client.close()
+```
+
+#### Server's End
+
+Then open another terminal on the same system and execute the following python code to send the frames to our client:
+
!!! tip "You can terminate both sides anytime by pressing ++ctrl+"C"++ on your keyboard!"
```python linenums="1" hl_lines="9"
@@ -171,49 +220,7 @@ stream.stop()
server.close()
```
-#### Client's End
-
-Then open another terminal on the same system and execute the following python code and see the output:
-
-!!! tip "You can terminate client anytime by pressing ++ctrl+"C"++ on your keyboard!"
-
-```python linenums="1" hl_lines="6"
-# import required libraries
-from vidgear.gears import NetGear
-import cv2
-
-# activate StoneHouse security mechanism
-options = {"secure_mode": 1}
-
-# define NetGear Client with `receive_mode = True` and defined parameter
-client = NetGear(pattern=1, receive_mode=True, logging=True, **options)
-
-# loop over
-while True:
- # receive frames from network
- frame = client.recv()
-
- # check for received frame if Nonetype
- if frame is None:
- break
-
- # {do something with the frame here}
-
- # Show output window
- cv2.imshow("Output Frame", frame)
-
- # check for 'q' key if pressed
- key = cv2.waitKey(1) & 0xFF
- if key == ord("q"):
- break
-
-# close output window
-cv2.destroyAllWindows()
-
-# safely close client
-client.close()
-```
@@ -222,11 +229,12 @@ client.close()
### Using Secure Mode with Variable Parameters
-
#### Client's End
Open a terminal on Client System _(where you want to display the input frames received from the Server)_ and execute the following python code:
+!!! alert "In Secure Mode, Client's end MUST run before the Server's end to establish a secure connection!"
+
!!! info "Note down the local IP-address of this system(required at Server's end) and also replace it in the following code. You can follow [this FAQ](../../../../help/netgear_faqs/#how-to-find-local-ip-address-on-different-os-platforms) for this purpose."
!!! danger "You need to paste the Public+Secret Keypairs _(generated at the Server End)_ at the `$HOME/.vidgear/keys` directory of your Client machine for a successful authentication!"
diff --git a/docs/gears/streamgear/introduction.md b/docs/gears/streamgear/introduction.md
index 8a12c3b12..9a27fc9c1 100644
--- a/docs/gears/streamgear/introduction.md
+++ b/docs/gears/streamgear/introduction.md
@@ -30,15 +30,15 @@ limitations under the License.
## Overview
-> 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 streamlines and simplifies the transcoding workflow to generate _Ultra-Low Latency, High-Quality, Dynamic & Adaptive Streaming Formats like MPEG-DASH and Apple HLS_ with just a few lines of Python code, allowing developers to focus on their application logic rather than dealing with the complexities of transcoding and chunking media files.
-StreamGear provides a standalone, highly extensible, and flexible wrapper around [**FFmpeg**](https://ffmpeg.org/) multimedia framework for generating chunked-encoded media segments of the content.
+StreamGear API provides a standalone, highly extensible, and flexible wrapper around the [**FFmpeg**](https://ffmpeg.org/) multimedia framework for generating chunk-encoded media segments from your multimedia content effortlessly.
-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.
+With StreamGear, you can transcode source video/audio files and real-time video frames into a sequence of multiple smaller chunks/segments of suitable lengths. These segments facilitate streaming at different quality levels _(bitrates or spatial resolutions)_ and allow for seamless switching between quality levels during playback based on available bandwidth. You can serve these segments on a web server, making them easily accessible via standard **HTTP 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)_.
+SteamGear currently supports both [**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)_.
-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 adaptive bit rates)_ and is provided to the client before the streaming session.
+Additionally, StreamGear generates a manifest file _(such as MPD for DASH)_ or a master playlist _(such as M3U8 for Apple HLS)_ alongside the segments. These files contain essential segment information, _including timing, URLs, and media characteristics like video resolution and adaptive bitrate_. They are provided to the client before the streaming session begins.
!!! alert "For streaming with older traditional protocols such as RTMP, RTSP/RTP you could use [WriteGear](../../writegear/introduction/) API instead."
@@ -59,9 +59,9 @@ SteamGear also creates a Manifest file _(such as MPD in-case of DASH)_ or a Mast
!!! tip "Useful Links"
- - Checkout [this detailed blogpost](https://ottverse.com/mpeg-dash-video-streaming-the-complete-guide/) on how MPEG-DASH works.
- - Checkout [this detailed blogpost](https://ottverse.com/hls-http-live-streaming-how-does-it-work/) on how HLS works.
- - Checkout [this detailed blogpost](https://ottverse.com/hls-http-live-streaming-how-does-it-work/) for HLS vs. MPEG-DASH comparison.
+ - Checkout [this detailed blogpost ➶](https://ottverse.com/mpeg-dash-video-streaming-the-complete-guide/) on how MPEG-DASH works.
+ - Checkout [this detailed blogpost ➶](https://ottverse.com/hls-http-live-streaming-how-does-it-work/) on how HLS works.
+ - Checkout [this detailed blogpost ➶](https://imagekit.io/blog/hls-vs-dash/) for HLS vs. MPEG-DASH comparison.
@@ -71,14 +71,12 @@ SteamGear also creates a Manifest file _(such as MPD in-case of DASH)_ or a Mast
StreamGear primarily operates in following independent modes for transcoding:
-??? warning "Real-time Frames Mode is NOT Live-Streaming."
+???+ alert "Real-time Frames Mode itself is NOT Live-Streaming :material-video-wireless-outline:"
+ To enable live-streaming in Real-time Frames Mode, use the exclusive [`-livestream`](../params/#a-exclusive-parameters) attribute of the `stream_params` dictionary parameter in the StreamGear API. Checkout [this usage example ➶](../rtfm/usage/#bare-minimum-usage-with-live-streaming) for more information.
- Rather, you can enable live-streaming in Real-time Frames Mode by using the exclusive [`-livestream`](../params/#a-exclusive-parameters) attribute of `stream_params` dictionary parameter in StreamGear API. Checkout [this usage example](../rtfm/usage/#bare-minimum-usage-with-live-streaming) for more information.
+- [**Single-Source Mode :material-file-video-outline:**](../ssm/overview) : 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.
-
-- [**Single-Source Mode**](../ssm/overview): 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.
-
-- [**Real-time Frames Mode**](../rtfm/overview): 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.
+- [**Real-time Frames Mode :material-camera-burst:**](../rtfm/overview) : 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.
diff --git a/docs/gears/streamgear/params.md b/docs/gears/streamgear/params.md
index 14575db35..3512b074d 100644
--- a/docs/gears/streamgear/params.md
+++ b/docs/gears/streamgear/params.md
@@ -24,15 +24,13 @@ limitations under the License.
## **`output`**
-This parameter sets the valid filename/path for storing the StreamGear assets _(Manifest file (such as MPD in-case of DASH) or a Master Playlist (such as M3U8 in-case of Apple HLS) & Transcoded sequence of segments)_.
+This parameter sets the valid filename/path for storing the StreamGear assets, including Manifest file _(such as MPD in case of DASH)_ or a Master Playlist _(such as M3U8 in case of Apple HLS)_ and generated sequence of chunks/segments.
-!!! warning "StreamGear API will throw `ValueError` if `output` provided is empty or invalid."
+!!! warning "StreamGear API will throw `ValueError` if the provided `output` is empty or invalid."
-!!! failure "Make sure to provide _valid filename with valid file-extension_ for selected [`format`](#format) value _(such as `.mpd` in case of MPEG-DASH and `.m3u8` in case of APPLE-HLS)_, otherwise StreamGear will throw `AssertionError`."
+!!! failure "Make sure to provide a valid filename with a valid file extension for the selected `format` value _(such as `.mpd` for MPEG-DASH and `.m3u8` for APPLE-HLS)_, otherwise StreamGear will throw `AssertionError`."
-!!! note "StreamGear generated sequence of multiple chunks/segments are also stored in the same directory."
-
-!!! tip "You can easily delete all previous assets at `output` location, by using [`-clear_prev_assets`](#a-exclusive-parameters) attribute of [`stream_params`](#stream_params) dictionary parameter."
+!!! tip "You can easily delete all previous assets at the `output` location by using the [`-clear_prev_assets`](#a-exclusive-parameters) attribute of the [`stream_params`](#stream_params) dictionary parameter."
**Data-Type:** String
@@ -40,60 +38,63 @@ This parameter sets the valid filename/path for storing the StreamGear assets _(
Its valid input can be one of the following:
-* **Path to directory**: Valid path of the directory. In this case, StreamGear API will automatically assign a unique filename for Manifest file. This can be defined as follows:
+* **Path to directory**: Valid path of the directory. In this case, StreamGear API will automatically assign a unique filename for the Manifest file. This can be defined as follows:
=== "DASH"
```python
- streamer = StreamGear(output = "/home/foo/foo1") # Define streamer with manifest saving directory path
+ # Define streamer with output directory path for saving DASH assets
+ streamer = StreamGear(output = "/home/foo/bar")
```
=== "HLS"
```python
- streamer = StreamGear(output = "/home/foo/foo1", format="hls") # Define streamer with playlist saving directory path
+ # Define streamer with output directory path for saving HLS assets
+ streamer = StreamGear(output = "/home/foo/bar", format="hls")
```
-* **Filename** _(with/without path)_: Valid filename(_with valid extension_) of the output Manifest file. In case filename is provided without path, then current working directory will be used.
+* **Filename** _(with/without path)_: Valid filename _(with a valid extension)_ of the output Manifest or Playlist file. If the filename is provided without a path, the current working directory will be used. This can be defined as follows:
=== "DASH"
```python
- streamer = StreamGear(output = "output_foo.mpd") # Define streamer with manifest file name
+ # Define streamer with output manifest filename
+ streamer = StreamGear(output = "output_dash.mpd")
```
=== "HLS"
```python
- streamer = StreamGear(output = "output_foo.m3u8", format="hls") # Define streamer with playlist file name
+ # Define streamer with output playlist filename
+ streamer = StreamGear(output = "output_hls.m3u8", format="hls")
```
-* **URL**: Valid URL of a network stream with a protocol supported by installed FFmpeg _(verify with command `ffmpeg -protocols`)_ only. This is useful for directly storing assets to a network server. For example, you can use a `http` protocol URL as follows:
-
+* **URL**: Valid URL of a network stream with a protocol supported by the installed FFmpeg _(verify with the `ffmpeg -protocols` command)_. This is useful for directly storing assets to a network server. For example, you can use an `HTTP` protocol URL as follows:
=== "DASH"
```python
- streamer = StreamGear(output = "http://195.167.1.101/live/test.mpd") #Define streamer
+ # Define streamer with output manifest URL
+ streamer = StreamGear(output = "http://some_dummy_serverip/live/output_dash.mpd")
```
=== "HLS"
```python
- streamer = StreamGear(output = "http://195.167.1.101/live/test.m3u8", format="hls") #Define streamer
+ # Define streamer with output playlist URL
+ streamer = StreamGear(output = "http://some_dummy_serverip/live/output_hls.m3u8", format="hls")
```
## **`format`**
+This parameter enables the adaptive HTTP streaming format. This parameter currently supported these formats: `dash` _(i.e [**MPEG-DASH**](https://www.encoding.com/mpeg-dash/))_ and `hls` _(i.e [**Apple HLS**](https://developer.apple.com/documentation/http_live_streaming))_.
-This parameter select the adaptive HTTP streaming formats. For now, the supported format are: `dash` _(i.e [**MPEG-DASH**](https://www.encoding.com/mpeg-dash/))_ and `hls` _(i.e [**Apple HLS**](https://developer.apple.com/documentation/http_live_streaming))_.
-
-!!! warning "Any invalid value to `format` parameter will result in ValueError!"
-
-!!! failure "Make sure to provide _valid filename with valid file-extension_ in [`output`](#output) for selected `format` value _(such as `.mpd` in case of MPEG-DASH and `.m3u8` in case of APPLE-HLS)_, otherwise StreamGear will throw `AssertionError`."
+!!! danger "Make sure to provide a valid filename with a valid file extension in the [`output`](#output) parameter for the selected `format` value _(i.e., `.mpd` for MPEG-DASH and `.m3u8` for APPLE-HLS)_, otherwise StreamGear will throw an `AssertionError`."
+!!! warning "Any improper value assigned to `format` parameter will result in a `ValueError`!"
**Data-Type:** String
@@ -104,16 +105,17 @@ This parameter select the adaptive HTTP streaming formats. For now, the supporte
=== "DASH"
```python
- StreamGear(output = "output_foo.mpd", format="dash")
+ # Define streamer with DASH format
+ StreamGear(output = "output_dash.mpd", format="dash")
```
=== "HLS"
```python
- StreamGear(output = "output_foo.m3u8", format="hls")
+ # Define streamer with HLS format
+ StreamGear(output = "output_hls.m3u8", format="hls")
```
-
@@ -121,9 +123,10 @@ This parameter select the adaptive HTTP streaming formats. For now, the supporte
This parameter assigns the custom _path/directory_ where the custom/downloaded FFmpeg executables are located.
-!!! info "Behavior on Windows"
+!!! info "Behavior on :fontawesome-brands-windows: Windows Systems"
+
+ On Windows, if a custom FFmpeg executable's path/directory is not provided through this `custom_ffmpeg` parameter, the StreamGear API will automatically attempt to download and extract suitable Static FFmpeg binaries at a suitable location on your Windows machine. More information can be found [here ➶](../ffmpeg_install/#a-auto-installation).
- If a custom FFmpeg executable's path | directory is not provided through `custom_ffmpeg` parameter on Windows machine, then StreamGear API will ==automatically attempt to download and extract suitable Static FFmpeg binaries at suitable location on your windows machine==. More information can be found [here ➶](../ffmpeg_install/#a-auto-installation).
**Data-Type:** String
@@ -132,8 +135,8 @@ This parameter assigns the custom _path/directory_ where the custom/downloaded F
**Usage:**
```python
-# If ffmpeg executables are located at "/foo/foo1/ffmpeg"
-StreamGear(output = 'output_foo.mpd', custom_ffmpeg="/foo/foo1/ffmpeg")
+# Define streamer with custom ffmpeg binary
+StreamGear(output = 'output_foo.mpd', custom_ffmpeg="C://foo//bar//ffmpeg.exe")
```
@@ -141,11 +144,9 @@ StreamGear(output = 'output_foo.mpd', custom_ffmpeg="/foo/foo1/ffmpeg")
## **`stream_params`**
-This parameter allows us to exploit almost all FFmpeg supported parameters effortlessly and flexibly change its internal settings for transcoding and seamlessly generating high-quality streams. All [supported parameters](#supported-parameters) can formatting as attributes for this dictionary parameter:
-
-
-!!! danger "Kindly read [**FFmpeg Docs**](https://ffmpeg.org/documentation.html) carefully, before passing any additional values to `stream_params` parameter. Wrong values may result in undesired errors or no output at all."
+This parameter allows developers to leverage nearly all FFmpeg options, providing effortless and flexible control over its internal settings for transcoding and generating high-quality streams. All [supported parameters](#supported-parameters) can be formatted as attributes within this dictionary parameter.
+!!! danger "Please read the [**FFmpeg Documentation**](https://ffmpeg.org/documentation.html) carefully before passing any additional values to the `stream_params` parameter. Incorrect values may cause errors or result in no output."
**Data-Type:** Dictionary
@@ -158,183 +159,219 @@ This parameter allows us to exploit almost all FFmpeg supported parameters effor
StreamGear API provides some exclusive internal parameters to easily generate Streaming Assets and effortlessly tweak its internal properties. These parameters are discussed below:
-* **`-streams`** _(list of dicts)_: This important attribute makes it simple and pretty straight-forward to define additional multiple streams as _list of dictionaries_ of different quality levels _(i.e. different bitrates or spatial resolutions)_ for streaming.
+* **`-streams`** _(list of dicts)_: This important attribute makes it simple and pretty straight-forward to define additional multiple streams as _list of dictionaries_ of different quality levels _(i.e. different bitrate or spatial resolutions)_ for streaming.
+
+ ???+ danger "Important Information about `-streams` attribute :material-file-document-alert-outline:"
- !!! danger "Important `-streams` attribute facts"
- * ==On top of these additional streams, StreamGear by default, generates a primary stream of same resolution and framerate[^1] as the input Video, at the index `0`.==
- * You **MUST** need to define `-resolution` value for your stream, otherwise stream will be discarded!
- * You only need either of `-video_bitrate` or `-framerate` for defining a valid stream. Since with `-framerate` value defined, video-bitrate is calculated automatically using `-bpps` and `-resolution` values.
- * If you define both `-video_bitrate` and `-framerate` values at the same time, StreamGear will discard the `-framerate` value automatically.
+ * In addition to the user-defined Secondary Streams, ==StreamGear automatically generates a Primary Stream _(at index `0`)_ with the same resolution as the input frames and at default framerate[^1], at the index `0`.==
+ * You **MUST** define the `-resolution` value for each stream; otherwise, the stream will be discarded.
+ * You only need to define either the `-video_bitrate` or the `-framerate` for a valid stream.
+ * If you specify the `-framerate`, the video bitrate will be calculated automatically.
+ * If you define both the `-video_bitrate` and the `-framerate`, the `-framerate` will get discard automatically.
- **To construct the additional stream dictionaries, you'll will need following sub-attributes:**
+ **To construct the additional stream dictionaries, you will need the following sub-attributes::**
- * `-resolution` _(string)_: It is **compulsory** to define the required resolution/dimension/size for the stream, otherwise given stream will be rejected. Its value can be a `"{width}x{height}"` as follows:
+ * `-resolution` _(string)_: It is **compulsory** to define the required resolution/dimension/size for the stream, otherwise, the given stream will be rejected. Its value should be in the format `"{width}x{height}"`, as shown below:
```python
- "-streams" = [{"-resolution": "1280x720"}] # to produce a 1280x720 resolution/scale
+ # produce a 1280x720 resolution/scale stream
+ "-streams" = [{"-resolution": "1280x720"}]
```
- * `-video_bitrate` _(string)_: It is an **optional** _(can be ignored if `-framerate` parameter is defined)_ sub-attribute that generally determines the bandwidth and quality of stream, i.e. the higher the bitrate, the better the quality and the larger will be bandwidth and more will be strain on network. It value is generally in `kbps` _(kilobits per second)_ for OBS (Open Broadcasting Softwares). You can easily define this attribute as follows:
+ * `-video_bitrate` _(string)_: This is an **optional** sub-attribute _(can be ignored if the `-framerate` parameter is defined)_ that generally determines the bandwidth and quality of the stream. The higher the bitrate, the better the quality and the larger the bandwidth, which can place more strain on the network. Its value is typically in `k` _(kilobits per second)_ or `M` _(Megabits per second)_. Define this attribute as follows:
```python
- "-streams" : [{"-resolution": "1280x720", "-video_bitrate": "2000k"}] # to produce a 1280x720 resolution and 2000kbps bitrate stream
+ # produce a 1280x720 resolution and 2000 kbps bitrate stream
+ "-streams" : [{"-resolution": "1280x720", "-video_bitrate": "2000k"}]
```
- * `-framerate` _(float/int)_: It is another **optional** _(can be ignored if `-video_bitrate` parameter is defined)_ sub-attribute that defines the assumed framerate for the stream. It's value can be float/integer as follows:
+ * `-framerate` _(float/int)_: This is another **optional** sub-attribute _(can be ignored if the `-video_bitrate` parameter is defined)_ that defines the assumed framerate for the stream. Its value can be a float or integer, as shown below:
```python
- "-streams" : [{"-resolution": "1280x720", "-framerate": "60.0"}] # to produce a 1280x720 resolution and 60fps framerate stream
+ # produce a 1280x720 resolution and 60fps framerate stream
+ "-streams" : [{"-resolution": "1280x720", "-framerate": "60.0"}]
```
**Usage:** You can easily define any number of streams using `-streams` attribute as follows:
- !!! tip "Usage example can be found [here ➶](../ssm/usage/#usage-with-additional-streams)"
-
```python
stream_params =
{"-streams":
- [{"-resolution": "1920x1080", "-video_bitrate": "4000k"}, # Stream1: 1920x1080 at 4000kbs bitrate
- {"-resolution": "1280x720", "-framerate": "30.0"}, # Stream2: 1280x720 at 30fps
- {"-resolution": "640x360", "-framerate": "60.0"}, # Stream3: 640x360 at 60fps
- ]}
+ [
+ {"-resolution": "1920x1080", "-video_bitrate": "4000k"}, # Stream1: 1920x1080 at 4000kbs bitrate
+ {"-resolution": "1280x720", "-framerate": 30}, # Stream2: 1280x720 at 30fps
+ {"-resolution": "640x360", "-framerate": 60.0}, # Stream3: 640x360 at 60fps
+ ]
+ }
```
+ !!! example "Its usage example can be found [here ➶](../ssm/usage/#usage-with-additional-streams)"
+
-* **`-video_source`** _(string)_: This attribute takes valid Video path as input and activates [**Single-Source Mode**](../ssm/overview), for transcoding it into multiple smaller chunks/segments for streaming after successful validation. Its value be one of the following:
+* **`-video_source`** _(string)_: This attribute takes a valid video path as input and activates [**Single-Source Mode**](../ssm/overview), for transcoding it into multiple smaller chunks/segments for streaming after successful validation. Its value can be one of the following:
- !!! tip "Usage example can be found [here ➶](../ssm/usage/#bare-minimum-usage)"
+ * **Video Filename**: Valid path to a video file as follows:
- * **Video Filename**: Valid path to Video file as follows:
```python
- stream_params = {"-video_source": "/home/foo/foo1.mp4"} # set input video source: /home/foo/foo1.mp4
+ # set video source as `/home/foo/bar.mp4`
+ stream_params = {"-video_source": "/home/foo/bar.mp4"}
```
* **Video URL**: Valid URL of a network video stream as follows:
- !!! danger "Make sure given Video URL has protocol that is supported by installed FFmpeg. _(verify with `ffmpeg -protocols` terminal command)_"
+ !!! danger "Ensure the given video URL uses a protocol supported by the installed FFmpeg _(verify with `ffmpeg -protocols` terminal command)_."
```python
- stream_params = {"-video_source": "http://livefeed.com:5050"} # set input video source: http://livefeed.com:5050
+ # set video source as `http://livefeed.com:5050`
+ stream_params = {"-video_source": "http://livefeed.com:5050"}
```
+ !!! example "Its usage example can be found [here ➶](../ssm/usage/#bare-minimum-usage)"
+
+* **`-audio`** _(string/list)_: This attribute takes an external custom audio path _(as a string)_ or an audio device name followed by a suitable demuxer _(as a list)_ as the audio source input for all StreamGear streams. Its value can be one of the following:
-* **`-audio`** _(string/list)_: This attribute takes external custom audio path _(as `string`)_ or audio device name followed by suitable demuxer _(as `list`)_ as audio source input for all StreamGear streams. Its value be one of the following:
+ !!! failure "Ensure the provided `-audio` audio source is compatible with the input video source. Incompatibility can cause multiple errors or result in no output at all."
- !!! failure "Make sure this audio-source is compatible with provided video -source, otherwise you could encounter multiple errors, or even no output at all!"
+ * **Audio Filename** _(string)_: Valid path to an audio file as follows:
- * **Audio Filename** _(string)_: Valid path to Audio file as follows:
```python
- stream_params = {"-audio": "/home/foo/foo1.aac"} # set input audio source: /home/foo/foo1.aac
+ # set audio source as `/home/foo/foo1.aac`
+ stream_params = {"-audio": "/home/foo/foo1.aac"}
```
- !!! tip "Usage example can be found [here ➶](../ssm/usage/#usage-with-custom-audio)"
+
+ !!! example "Its usage examples can be found [here ➶](../ssm/usage/#usage-with-custom-audio) and [here ➶](../ssm/usage/#usage-with-file-audio-input)"
* **Audio URL** _(string)_: Valid URL of a network audio stream as follows:
- !!! danger "Make sure given Video URL has protocol that is supported by installed FFmpeg. _(verify with `ffmpeg -protocols` terminal command)_"
+ !!! danger "Ensure the given audio URL uses a protocol supported by the installed FFmpeg _(verify with `ffmpeg -protocols` terminal command)_."
```python
- stream_params = {"-audio": "https://exampleaudio.org/example-160.mp3"} # set input audio source: https://exampleaudio.org/example-160.mp3
+ # set input audio source as `https://exampleaudio.org/example-160.mp3`
+ stream_params = {"-audio": "https://exampleaudio.org/example-160.mp3"}
```
- * **Device name and Demuxer** _(list)_: Valid audio device name followed by suitable demuxer as follows:
+ * **Device name and Demuxer** _(list)_: Valid audio device name followed by a suitable demuxer as follows:
```python
- stream_params = {"-audio": "https://exampleaudio.org/example-160.mp3"} # set input audio source: https://exampleaudio.org/example-160.mp3
+ # Assign appropriate input audio-source device (compatible with video source) and its demuxer
+ stream_params = {"-audio": [
+ "-f",
+ "dshow",
+ "-i",
+ "audio=Microphone (USB2.0 Camera)",
+ ]}
```
- !!! tip "Usage example can be found [here ➶](../rtfm/usage/#usage-with-device-audio--input)"
-
+ !!! example "Its usage example can be found [here ➶](../rtfm/usage/#usage-with-device-audio--input)"
-* **`-livestream`** _(bool)_: ***(optional)*** specifies whether to enable **Livestream Support**_(chunks will contain information for new frames only)_ for the selected mode, or not. You can easily set it to `True` to enable this feature, and default value is `False`. It can be used as follows:
+* **`-livestream`** _(bool)_: ***(optional)*** specifies whether to enable **Low-latency Live-Streaming :material-video-wireless-outline:** in Real-time Frames Mode only, where chunks will contain information for new frames only and forget previous ones, or not. The default value is `False`. It can be used as follows:
- !!! tip "Use `window_size` & `extra_window_size` FFmpeg parameters for controlling number of frames to be kept in New Chunks."
+ !!! warning "The `-livestream` optional parameter is **NOT** supported in [Single-Source mode](../ssm/overview)."
```python
- stream_params = {"-livestream": True} # enable livestreaming
+ stream_params = {"-livestream": True} # enable live-streaming
```
-
+ !!! example "Its usage example can be found [here ➶](../rtfm/usage/#bare-minimum-usage-with-live-streaming)"
-* **`-input_framerate`** _(float/int)_ : ***(optional)*** specifies the assumed input video source framerate, and only works in [Real-time Frames Mode](../usage/#b-real-time-frames-mode). It can be used as follows:
+
- !!! tip "Usage example can be found [here ➶](../rtfm/usage/#bare-minimum-usage-with-controlled-input-framerate)"
+* **`-input_framerate`** _(float/int)_ : ***(optional)*** This parameter specifies the assumed input video source framerate and only works in [Real-time Frames Mode](../usage/#b-real-time-frames-mode). Its default value is `25.0` fps. Its value can be a float or integer, as shown below:
```python
- stream_params = {"-input_framerate": 60.0} # set input video source framerate to 60fps
+ # set input video source framerate to 60fps
+ stream_params = {"-input_framerate": 60.0}
```
+ !!! example "Its usage example can be found [here ➶](../rtfm/usage/#bare-minimum-usage-with-controlled-input-framerate)"
+
-* **`-bpp`** _(float/int)_: ***(optional)*** This attribute controls constant _Bits-Per-Pixel_(BPP) value, which is kind of a constant value to ensure good quality of high motion scenes ,and thereby used in calculating desired video-bitrate for streams. Higher the BPP, better will be motion quality. Its default value is `0.1`. Going over `0.1`helps to fill gaps between current bitrate and upload limit/ingest cap. Its value can be anything above `0.001`, can be used as follows:
+* **`-bpp`** _(float/int)_: ***(optional)*** This attribute controls the constant **BPP** _(Bits-Per-Pixel)_ value, which helps ensure good quality in high motion scenes by determining the desired video bitrate for streams. A higher BPP value improves motion quality. The default value is `0.1`. Increasing the BPP value helps fill the gaps between the current bitrate and the upload limit/ingest cap. Its value can be anything above `0.001` and can be used as follows:
- !!! tip "Important BPP tips for streaming"
- * `-bpp` a sensitive value, try 0.001, and then make increments in 0.0001 to fine tune
- * If your desired resolution/fps/audio combination is below maximum service bitrate, raise BPP to match it for extra quality.
- * It is generally better to lower resolution (and/or fps) and raise BPP than raise resolution and loose on BPP.
+ !!! tip "Important points while tweaking BPP"
+ * BPP is a sensitive value; start with `0.001` and make small increments (`0.0001`) to fine-tune.
+ * If your desired resolution/fps/audio combination is below the maximum service bitrate, raise BPP to match it for extra quality.
+ * It is generally better to lower resolution _(and/or `fps`)_ and raise BPP than to raise resolution and lose BPP.
```python
- stream_params = {"-bpp": 0.05} # sets BPP to 0.05
+ # sets BPP to 0.05
+ stream_params = {"-bpp": 0.05}
```
-* **`-gop`** _(float/int)_ : ***(optional)*** specifies the number of frames between two I-frames for accurate GOP length. By increasing the length of the GOP, there will be fewer I-frames per time frame, which minimizes bandwidth consumption. So, for example, with extremely complex subjects such as water sports or action mode, you’ll want to use a shorter GOP length such as 15 or below that results in excellent video quality. For more static video such as talking heads, then much longer GOP sizes are not only sufficient but also more efficient. It can be used as follows:
+* **`-gop`** _(float/int)_ : ***(optional)*** This parameter specifies the number of frames between two I-frames for accurate **GOP** _(Group of Pictures)_ length. Increasing the GOP length reduces the number of I-frames per time frame, minimizing bandwidth consumption. For example, with complex subjects such as water sports or action scenes, a shorter GOP length _(e.g., `15` or below)_ results in excellent video quality. For more static video, such as talking heads, much longer GOP sizes are not only sufficient but also more efficient. It can be used as follows:
- !!! tip "The larger the GOP size, the more efficient the compression and the less bandwidth you will need"
+ !!! tip "The larger the GOP size, the more efficient the compression and the less bandwidth you will need."
- !!! info "By default, StreamGear automatically sets recommended fixed GOP value _(i.e. every two seconds)_ w.r.t input framerate and selected encoder."
+ !!! info "By default, StreamGear automatically sets a recommended fixed GOP value _(i.e., every two seconds)_ based on the input framerate and selected encoder."
```python
- stream_params = {"-gop": 70} # set GOP length to 70
+ # set GOP length to 70
+ stream_params = {"-gop": 70}
```
-* **`-clones`** _(list)_: ***(optional)*** sets the special FFmpeg parameters that are repeated more than once in the command _(For more info., see [this issue](https://github.com/abhiTronix/vidgear/issues/141))_ as **list** only. Usage is as follows:
+* **`-clones`** _(list)_: ***(optional)*** This parameter sets special FFmpeg options that need to be repeated more than once in the command. For more information, see [this issue](https://github.com/abhiTronix/vidgear/issues/141). It accepts values as a **list** only. Usage is as follows:
```python
+ # sets special FFmpeg options repeated multiple times
stream_params = {"-clones": ['-map', '0:v:0', '-map', '1:a?']}
```
-* **`-ffmpeg_download_path`** _(string)_: ***(optional)*** sets the custom directory for downloading FFmpeg Static Binaries in Compression Mode, during the [Auto-Installation](../ffmpeg_install/#a-auto-installation) on Windows Machines Only. If this parameter is not altered, then these binaries will auto-save to the default temporary directory (for e.g. `C:/User/temp`) on your windows machine. It can be used as follows:
+* **`-ffmpeg_download_path`** _(string)_: ***(optional)*** This parameter sets a custom directory for downloading FFmpeg static binaries in Compression Mode during the [**Auto-Installation**](../ffmpeg_install/#a-auto-installation) step on Windows machines only. If this parameter is not altered, the binaries will be saved to the default temporary directory _(e.g., `C:/User/foo/temp`)_ on your Windows machine. It can be used as follows:
```python
- stream_params = {"-ffmpeg_download_path": "C:/User/foo/foo1"} # will be saved to "C:/User/foo/foo1"
+ # download FFmpeg static binaries to `C:/User/foo/bar`
+ stream_params = {"-ffmpeg_download_path": "C:/User/foo/bar"}
```
-* **`-clear_prev_assets`** _(bool)_: ***(optional)*** specify whether to force-delete any previous copies of StreamGear Assets _(i.e. Manifest files(.mpd) & streaming chunks(.m4s) etc.)_ present at path specified by [`output`](#output) parameter. You can easily set it to `True` to enable this feature, and default value is `False`. It can be used as follows:
+* **`-clear_prev_assets`** _(bool)_: ***(optional)*** This parameter specifies whether to force-delete any previous copies of StreamGear assets _(i.e., manifest (`mpd`), playlist (`mu38`), and streaming chunks (`.m4s`), etc. files)_ present at the path specified by the [`output`](#output) parameter. The default value is `False`. It can be used as follows:
- !!! info "In Single-Source Mode, additional segments _(such as `.webm`, `.mp4` chunks)_ are also cleared automatically."
+ !!! info "Additional segments _(such as `.webm`, `.mp4` chunks)_ are also cleared automatically."
```python
- stream_params = {"-clear_prev_assets": True} # will delete all previous assets
+ # delete all previous assets
+ stream_params = {"-clear_prev_assets": True}
```
-#### B. FFmpeg Parameters
+* **`-enable_force_termination`** _(bool)_: sets a special flag to enable the forced termination of the FFmpeg process, required only if StreamGear is getting frozen when terminated. Its usage is as follows:
+
+ !!! warning "The `-enable_force_termination` flag can potentially cause unexpected behavior or corrupted output in certain scenarios. It is recommended to use this flag with caution."
-Almost all FFmpeg parameter can be passed as dictionary attributes in `stream_params`. For example, for using `libx264 encoder` to produce a lossless output video, we can pass required FFmpeg parameters as dictionary attributes, as follows:
+ ```python
+ # enables forced termination of FFmpeg process
+ stream_params = {"-enable_force_termination": True}
+ ```
+
+
-!!! tip "Kindly check [H.264 docs ➶](https://trac.ffmpeg.org/wiki/Encode/H.264) and other [FFmpeg Docs ➶](https://ffmpeg.org/documentation.html) for more information on these parameters"
+#### B. FFmpeg Parameters
+Almost all FFmpeg parameters can be passed as dictionary attributes in `stream_params`. For example, to use the `libx264` encoder to produce a lossless output video, you can pass the required FFmpeg parameters as dictionary attributes as follows:
-!!! failure "All ffmpeg parameters are case-sensitive. Remember to double check every parameter if any error occurs."
+!!! tip "Please check the [H.264 documentation ➶](https://trac.ffmpeg.org/wiki/Encode/H.264) and [FFmpeg Documentation ➶](https://ffmpeg.org/documentation.html) for more information on following parameters."
+!!! failure "All FFmpeg parameters are case-sensitive. Double-check each parameter if any errors occur."
-!!! note "In addition to these parameters, almost any FFmpeg parameter _(supported by installed FFmpeg)_ is also supported. But make sure to read [**FFmpeg Docs**](https://ffmpeg.org/documentation.html) carefully first."
+!!! note "In addition to these parameters, almost any FFmpeg parameter _(supported by the installed FFmpeg)_ is also supported. Be sure to read the [**FFmpeg Documentation**](https://ffmpeg.org/documentation.html) carefully first."
```python
+# libx264 encoder and its supported parameters
stream_params = {"-vcodec":"libx264", "-crf": 0, "-preset": "fast", "-tune": "zerolatency"}
```
@@ -342,9 +379,11 @@ stream_params = {"-vcodec":"libx264", "-crf": 0, "-preset": "fast", "-tune": "ze
### Supported Encoders and Decoders
-All the encoders and decoders that are compiled with FFmpeg in use, are supported by WriteGear API. You can easily check the compiled encoders by running following command in your terminal:
+All encoders and decoders compiled with the FFmpeg in use are supported by the StreamGear API. You can check the compiled encoders by running the following command in your terminal:
+
+!!! warning "Stream copy (`-vcodec copy`) is not compatible with Real-time Frames Mode as this mode requires re-encoding of incoming frames."
-!!! info "Similarily, supported demuxers and filters depends upons compiled FFmpeg in use."
+!!! info "Similarly, supported audio/video demuxers and filters depend on the FFmpeg binaries in use."
```sh
# for checking encoder
diff --git a/docs/gears/streamgear/rtfm/overview.md b/docs/gears/streamgear/rtfm/overview.md
index 13e78154b..f213821cb 100644
--- a/docs/gears/streamgear/rtfm/overview.md
+++ b/docs/gears/streamgear/rtfm/overview.md
@@ -18,7 +18,7 @@ limitations under the License.
===============================================
-->
-# StreamGear API: Real-time Frames Mode
+# StreamGear API: Real-time Frames Mode :material-camera-burst: