class_docstr: StreamGear automates transcoding workflow for generating Ultra-Low Latency, High-Quality, Dynamic & Adaptive Streaming Formats (such as MPEG-DASH and HLS) in just few lines of python code.
  StreamGear provides a standalone, highly extensible, and flexible wrapper around FFmpeg multimedia framework for generating chunked-encoded media segments of the content.
  
  SteamGear easily transcodes source videos/audio files & real-time video-frames and breaks them into a sequence of multiple smaller chunks/segments of suitable length. 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 also creates a Manifest/Playlist file (such as MPD in-case of DASH and M3U8 in-case of 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.
  
  SteamGear currently supports MPEG-DASH (Dynamic Adaptive Streaming over HTTP, ISO/IEC 23009-1) and Apple HLS (HTTP live streaming).
docstr: This constructor method initializes the object state and attributes of the StreamGear class.
  
  Parameters:
      output (str): sets the valid filename/path for storing the StreamGear assets.
      format (str): select the adaptive HTTP streaming format(DASH and HLS).
      custom_ffmpeg (str): assigns the location of custom path/directory for custom FFmpeg executables.
      logging (bool): enables/disables logging.
      stream_params (dict): provides the flexibility to control supported internal parameters and FFmpeg properties.
docstr_tok: ["This","constructor","method","initializes","the","object","state","and","attributes","of","the","StreamGear","class",".","Parameters",":","output","(","str",")",":","sets","the","valid","filename\/path","for","storing","the","StreamGear","assets",".","format","(","str",")",":","select","the","adaptive","HTTP","streaming","format","(","DASH","and","HLS",")",".","custom_ffmpeg","(","str",")",":","assigns","the","location","of","custom","path\/directory","for","custom","FFmpeg","executables",".","logging","(","bool",")",":","enables\/disables","logging",".","stream_params","(","dict",")",":","provides","the","flexibility","to","control","supported","internal","parameters","and","FFmpeg","properties","."]
code: def __init__(
      self,
      output="",
      format="dash",
      custom_ffmpeg="",
      logging=False,
      **stream_params,
  ):
      """
      This constructor method initializes the object state and attributes of the StreamGear class.
  
      Parameters:
          output (str): sets the valid filename/path for storing the StreamGear assets.
          format (str): select the adaptive HTTP streaming format(DASH and HLS).
          custom_ffmpeg (str): assigns the location of custom path/directory for custom FFmpeg executables.
          logging (bool): enables/disables logging.
          stream_params (dict): provides the flexibility to control supported internal parameters and FFmpeg properties.
      """
  
      # print current version
      logcurr_vidgear_ver(logging=logging)
  
      # checks if machine in-use is running windows os or not
      self.__os_windows = True if os.name == "nt" else False
      # enable logging if specified
      self.__logging = (
          logging if (logging and isinstance(logging, bool)) else False
      )
  
      # initialize various class variables
      # handles user-defined parameters
      self.__params = {}
      # handle input video/frame resolution and channels
      self.__inputheight = None
      self.__inputwidth = None
      self.__inputchannels = None
      self.__sourceframerate = None
      # handle process to be frames written
      self.__process = None
      # handle valid FFmpeg assets location
      self.__ffmpeg = ""
      # handle one time process for valid process initialization
      self.__initiate_stream = True
  
      # cleans and reformat user-defined parameters
      self.__params = {
          str(k).strip(): str(v).strip()
          if not isinstance(v, (dict, list, int, float))
          else v
          for k, v in stream_params.items()
      }
  
      # handle where to save the downloaded FFmpeg Static assets on Windows(if specified)
      __ffmpeg_download_path = self.__params.pop(
          "-ffmpeg_download_path", ""
      )
      if not isinstance(__ffmpeg_download_path, (str)):
          # reset improper values
          __ffmpeg_download_path = ""
  
      # validate the FFmpeg assets and return location (also downloads static assets on windows)
      self.__ffmpeg = get_valid_ffmpeg_path(
          str(custom_ffmpeg),
          self.__os_windows,
          ffmpeg_download_path=__ffmpeg_download_path,
          logging=self.__logging,
      )
  
      # check if valid FFmpeg path returned
      if self.__ffmpeg:
          self.__logging and logger.debug(
              "Found valid FFmpeg executables: `{}`.".format(
                  self.__ffmpeg
              )
          )
      else:
          # else raise error
          raise RuntimeError(
              "[StreamGear:ERROR] :: Failed to find FFmpeg assets on this system. Kindly compile/install FFmpeg or provide a valid custom FFmpeg binary path!"
          )
  
      # handle Audio-Input
      audio = self.__params.pop("-audio", "")
      if audio and isinstance(audio, str):
          if os.path.isfile(audio):
              self.__audio = os.path.abspath(audio)
          elif is_valid_url(
              self.__ffmpeg, url=audio, logging=self.__logging
          ):
              self.__audio = audio
          else:
              self.__audio = ""
      elif audio and isinstance(audio, list):
          self.__audio = audio
      else:
          self.__audio = ""
  
      if self.__audio and self.__logging:
          logger.debug("External audio source detected!")
  
      # handle Video-Source input
      source = self.__params.pop("-video_source", "")
      # Check if input is valid string
      if source and isinstance(source, str) and len(source) > 1:
          # Differentiate input
          if os.path.isfile(source):
              self.__video_source = os.path.abspath(source)
          elif is_valid_url(
              self.__ffmpeg, url=source, logging=self.__logging
          ):
              self.__video_source = source
          else:
              # discard the value otherwise
              self.__video_source = ""
          # Validate input
          if self.__video_source:
              validation_results = validate_video(
                  self.__ffmpeg, video_path=self.__video_source
              )
              assert not (
                  validation_results is None
              ), "[StreamGear:ERROR] :: Given `{}` video_source is Invalid, Check Again!".format(
                  self.__video_source
              )
              self.__aspect_source = validation_results["resolution"]
              self.__fps_source = validation_results["framerate"]
              # log it
              self.__logging and logger.debug(
                  "Given video_source is valid and has {}x{} resolution, and a framerate of {} fps.".format(
                      self.__aspect_source[0],
                      self.__aspect_source[1],
                      self.__fps_source,
                  )
              )
          else:
              logger.warning("No valid video_source provided.")
      else:
          # discard the value otherwise
          self.__video_source = ""
  
      # handle user-defined framerate
      self.__inputframerate = self.__params.pop("-input_framerate", 0.0)
      if isinstance(self.__inputframerate, (float, int)):
          # must be float
          self.__inputframerate = float(self.__inputframerate)
      else:
          # reset improper values
          self.__inputframerate = 0.0
  
      # handle old assests
      self.__clear_assets = self.__params.pop(
          "-clear_prev_assets", False
      )
      if not isinstance(self.__clear_assets, bool):
          # reset improper values
          self.__clear_assets = False
  
      # handle whether to livestream?
      self.__livestreaming = self.__params.pop("-livestream", False)
      if not isinstance(self.__livestreaming, bool):
          # reset improper values
          self.__livestreaming = False
  
      # handle Streaming formats
      supported_formats = ["dash", "hls"]  # will be extended in future
      # Validate
      if not (format is None) and format and isinstance(format, str):
          _format = format.strip().lower()
          if _format in supported_formats:
              self.__format = _format
              logger.info(
                  "StreamGear will generate files for {} HTTP streaming format.".format(
                      self.__format.upper()
                  )
              )
          elif difflib.get_close_matches(_format, supported_formats):
              raise ValueError(
                  "[StreamGear:ERROR] :: Incorrect format! Did you mean `{}`?".format(
                      difflib.get_close_matches(
                          _format, supported_formats
                      )[0]
                  )
              )
          else:
              raise ValueError(
                  "[StreamGear:ERROR] :: format value `{}` not valid/supported!".format(
                      format
                  )
              )
      else:
          raise ValueError(
              "[StreamGear:ERROR] :: format value is Missing/Incorrect. Check vidgear docs!"
          )
  
      # handles output name
      if not output:
          raise ValueError(
              "[StreamGear:ERROR] :: Kindly provide a valid `output` value. Refer Docs for more information."
          )
      else:
          # validate this class has the access rights to specified directory or not
          abs_path = os.path.abspath(output)
  
          if check_WriteAccess(
              os.path.dirname(abs_path),
              is_windows=self.__os_windows,
              logging=self.__logging,
          ):
              # check if given path is directory
              valid_extension = (
                  "mpd" if self.__format == "dash" else "m3u8"
              )
              # get all assets extensions
              assets_exts = [
                  (
                      "chunk-stream",
                      ".m4s",
                  ),  # filename prefix, extension
                  ("chunk-stream", ".ts"),  # filename prefix, extension
                  ".{}".format(valid_extension),
              ]
              # add source file extension too
              if self.__video_source:
                  assets_exts.append(
                      (
                          "chunk-stream",
                          os.path.splitext(self.__video_source)[1],
                      )  # filename prefix, extension
                  )
              if os.path.isdir(abs_path):
                  if self.__clear_assets:
                      delete_ext_safe(
                          abs_path, assets_exts, logging=self.__logging
                      )
                  abs_path = os.path.join(
                      abs_path,
                      "{}-{}.{}".format(
                          self.__format,
                          time.strftime("%Y%m%d-%H%M%S"),
                          valid_extension,
                      ),
                  )  # auto-assign valid name and adds it to path
              elif self.__clear_assets and os.path.isfile(abs_path):
                  delete_ext_safe(
                      os.path.dirname(abs_path),
                      assets_exts,
                      logging=self.__logging,
                  )
              # check if path has valid file extension
              assert abs_path.endswith(
                  valid_extension
              ), "Given `{}` path has invalid file-extension w.r.t selected format: `{}`!".format(
                  output, self.__format.upper()
              )
              self.__logging and logger.debug(
                  "Path:`{}` is sucessfully configured for streaming.".format(
                      abs_path
                  )
              )
              # assign it
              self.__out_file = abs_path.replace(
                  "\\", "/"
              )  # workaround for Windows platform only, others will not be affected
          elif (
              platform.system() == "Linux"
              and pathlib.Path(output).is_char_device()
          ):
              # check if linux video device path (such as `/dev/video0`)
              self.__logging and logger.debug(
                  "Path:`{}` is a valid Linux Video Device path.".format(
                      output
                  )
              )
              self.__out_file = output
          # check if given output is a valid URL
          elif is_valid_url(
              self.__ffmpeg, url=output, logging=self.__logging
          ):
              self.__logging and logger.debug(
                  "URL:`{}` is valid and sucessfully configured for streaming.".format(
                      output
                  )
              )
              self.__out_file = output
          else:
              raise ValueError(
                  "[StreamGear:ERROR] :: Output value:`{}` is not valid/supported!".format(
                      output
                  )
              )
      # log Mode of operation
      logger.info(
          "StreamGear has been successfully configured for {} Mode.".format(
              "Single-Source"
              if self.__video_source
              else "Real-time Frames"
          )
      )
  
imports: import os
  import time
  import math
  import platform
  import pathlib
  import difflib
  import logging
  import subprocess
  from tqdm import tqdm
  from fractions import Fraction
  from collections import OrderedDict
  from .helper import capPropId, dict2Args, delete_ext_safe, extract_time, is_valid_url, logger_handler, validate_audio, validate_video, check_WriteAccess, get_video_bitrate, get_valid_ffmpeg_path, logcurr_vidgear_ver
label_desc: Use image node_id 1 to create a new StreamGear object  with example: obj = StreamGear(output, format, custom_ffmpeg, logging)