class_docstr: 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, a leading multimedia framework. WriteGear can process real-time frames into a lossless
  compressed video-file with any suitable specification (such as bitrate, codec, framerate, resolution, subtitles, etc.). It is powerful enough to perform complex tasks such as
  Live-Streaming (such as for Twitch) and Multiplexing Video-Audio with real-time frames in way fewer lines of code.
  
  Best of all, WriteGear grants users the complete freedom to play with any FFmpeg parameter with its exclusive Custom Commands function without relying on any
  third-party API.
  
  In addition to this, WriteGear also provides flexible access to OpenCV's VideoWriter API tools for video-frames encoding without compression.
  
  ??? tip "Modes of Operation"
  
      WriteGear primarily operates in following modes:
  
      * **Compression Mode**: In this mode, WriteGear utilizes powerful **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.
  
      * **Non-Compression Mode**: In this mode, WriteGear utilizes basic **OpenCV's inbuilt VideoWriter API** tools. This mode also supports all
                                  parameters manipulation available within VideoWriter API, but it lacks the ability to manipulate encoding parameters
                                  and other important features like video compression, audio encoding, etc.
class_docstr_tok: ["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",",","a","leading","multimedia","framework",".","WriteGear","can","process","real-time","frames","into","a","lossless","compressed","video-file","with","any","suitable","specification","(","such","as","bitrate",",","codec",",","framerate",",","resolution",",","subtitles",",","etc.",")",".","It","is","powerful","enough","to","perform","complex","tasks","such","as","Live-Streaming","(","such","as","for","Twitch",")","and","Multiplexing","Video-Audio","with","real-time","frames","in","way","fewer","lines","of","code",".","Best","of","all",",","WriteGear","grants","users","the","complete","freedom","to","play","with","any","FFmpeg","parameter","with","its","exclusive","Custom","Commands","function","without","relying","on","any","third-party","API",".","In","addition","to","this",",","WriteGear","also","provides","flexible","access","to","OpenCV","'s","VideoWriter","API","tools","for","video-frames","encoding","without","compression",".","?","?","?","tip","``","Modes","of","Operation","''","WriteGear","primarily","operates","in","following","modes",":","*","*","*","Compression","Mode","*","*",":","In","this","mode",",","WriteGear","utilizes","powerful","*","*","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",".","*","*","*","Non-Compression","Mode","*","*",":","In","this","mode",",","WriteGear","utilizes","basic","*","*","OpenCV","'s","inbuilt","VideoWriter","API","*","*","tools",".","This","mode","also","supports","all","parameters","manipulation","available","within","VideoWriter","API",",","but","it","lacks","the","ability","to","manipulate","encoding","parameters","and","other","important","features","like","video","compression",",","audio","encoding",",","etc","."]
docstr: Pipelines `ndarray` frames to respective API _(**FFmpeg** in Compression Mode & **OpenCV's VideoWriter API** in Non-Compression Mode)_.
  
  Parameters:
      frame (ndarray): a valid numpy frame
      rgb_mode (boolean): enable this flag to activate RGB mode _(i.e. specifies that incoming frames are of RGB format(instead of default BGR)_.
docstr_tok: ["Pipelines","`","ndarray","`","frames","to","respective","API","_","(","*","*","FFmpeg","*","*","in","Compression","Mode","&","*","*","OpenCV","'s","VideoWriter","API","*","*","in","Non-Compression","Mode",")","_.","Parameters",":","frame","(","ndarray",")",":","a","valid","numpy","frame","rgb_mode","(","boolean",")",":","enable","this","flag","to","activate","RGB","mode","_","(","i.e",".","specifies","that","incoming","frames","are","of","RGB","format","(","instead","of","default","BGR",")","_","."]
code: def write(self, frame, rgb_mode=False):
      """
      Pipelines `ndarray` frames to respective API _(**FFmpeg** in Compression Mode & **OpenCV's VideoWriter API** in Non-Compression Mode)_.
  
      Parameters:
          frame (ndarray): a valid numpy frame
          rgb_mode (boolean): enable this flag to activate RGB mode _(i.e. specifies that incoming frames are of RGB format(instead of default BGR)_.
  
      """
      if frame is None:  # None-Type frames will be skipped
          return
  
      # get height, width, number of channels, and dtype of current frame
      height, width = frame.shape[:2]
      channels = frame.shape[-1] if frame.ndim == 3 else 1
      dtype = frame.dtype
  
      # assign values to class variables on first run
      if self.__initiate_process:
          self.__inputheight = height
          self.__inputwidth = width
          self.__inputchannels = channels
          self.__inputdtype = dtype
          self.__logging and logger.debug(
              "InputFrame => Height:{} Width:{} Channels:{} Datatype:{}".format(
                  self.__inputheight,
                  self.__inputwidth,
                  self.__inputchannels,
                  self.__inputdtype,
              )
          )
  
      # validate frame size
      if height != self.__inputheight or width != self.__inputwidth:
          raise ValueError(
              "[WriteGear:ERROR] :: All video-frames must have same size!"
          )
      # validate number of channels in frame
      if channels != self.__inputchannels:
          raise ValueError(
              "[WriteGear:ERROR] :: All video-frames must have same number of channels!"
          )
      # validate frame datatype
      if dtype != self.__inputdtype:
          raise ValueError(
              "[WriteGear:ERROR] :: All video-frames must have same datatype!"
          )
  
      # checks if compression mode is enabled
      if self.__compression:
          # initiate FFmpeg process on first run
          if self.__initiate_process:
              # start pre-processing of FFmpeg parameters, and initiate process
              self.__PreprocessFFParams(
                  channels, dtype=dtype, rgb=rgb_mode
              )
              # Check status of the process
              assert self.__process is not None
          try:
              # try writing the frame bytes to the subprocess pipeline
              self.__process.stdin.write(frame.tobytes())
          except (OSError, IOError):
              # log if something is wrong!
              logger.error(
                  "BrokenPipeError caught, Wrong values passed to FFmpeg Pipe. Kindly Refer Docs!"
              )
              raise ValueError  # for testing purpose only
      else:
          # otherwise initiate OpenCV's VideoWriter Class process
          if self.__initiate_process:
              # start VideoWriter Class process
              self.__start_CVProcess()
              # Check status of the process
              assert self.__process is not None
              # log one-time OpenCV warning
              self.__logging and logger.info(
                  "RGBA and 16-bit grayscale video frames are not supported by OpenCV yet. Kindly switch on `compression_mode` to use them!"
              )
          # write frame directly to
          # VideoWriter Class process
          self.__process.write(frame)
  
file_path: vidgear/vidgear/gears/writegear.py
imports: import os
  import cv2
  import time
  import platform
  import pathlib
  import logging
  import subprocess
  from .helper import capPropId, dict2Args, is_valid_url, logger_handler, check_WriteAccess, get_valid_ffmpeg_path, get_supported_pixfmts, get_supported_vencoders, check_gstreamer_support, logcurr_vidgear_ver
label_desc: Use image node_id 2 for calling the WriteGear obj's underlying member method code with example usage: obj.write(frame, rgb_mode) without return types