From dd60fcb3e2d679192b889ad8063af9b52b20bb07 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Thu, 7 Jul 2022 18:45:19 +0530 Subject: [PATCH 01/76] =?UTF-8?q?=F0=9F=94=96=20Setup:=20Bumped=20version?= =?UTF-8?q?=20to=20`0.2.1`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deffcode/version.py b/deffcode/version.py index 49f34f4..77648b6 100644 --- a/deffcode/version.py +++ b/deffcode/version.py @@ -1 +1 @@ -__version__ = "0.2.0" \ No newline at end of file +__version__ = "0.2.1" \ No newline at end of file From f2218d15eb814ce03a72582584dd831b5b6ef80d Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Thu, 7 Jul 2022 18:45:48 +0530 Subject: [PATCH 02/76] =?UTF-8?q?=F0=9F=93=9D=20Docs:=20Updated=20Roadmap?= =?UTF-8?q?=20in=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1066e65..298cd2f 100644 --- a/README.md +++ b/README.md @@ -144,8 +144,8 @@ For more examples and in-depth usage guide, kindly refer our **[Basic Recipes - [x] Add project Issue and PR templates. - [x] Add related unit tests with `pytests`. - [x] Automate stuff with Continuous Integration. +- [ ] Add Devices and Screen Capture support. [:construction:WIP] - [ ] Add Multiple Source Inputs support. -- [ ] Add Devices and Screen Capture support. - [ ] Resolve High CPU usage issue with WriteGear API. - [ ] Add more parameters to Sourcer API's metadata. - [ ] Implement Buffer and Audio pass-through modes. From f78197767cac6abbfc69b6b49a7f311116d15636 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Thu, 7 Jul 2022 18:50:22 +0530 Subject: [PATCH 03/76] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20FFdecoder:=20Added?= =?UTF-8?q?=20special=20case=20for=20discarding=20`-framerate`=20value=20w?= =?UTF-8?q?ith=20Nonetype.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/ffdecoder.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/deffcode/ffdecoder.py b/deffcode/ffdecoder.py index 4084e1a..9603ead 100644 --- a/deffcode/ffdecoder.py +++ b/deffcode/ffdecoder.py @@ -101,7 +101,7 @@ def __init__( # cleans and reformat user-defined parameters self.__extra_params = { str(k).strip(): str(v).strip() - if not isinstance(v, (dict, list, int, float)) + if not (v is None) and not isinstance(v, (dict, list, int, float)) else v for k, v in extraparams.items() } @@ -182,15 +182,20 @@ def __init__( # handle user-defined framerate self.__inputframerate = self.__extra_params.pop("-framerate", 0.0) - if ( - isinstance(self.__inputframerate, (float, int)) - and self.__inputframerate > 0.0 - ): - # must be float - self.__inputframerate = float(self.__inputframerate) + if isinstance(self.__inputframerate, (float, int)): + self.__inputframerate = ( + float(self.__inputframerate) if self.__inputframerate > 0 else 0.0 + ) + elif self.__inputframerate is None: + # special case for discarding framerate value + pass else: - # reset improper values - self.__inputframerate = 0.0 + # warn if wrong type + logger.warning( + "Discarding `-framerate` value of wrong type `{}`!".format( + type(self.__inputframerate) + ) + ) # FFmpeg parameter `-s` is unsupported if not (self.__extra_params.pop("-s", None) is None): From c906045c55654c17c7a4d5160933359e795d834a Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Thu, 7 Jul 2022 20:05:51 +0530 Subject: [PATCH 04/76] =?UTF-8?q?=E2=9C=A8=20[WIP]=20Sourcer:=20Implemente?= =?UTF-8?q?d=20complete=20support=20for=20live=20input=20devices/sources.?= =?UTF-8?q?=20(#16)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ⚡️ Implemented support for extracting metadata from live input devices/sources. - 🚧 `source` parameter now accepts device name or path. - 🚩 Added `source_demuxer` parameter to specify demuxer for live input devices/sources. - ✨ Added new `source_demuxer` and `forced_validate` parameters to `validate_source` internal method. - 🥅 Implemented logic to validate `source_demuxer` value against available demuxers. - 🚩 Included `-f` FFmpeg parameter into pipeline to specify source device demuxer. --- deffcode/sourcer.py | 51 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index b620558..57fc833 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -41,7 +41,14 @@ class Sourcer: """ """ - def __init__(self, source, custom_ffmpeg="", verbose=False, **sourcer_params): + def __init__( + self, + source, + source_demuxer=None, + custom_ffmpeg="", + verbose=False, + **sourcer_params + ): """ This constructor method initializes the object state and attributes of the Sourcer. @@ -101,9 +108,12 @@ def __init__(self, source, custom_ffmpeg="", verbose=False, **sourcer_params): # define externally accessible parameters self.__source = source # handles source stream - self.__source_extension = os.path.splitext(source)[ - -1 - ] # handles source stream extension + # handles source demuxer + self.__source_demuxer = ( + source_demuxer.strip().lower() if isinstance(source_demuxer, str) else None + ) + # handles source stream extension + self.__source_extension = os.path.splitext(source)[-1] self.__default_video_resolution = "" # handle stream resolution self.__default_video_framerate = "" # handle stream framerate self.__default_video_bitrate = "" # handle stream's video bitrate @@ -137,7 +147,13 @@ def probe_stream(self, default_stream_indexes=(0, 0)): and all(isinstance(x, int) for x in default_stream_indexes) ), "Invalid default_stream_indexes value!" # validate source and extract metadata - self.__ffsp_output = self.__validate_source(self.__source) + self.__ffsp_output = self.__validate_source( + self.__source, + source_demuxer=self.__source_demuxer, + forced_validate=( + self.__forcevalidatesource if self.__source_demuxer is None else True + ), + ) # parse resolution and framerate video_rfparams = self.__extract_resolution_framerate( default_stream=default_stream_indexes[0] @@ -227,12 +243,20 @@ def retrieve_metadata(self): } return metadata - def __validate_source(self, source): + def __validate_source(self, source, source_format=None, forced_validate=False): """ Internal method for validating source and extract its FFmpeg metadata. """ - if source is None or not source or not isinstance(source, str): - raise ValueError("Input source is empty!") + # assert if valid source + assert ( + source is None or not source or not isinstance(source, str) + ), "Input source is empty!" + # assert if valid source demuxer + assert source_demuxer in get_supported_demuxers( + self.__ffmpeg + ), "Installed FFmpeg failed to recognise `{}` demuxer. Check ``source_demuxer`` parameter value again!".format( + source_demuxer + ) # Differentiate input if os.path.isfile(source): self.__video_source = os.path.abspath(source) @@ -243,8 +267,10 @@ def __validate_source(self, source): self.__contains_images = True elif is_valid_url(self.__ffmpeg, url=source, verbose=self.__verbose_logs): self.__video_source = source - elif self.__forcevalidatesource: - logger.critical("Forcefully passing validation test for given source!") + elif forced_validate: + source_format is None and logger.critical( + "Forcefully passing validation test for given source!" + ) self.__video_source = source else: logger.error("`source` value is unusable or unsupported!") @@ -252,7 +278,10 @@ def __validate_source(self, source): raise ValueError("Input source is invalid. Aborting!") # extract metadata metadata = check_sp_output( - [self.__ffmpeg, "-hide_banner", "-i", source], force_retrieve_stderr=True + [self.__ffmpeg, "-hide_banner"] + + (["-f", source_format] if source_format else []) + + ["-i", source], + force_retrieve_stderr=True, ) # filter and return return metadata.decode("utf-8").strip() From e78fd615cd01cd9374f165c57e3e743f4b8e9669 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Thu, 7 Jul 2022 20:11:20 +0530 Subject: [PATCH 05/76] =?UTF-8?q?=F0=9F=9A=B8=20Added=20`source=5Fdemuxer`?= =?UTF-8?q?=20metadata=20attribute=20to=20specify=20source=20demuxer=20in?= =?UTF-8?q?=20metadata.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 🎨 Only either `source_demuxer` or `source_extension` attribute can be present in metadata. --- deffcode/sourcer.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index 57fc833..534e32c 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -225,7 +225,6 @@ def retrieve_metadata(self): metadata = { "ffmpeg_binary_path": self.__ffmpeg, "source": self.__source, - "source_extension": self.__source_extension, "source_video_resolution": self.__default_video_resolution, "source_video_framerate": self.__default_video_framerate, "source_video_pixfmt": self.__default_video_pixfmt, @@ -241,6 +240,11 @@ def retrieve_metadata(self): "source_has_audio": self.__contains_audio, "source_has_image_sequence": self.__contains_images, } + metadata.update( + {"source_extension": self.__source_extension} + if self.__source_demuxer is None + else {"source_demuxer": self.__source_demuxer} + ) return metadata def __validate_source(self, source, source_format=None, forced_validate=False): From 3ef29fc0976531eb77f98e3a314c0f262e7e2efa Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Thu, 7 Jul 2022 20:36:08 +0530 Subject: [PATCH 06/76] =?UTF-8?q?=F0=9F=8E=A8=20Sourcer:=20Rearranged=20me?= =?UTF-8?q?tadata=20dict.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/sourcer.py | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index 534e32c..63bea15 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -225,26 +225,32 @@ def retrieve_metadata(self): metadata = { "ffmpeg_binary_path": self.__ffmpeg, "source": self.__source, - "source_video_resolution": self.__default_video_resolution, - "source_video_framerate": self.__default_video_framerate, - "source_video_pixfmt": self.__default_video_pixfmt, - "source_video_decoder": self.__default_video_decoder, - "source_duration_sec": self.__default_source_duration, - "approx_video_nframes": int(self.__approx_video_nframes) - if self.__approx_video_nframes - else None, - "source_video_bitrate": self.__default_video_bitrate, - "source_audio_bitrate": self.__default_audio_bitrate, - "source_audio_samplerate": self.__default_audio_samplerate, - "source_has_video": self.__contains_video, - "source_has_audio": self.__contains_audio, - "source_has_image_sequence": self.__contains_images, } metadata.update( {"source_extension": self.__source_extension} if self.__source_demuxer is None else {"source_demuxer": self.__source_demuxer} ) + metadata.update( + { + "source_video_resolution": self.__default_video_resolution, + "source_video_framerate": self.__default_video_framerate, + "source_video_pixfmt": self.__default_video_pixfmt, + "source_video_decoder": self.__default_video_decoder, + "source_duration_sec": self.__default_source_duration, + "approx_video_nframes": ( + int(self.__approx_video_nframes) + if self.__approx_video_nframes + else None + ), + "source_video_bitrate": self.__default_video_bitrate, + "source_audio_bitrate": self.__default_audio_bitrate, + "source_audio_samplerate": self.__default_audio_samplerate, + "source_has_video": self.__contains_video, + "source_has_audio": self.__contains_audio, + "source_has_image_sequence": self.__contains_images, + } + ) return metadata def __validate_source(self, source, source_format=None, forced_validate=False): From 0ce978729b2f8fd0c87c45dfb26f8b14b130878b Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Thu, 7 Jul 2022 20:37:44 +0530 Subject: [PATCH 07/76] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Sourcer:=20Fixed=20t?= =?UTF-8?q?ypos=20in=20parameter=20names.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/sourcer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index 63bea15..318f1b0 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -253,7 +253,7 @@ def retrieve_metadata(self): ) return metadata - def __validate_source(self, source, source_format=None, forced_validate=False): + def __validate_source(self, source, source_demuxer=None, forced_validate=False): """ Internal method for validating source and extract its FFmpeg metadata. """ @@ -278,7 +278,7 @@ def __validate_source(self, source, source_format=None, forced_validate=False): elif is_valid_url(self.__ffmpeg, url=source, verbose=self.__verbose_logs): self.__video_source = source elif forced_validate: - source_format is None and logger.critical( + source_demuxer is None and logger.critical( "Forcefully passing validation test for given source!" ) self.__video_source = source @@ -289,7 +289,7 @@ def __validate_source(self, source, source_format=None, forced_validate=False): # extract metadata metadata = check_sp_output( [self.__ffmpeg, "-hide_banner"] - + (["-f", source_format] if source_format else []) + + (["-f", source_demuxer] if source_demuxer else []) + ["-i", source], force_retrieve_stderr=True, ) From 91a5e869243b51df2e172964e59c5332fe2b37bb Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Thu, 7 Jul 2022 20:43:47 +0530 Subject: [PATCH 08/76] =?UTF-8?q?=E2=9E=95=20Sourcer:=20Added=20missing=20?= =?UTF-8?q?import.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/sourcer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index 318f1b0..30fe943 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -26,6 +26,7 @@ from .utils import logger_handler from .ffhelper import ( check_sp_output, + get_supported_demuxers, is_valid_url, is_valid_image_seq, get_valid_ffmpeg_path, From eed3cad3a98ae0b3276463358f5d1ced20e80dd9 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Thu, 7 Jul 2022 20:58:32 +0530 Subject: [PATCH 09/76] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20FFdecoder:=20Impleme?= =?UTF-8?q?nted=20functionality=20to=20supported=20live=20input=20devices.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 🚩 Added `source_demuxer` parameter to specify demuxer for live input devices/sources. - 🚧 Implemented functionality to supported live devices by allowing device path and respective demuxer into pipeline. - ✨ Automated inserting of `-f` FFmpeg parameter whenever `source_demuxer` is specified by the user. - ✏️ Fixed typos in parameter names. - 🔥 Removed redundant code. --- deffcode/ffdecoder.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/deffcode/ffdecoder.py b/deffcode/ffdecoder.py index 9603ead..7c0fa2d 100644 --- a/deffcode/ffdecoder.py +++ b/deffcode/ffdecoder.py @@ -44,7 +44,13 @@ class FFdecoder: """ """ def __init__( - self, source, frame_format=None, custom_ffmpeg="", verbose=False, **extraparams + self, + source, + source_demuxer=None, + frame_format=None, + custom_ffmpeg="", + verbose=False, + **extraparams ): """ This constructor method initializes the object state and attributes of the FFdecoder. @@ -74,9 +80,6 @@ def __init__( # handle process to be frames written self.__process = None - # handle valid FFmpeg assets location - self.__ffmpeg = "" - # handle exclusive metadata self.__ff_pixfmt_metadata = None # metadata self.__raw_frame_num = None # raw-frame number @@ -132,15 +135,16 @@ def __init__( self.__source_metadata = ( Sourcer( source=source, + source_demuxer=source_demuxer, verbose=verbose, - ffmpeg_path=self.__ffmpeg, + custom_ffmpeg=custom_ffmpeg if isinstance(custom_ffmpeg, str) else "", **sourcer_params ) .probe_stream(default_stream_indexes=default_stream_indexes) .retrieve_metadata() ) - # get valid ffmpeg path + # handle valid FFmpeg assets location self.__ffmpeg = self.__source_metadata["ffmpeg_binary_path"] # handle pass-through audio mode works in conjunction with WriteGear [WIP] @@ -538,8 +542,12 @@ def __launch_FFdecoderline(self, input_params, output_params): + self.__ffmpeg_prefixes + input_parameters + self.__ffmpeg_postfixes - + ["-i"] - + [self.__source_metadata["source"]] + + ( + ["-f", self.__source_metadata["source_demuxer"]] + if ("source_demuxer" in self.__source_metadata.keys()) + else [] + ) + + ["-i", self.__source_metadata["source"]] + output_parameters + ["-f", "rawvideo", "-"] ) From 9920334c959e709a47f20428a3523333a0891f93 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 12:35:37 +0530 Subject: [PATCH 10/76] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Sourcer:=20Fixed=20t?= =?UTF-8?q?ypos=20in=20parameter=20names.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/sourcer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index 30fe943..3e6342e 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -270,19 +270,19 @@ def __validate_source(self, source, source_demuxer=None, forced_validate=False): ) # Differentiate input if os.path.isfile(source): - self.__video_source = os.path.abspath(source) + self.__source = os.path.abspath(source) elif is_valid_image_seq( self.__ffmpeg, source=source, verbose=self.__verbose_logs ): - self.__video_source = source + self.__source = source self.__contains_images = True elif is_valid_url(self.__ffmpeg, url=source, verbose=self.__verbose_logs): - self.__video_source = source + self.__source = source elif forced_validate: source_demuxer is None and logger.critical( "Forcefully passing validation test for given source!" ) - self.__video_source = source + self.__source = source else: logger.error("`source` value is unusable or unsupported!") # discard the value otherwise From 012cf71596798bfeb4a395a447fcc704865d1fd3 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 12:54:59 +0530 Subject: [PATCH 11/76] =?UTF-8?q?=F0=9F=90=9B=20Sourcer:=20Fixed=20bugs=20?= =?UTF-8?q?in=20assertion=20logic.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 🎨 Minor tweaks in code formatting. --- deffcode/sourcer.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index 3e6342e..4257716 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -259,9 +259,7 @@ def __validate_source(self, source, source_demuxer=None, forced_validate=False): Internal method for validating source and extract its FFmpeg metadata. """ # assert if valid source - assert ( - source is None or not source or not isinstance(source, str) - ), "Input source is empty!" + assert source and isinstance(source, str), "Input source is empty!" # assert if valid source demuxer assert source_demuxer in get_supported_demuxers( self.__ffmpeg @@ -269,7 +267,12 @@ def __validate_source(self, source, source_demuxer=None, forced_validate=False): source_demuxer ) # Differentiate input - if os.path.isfile(source): + if forced_validate: + source_demuxer is None and logger.critical( + "Forcefully passing validation test for given source!" + ) + self.__source = source + elif os.path.isfile(source): self.__source = os.path.abspath(source) elif is_valid_image_seq( self.__ffmpeg, source=source, verbose=self.__verbose_logs @@ -278,11 +281,6 @@ def __validate_source(self, source, source_demuxer=None, forced_validate=False): self.__contains_images = True elif is_valid_url(self.__ffmpeg, url=source, verbose=self.__verbose_logs): self.__source = source - elif forced_validate: - source_demuxer is None and logger.critical( - "Forcefully passing validation test for given source!" - ) - self.__source = source else: logger.error("`source` value is unusable or unsupported!") # discard the value otherwise From 139c6deb1c16ea08e741610fd697e649b9dbf488 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 15:43:10 +0530 Subject: [PATCH 12/76] =?UTF-8?q?=F0=9F=90=9B=20Sourcer:=20Fixed=20Nonetyp?= =?UTF-8?q?e=20value=20bug=20in=20`source=5Fdemuxer`=20assertion.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/sourcer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index 4257716..534974c 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -261,7 +261,7 @@ def __validate_source(self, source, source_demuxer=None, forced_validate=False): # assert if valid source assert source and isinstance(source, str), "Input source is empty!" # assert if valid source demuxer - assert source_demuxer in get_supported_demuxers( + assert source_demuxer is None or source_demuxer in get_supported_demuxers( self.__ffmpeg ), "Installed FFmpeg failed to recognise `{}` demuxer. Check ``source_demuxer`` parameter value again!".format( source_demuxer From 0913343c8b61291ac47c5ae1a6bb22b48142f9b2 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 15:48:25 +0530 Subject: [PATCH 13/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20jinja2=20`3.?= =?UTF-8?q?1.0`=20or=20above=20breaks=20mkdocs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 📌 `jinja2>=3.1.0` breaks mkdocs (mkdocs/mkdocs#2799), therefore pinned jinja2 version to `<3.1.0`. --- .github/workflows/docs_deployer.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/docs_deployer.yml b/.github/workflows/docs_deployer.yml index 770ea25..bbb0d8d 100644 --- a/.github/workflows/docs_deployer.yml +++ b/.github/workflows/docs_deployer.yml @@ -49,6 +49,7 @@ jobs: run: | pip install -U mkdocs mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-minify-plugin mkdocs-exclude mike pip install mkdocstrings==0.17.0 + pip install jinja2==3.0.* if: success() - name: git configure run: | @@ -96,6 +97,7 @@ jobs: run: | pip install -U mkdocs mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-minify-plugin mkdocs-exclude mike pip install mkdocstrings==0.17.0 + pip install jinja2==3.0.* if: success() - name: git configure run: | @@ -145,6 +147,7 @@ jobs: run: | pip install -U mkdocs mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-minify-plugin mkdocs-exclude mike pip install mkdocstrings==0.17.0 + pip install jinja2==3.0.* if: success() - name: git configure run: | From 0c4c40e57eb293419ffba5fa376d3a080b27ca6f Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 17:08:52 +0530 Subject: [PATCH 14/76] =?UTF-8?q?=E2=9C=85=20CI:=20Added=20basic=20webcam?= =?UTF-8?q?=20playback=20test=20using=20`pyvirtualcam`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ✅ Added new `test_cameradevice` to test FFdecoder's webcam playback capabilities. - ✨ Added `array_data` to generate random data of given frame-size and frame number. - ➕ Added `pyvirtualcam` pip dependency. - ➕ Added `v4l2loopback-dkms` apt dependency. - 🥅 `test_cameradevice` will be enabled for Linux platforms only. - 🚧 Added necessary imports. --- .github/workflows/CIlinux.yml | 7 ++--- tests/test_ffdecoder.py | 48 +++++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index d71f37e..f9787a9 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -46,16 +46,17 @@ jobs: run: | sudo apt-get update -qq sudo apt-get install -qq unzip curl -y - sudo apt-get install -qq dos2unix ffmpeg -y + sudo apt-get install -qq dos2unix ffmpeg v4l2loopback-dkms -y + sudo modprobe v4l2loopback devices=1 - name: Prepare Bash scripts run: | dos2unix scripts/bash/prepare_dataset.sh chmod +x scripts/bash/prepare_dataset.sh - name: Install Pip Dependencies run: | - pip install -U pip wheel numpy + pip install -U pip wheel numpy pip install -U . - pip install -U vidgear[core] opencv-python-headless + pip install -U vidgear[core] opencv-python-headless pyvirtualcam pip install -U flake8 six codecov pytest pytest-cov if: success() - name: Run prepare_dataset Bash script diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index 70afb60..d52409d 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -24,6 +24,9 @@ import json import pytest import tempfile +import platform +import pyvirtualcam +import numpy as np import logging from .essentials import ( return_static_ffmpeg, @@ -43,6 +46,15 @@ logger.setLevel(logging.DEBUG) +def array_data(self, size, frame_num=10): + """ + Generate 10 numpy frames with random pixels + """ + np.random.seed(0) + random_data = np.random.random(size=(frame_num, size[0], size[1], 3)) * 255 + return random_data.astype(np.uint8) + + @pytest.mark.parametrize( "source, output", [ @@ -129,7 +141,7 @@ def test_frame_format(pixfmts): source, frame_format=pixfmts, custom_ffmpeg=return_static_ffmpeg(), - **extraparams + **extraparams, ).formulate() # grab RGB24(default) 3D frames from decoder @@ -206,7 +218,7 @@ def test_seek_n_save(extraparams, pixfmts): frame_format=pixfmts, custom_ffmpeg=return_static_ffmpeg(), verbose=True, - **extraparams + **extraparams, ).formulate() # grab the RGB24(default) frame from the decoder @@ -302,3 +314,35 @@ def test_FFdecoder_params(source, extraparams, result): # terminate the decoder not (decoder is None) and decoder.terminate() not (writer is None) and writer.release() and remove_file_safe(f_name) + + +@pytest.mark.skipif((platform.system() != "Linux"), reason="Tests on other platforms not supported yet!") +def test_cameradevice(): + """ + Tests FFdecoder's webcam playback capabilities + """ + try: + # initialize pyvirtualcam + logger.debug(f"Virtual camera: {cam.device}") + with pyvirtualcam.Camera(width=1280, height=720, fps=20) as cam: + # initialize and formulate the decode with suitable source + logger.debug("Creating FFdecoder sink") + decoder = FFdecoder( + cam.device, source_demuxer="v4l2", frame_format="bgr24", verbose=True + ).formulate() + + # create fake frame + frames_data = array_data(size=(cam.height, cam.width)) + + # send and capture frames + for frame_sent in frames_data: + cam.send(frame_sent) + # grab the bgr24 frame from the decoder + frame_recv = next(decoder.generateFrame(), None) + # check if frame is None + if frame_recv is None: + raise AssertionError("Test Failed!") + # wait till ready + cam.sleep_until_next_frame() + except Exception as e: + pytest.xfail(str(e)) From 38b7e0342c6bca963b763780d04d55b4438e1581 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 17:14:10 +0530 Subject: [PATCH 15/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20Added=20missing=20ap?= =?UTF-8?q?t=20dependencies.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index f9787a9..960b492 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -46,7 +46,7 @@ jobs: run: | sudo apt-get update -qq sudo apt-get install -qq unzip curl -y - sudo apt-get install -qq dos2unix ffmpeg v4l2loopback-dkms -y + sudo apt-get install -qq dos2unix ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y sudo modprobe v4l2loopback devices=1 - name: Prepare Bash scripts run: | From f2ffd72caa608b27355eced47e45b1a412e010c3 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 17:17:39 +0530 Subject: [PATCH 16/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20F821=20undef?= =?UTF-8?q?ined=20name=20'cam'=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_ffdecoder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index d52409d..ccf9d62 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -323,8 +323,8 @@ def test_cameradevice(): """ try: # initialize pyvirtualcam - logger.debug(f"Virtual camera: {cam.device}") with pyvirtualcam.Camera(width=1280, height=720, fps=20) as cam: + logger.debug(f"Virtual camera: {cam.device}") # initialize and formulate the decode with suitable source logger.debug("Creating FFdecoder sink") decoder = FFdecoder( From 198f0844a6ff3420bdb6b705bb2d0828790a1753 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 17:42:13 +0530 Subject: [PATCH 17/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20Enabled=20pytest.fai?= =?UTF-8?q?l=20to=20check=20failure.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_ffdecoder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index ccf9d62..58f6395 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -345,4 +345,4 @@ def test_cameradevice(): # wait till ready cam.sleep_until_next_frame() except Exception as e: - pytest.xfail(str(e)) + pytest.fail(str(e)) From b3b6455c503347345bf0e1748a97abe21abe88f5 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 18:21:49 +0530 Subject: [PATCH 18/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20Added=20permission?= =?UTF-8?q?=20for=20video=20user-group.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added `v4l2-ctl` command for debugging. --- .github/workflows/CIlinux.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 960b492..47d1d3a 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,6 +48,8 @@ jobs: sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y sudo modprobe v4l2loopback devices=1 + sudo usermod -a -G video $(whoami) + v4l2-ctl --list-devices - name: Prepare Bash scripts run: | dos2unix scripts/bash/prepare_dataset.sh From 8d546d796a67eb77820b8604c4138ed20d445ef5 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 18:35:19 +0530 Subject: [PATCH 19/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20Fixed=20typos=20and?= =?UTF-8?q?=20testing=20new=20configuration.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 47d1d3a..f7eb948 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -42,13 +42,12 @@ jobs: - uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - - name: Install API Dependencies + - name: Install APT Dependencies run: | sudo apt-get update -qq sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y - sudo modprobe v4l2loopback devices=1 - sudo usermod -a -G video $(whoami) + sudo modprobe v4l2loopback devices=1 video_nr=10 card_label="Overlay" v4l2-ctl --list-devices - name: Prepare Bash scripts run: | From fbede28c91f38aff1b273a10c6096b8470258124 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 18:56:55 +0530 Subject: [PATCH 20/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20Trying=20with=20obs?= =?UTF-8?q?=20backend.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 5 +++-- tests/test_ffdecoder.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index f7eb948..806236c 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -44,10 +44,11 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install APT Dependencies run: | + sudo add-apt-repository ppa:obsproject/obs-studio -y sudo apt-get update -qq sudo apt-get install -qq unzip curl -y - sudo apt-get install -qq dos2unix ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y - sudo modprobe v4l2loopback devices=1 video_nr=10 card_label="Overlay" + sudo apt-get install -qq dos2unix -y + sudo apt-get install ffmpeg obs-studio v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y v4l2-ctl --list-devices - name: Prepare Bash scripts run: | diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index 58f6395..1f4c549 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -323,7 +323,7 @@ def test_cameradevice(): """ try: # initialize pyvirtualcam - with pyvirtualcam.Camera(width=1280, height=720, fps=20) as cam: + with pyvirtualcam.Camera(width=1280, height=720, fps=20, backend="obs") as cam: logger.debug(f"Virtual camera: {cam.device}") # initialize and formulate the decode with suitable source logger.debug("Creating FFdecoder sink") From 5b10e0c4b7ed13837b5d4f3b2601c85a6c7d9014 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 19:05:59 +0530 Subject: [PATCH 21/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 806236c..d3f3393 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,8 +48,8 @@ jobs: sudo apt-get update -qq sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix -y - sudo apt-get install ffmpeg obs-studio v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y - v4l2-ctl --list-devices + sudo apt-get install ffmpeg obs-studio v4l2loopback-dkms v4l2loopback-utils -y + sudo v4l2-ctl --list-devices - name: Prepare Bash scripts run: | dos2unix scripts/bash/prepare_dataset.sh From 7e777a904fd63262f8ee47b8c39a9885be8c3b6c Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 19:09:18 +0530 Subject: [PATCH 22/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index d3f3393..4831908 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,7 +48,7 @@ jobs: sudo apt-get update -qq sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix -y - sudo apt-get install ffmpeg obs-studio v4l2loopback-dkms v4l2loopback-utils -y + sudo apt-get install ffmpeg obs-studio v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y sudo v4l2-ctl --list-devices - name: Prepare Bash scripts run: | From a05e5c4cf86a3f959a038cc4800fd7b8ea27a154 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 19:11:52 +0530 Subject: [PATCH 23/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20Removed=20code.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 4831908..0c2f5ea 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,8 +48,7 @@ jobs: sudo apt-get update -qq sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix -y - sudo apt-get install ffmpeg obs-studio v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y - sudo v4l2-ctl --list-devices + sudo apt-get install ffmpeg obs-studio -y - name: Prepare Bash scripts run: | dos2unix scripts/bash/prepare_dataset.sh From 49a75669de3e91855d0dde7e56093d6c7cf3a9b5 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 19:27:29 +0530 Subject: [PATCH 24/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 6 ++++-- tests/test_ffdecoder.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 0c2f5ea..00eb457 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -44,11 +44,13 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install APT Dependencies run: | - sudo add-apt-repository ppa:obsproject/obs-studio -y sudo apt-get update -qq sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix -y - sudo apt-get install ffmpeg obs-studio -y + sudo apt-get install ffmpeg v4l2loopback-dkms libv4l-dev v4l-utils -y + sudo rmmod v4l2loopback 2>/dev/null + sudo modprobe v4l2loopback devices=${1:-1} exclusive_caps=1 card_label='VCamera' + sudo v4l2-ctl --list-devices - name: Prepare Bash scripts run: | dos2unix scripts/bash/prepare_dataset.sh diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index 1f4c549..58f6395 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -323,7 +323,7 @@ def test_cameradevice(): """ try: # initialize pyvirtualcam - with pyvirtualcam.Camera(width=1280, height=720, fps=20, backend="obs") as cam: + with pyvirtualcam.Camera(width=1280, height=720, fps=20) as cam: logger.debug(f"Virtual camera: {cam.device}") # initialize and formulate the decode with suitable source logger.debug("Creating FFdecoder sink") From 3a580af763fdf43367337e0991ec2534419f94cb Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 19:32:16 +0530 Subject: [PATCH 25/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 00eb457..28b3419 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -49,7 +49,7 @@ jobs: sudo apt-get install -qq dos2unix -y sudo apt-get install ffmpeg v4l2loopback-dkms libv4l-dev v4l-utils -y sudo rmmod v4l2loopback 2>/dev/null - sudo modprobe v4l2loopback devices=${1:-1} exclusive_caps=1 card_label='VCamera' + sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices - name: Prepare Bash scripts run: | From 7bc9e4ec607e31e6af0679ea6828db10de84262a Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 19:34:10 +0530 Subject: [PATCH 26/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 28b3419..7c57c20 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,7 +48,6 @@ jobs: sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix -y sudo apt-get install ffmpeg v4l2loopback-dkms libv4l-dev v4l-utils -y - sudo rmmod v4l2loopback 2>/dev/null sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices - name: Prepare Bash scripts From d084a05783b260aa402711f5eef92c7a6bac823b Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 19:41:28 +0530 Subject: [PATCH 27/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 7c57c20..0b3e2d3 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -44,10 +44,11 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install APT Dependencies run: | + sudo add-apt-repository ppa:doctormo/ppa sudo apt-get update -qq sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix -y - sudo apt-get install ffmpeg v4l2loopback-dkms libv4l-dev v4l-utils -y + sudo apt-get install ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices - name: Prepare Bash scripts From a32ab080d119b0a05c3806f8ac4a1ea230220c0a Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 19:43:02 +0530 Subject: [PATCH 28/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20Removed=20code.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 0b3e2d3..7eab46c 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -44,7 +44,6 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install APT Dependencies run: | - sudo add-apt-repository ppa:doctormo/ppa sudo apt-get update -qq sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix -y From 32ab391242d3084bba9f12f9e7cb9ac289ce230a Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 19:54:56 +0530 Subject: [PATCH 29/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 7eab46c..3829793 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,6 +48,7 @@ jobs: sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix -y sudo apt-get install ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y + sudo usermod -a -G video $(whoami) sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices - name: Prepare Bash scripts From ae8235e44a38b317e08ff92518df8888559358a1 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 20:23:53 +0530 Subject: [PATCH 30/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 3829793..d13fcae 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,6 +48,7 @@ jobs: sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix -y sudo apt-get install ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y + sudo adduser $(whoami) video sudo usermod -a -G video $(whoami) sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices From 5a9698b05d0254d554520300e45b526e9fbcf5f6 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 20:38:45 +0530 Subject: [PATCH 31/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20replaced=20pyvirtual?= =?UTF-8?q?cam=20with=20WriteGear=20API's=20compression=20mode.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 2 +- tests/test_ffdecoder.py | 47 +++++++++++++++++++---------------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index d13fcae..a34f38b 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -60,7 +60,7 @@ jobs: run: | pip install -U pip wheel numpy pip install -U . - pip install -U vidgear[core] opencv-python-headless pyvirtualcam + pip install -U vidgear[core] opencv-python-headless pip install -U flake8 six codecov pytest pytest-cov if: success() - name: Run prepare_dataset Bash script diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index 58f6395..71be2b4 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -25,7 +25,6 @@ import pytest import tempfile import platform -import pyvirtualcam import numpy as np import logging from .essentials import ( @@ -37,6 +36,7 @@ ) from PIL import Image from deffcode import FFdecoder +from vidgear.gears import WriteGear from deffcode.utils import logger_handler # define test logger @@ -316,33 +316,38 @@ def test_FFdecoder_params(source, extraparams, result): not (writer is None) and writer.release() and remove_file_safe(f_name) -@pytest.mark.skipif((platform.system() != "Linux"), reason="Tests on other platforms not supported yet!") +@pytest.mark.skipif( + (platform.system() != "Linux"), reason="Tests on other platforms not supported yet!" +) def test_cameradevice(): """ Tests FFdecoder's webcam playback capabilities """ try: - # initialize pyvirtualcam - with pyvirtualcam.Camera(width=1280, height=720, fps=20) as cam: - logger.debug(f"Virtual camera: {cam.device}") - # initialize and formulate the decode with suitable source - logger.debug("Creating FFdecoder sink") - decoder = FFdecoder( - cam.device, source_demuxer="v4l2", frame_format="bgr24", verbose=True - ).formulate() + # Define writer with default parameters and suitable output filename for e.g. `Output.mp4` + logger.debug("Creating v4l2loopback source") + output_params = {"-f": "v4l2"} + writer = WriteGear(output_filename="/dev/video0", logging=True, **output_params) + + # initialize and formulate the decode with suitable source + logger.debug("Creating FFdecoder sink") + decoder = FFdecoder( + cam.device, source_demuxer="v4l2", frame_format="bgr24", verbose=True + ).formulate() - # create fake frame - frames_data = array_data(size=(cam.height, cam.width)) + # create fake frame + frames_data = array_data(size=(1280, 720)) + # send and capture frames + for frame_sent in frames_data: # send and capture frames - for frame_sent in frames_data: - cam.send(frame_sent) - # grab the bgr24 frame from the decoder - frame_recv = next(decoder.generateFrame(), None) - # check if frame is None - if frame_recv is None: - raise AssertionError("Test Failed!") - # wait till ready - cam.sleep_until_next_frame() + writer.write(frame_sent) + + # grab the bgr24 frame from the decoder + frame_recv = next(decoder.generateFrame(), None) + + # check if frame is None + if frame_recv is None: + raise AssertionError("Test Failed!") except Exception as e: pytest.fail(str(e)) From a250864741e8eab774c9bce15b62e332410d613f Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 23:03:57 +0530 Subject: [PATCH 32/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20Added=20git=20`testi?= =?UTF-8?q?ng`=20branch=20pip=20installation.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index a34f38b..c2d901c 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -46,7 +46,7 @@ jobs: run: | sudo apt-get update -qq sudo apt-get install -qq unzip curl -y - sudo apt-get install -qq dos2unix -y + sudo apt-get install -qq dos2unix git -y sudo apt-get install ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y sudo adduser $(whoami) video sudo usermod -a -G video $(whoami) @@ -60,7 +60,8 @@ jobs: run: | pip install -U pip wheel numpy pip install -U . - pip install -U vidgear[core] opencv-python-headless + pip install git+git://github.com/abhiTronix/vidgear@testing#egg=vidgear[core] + pip install -U opencv-python-headless pip install -U flake8 six codecov pytest pytest-cov if: success() - name: Run prepare_dataset Bash script From 671f9bd276670cbd2ba1eca110208c00bf052d67 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 23:10:40 +0530 Subject: [PATCH 33/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20Fixed=20timeout=20is?= =?UTF-8?q?sue.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index c2d901c..418ee24 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -60,7 +60,7 @@ jobs: run: | pip install -U pip wheel numpy pip install -U . - pip install git+git://github.com/abhiTronix/vidgear@testing#egg=vidgear[core] + pip install git+https://github.com/abhiTronix/vidgear@testing#egg=vidgear[core] pip install -U opencv-python-headless pip install -U flake8 six codecov pytest pytest-cov if: success() From 02c755629427c2ed0976fbedbcf28d5b9a169d67 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Fri, 8 Jul 2022 23:29:55 +0530 Subject: [PATCH 34/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20Reload=20a=20Linux?= =?UTF-8?q?=20user's=20group=20assignments=20without=20logging=20out?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 418ee24..c69d7bb 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,9 +48,10 @@ jobs: sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix git -y sudo apt-get install ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y + sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' sudo adduser $(whoami) video sudo usermod -a -G video $(whoami) - sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' + exec sudo su -l $USER sudo v4l2-ctl --list-devices - name: Prepare Bash scripts run: | From 1c11247494f753e33a619e2e210071ed11f53898 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 12:05:33 +0530 Subject: [PATCH 35/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20all=20tests?= =?UTF-8?q?=20bugs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ✨ Added new fixture function `onetime_setup` to run onetime setup before tests. - ✨ Added new `OnetimeSetup` class for creating process and image at runtime. - 👷 Updated test `test_cameradevice` to `test_camera_capture`. - 🐛 Fixed several bugs in `test_camera_capture` test. - ⚡️ Added finally block to terminate processes and deffcode properly. - 🔥 Removed redundant code. --- deffcode/ffhelper.py | 2 +- tests/test_ffdecoder.py | 81 +++++++++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/deffcode/ffhelper.py b/deffcode/ffhelper.py index 1cb3f69..af6b56e 100644 --- a/deffcode/ffhelper.py +++ b/deffcode/ffhelper.py @@ -347,7 +347,7 @@ def get_supported_demuxers(path): # find all outputs outputs = finder.findall("\n".join(supported_demuxers)) # return output findings - return [o.strip() for o in outputs] + return [o.strip() if not ("," in o) else o.split(",")[-1].strip() for o in outputs] def validate_imgseqdir(source, extension="jpg", verbose=False): diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index 71be2b4..b7e7e22 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -46,13 +46,47 @@ logger.setLevel(logging.DEBUG) -def array_data(self, size, frame_num=10): - """ - Generate 10 numpy frames with random pixels - """ - np.random.seed(0) - random_data = np.random.random(size=(frame_num, size[0], size[1], 3)) * 255 - return random_data.astype(np.uint8) +# One time setup class +class OnetimeSetup: + def __init__(self): + # imports + import time + import subprocess as sp + from PIL import Image + + # create image + img = Image.new("RGB", (1280, 720), (255, 255, 255)) + img.save("image.png", "PNG") + + # create process to loopback image + self.process = sp.Popen( + [ + "ffmpeg", + "-hide_banner", + "-loglevel", + "error", + "-loop", + "1", + "-re", + "-i", + "image.png", + "-f", + "v4l2", + "-pix_fmt", + "yuv420p", + "/dev/video2", + ] + ) + + # wait for streaming to start + time.sleep(5) + + +# Fixture +@pytest.fixture(scope="session") +def onetime_setup(): + logger.debug("Running setup!") + return OnetimeSetup() @pytest.mark.parametrize( @@ -317,37 +351,30 @@ def test_FFdecoder_params(source, extraparams, result): @pytest.mark.skipif( - (platform.system() != "Linux"), reason="Tests on other platforms not supported yet!" + (platform.system() != "Linux"), + reason="This test not supported yet on platforms other than Linux!", ) -def test_cameradevice(): +def test_camera_capture(onetime_setup): """ - Tests FFdecoder's webcam playback capabilities + Tests FFdecoder's realtime camera playback capabilities """ + decoder = None try: - # Define writer with default parameters and suitable output filename for e.g. `Output.mp4` - logger.debug("Creating v4l2loopback source") - output_params = {"-f": "v4l2"} - writer = WriteGear(output_filename="/dev/video0", logging=True, **output_params) - # initialize and formulate the decode with suitable source - logger.debug("Creating FFdecoder sink") decoder = FFdecoder( - cam.device, source_demuxer="v4l2", frame_format="bgr24", verbose=True + "/dev/video0", source_demuxer="v4l2", frame_format="bgr24" ).formulate() - - # create fake frame - frames_data = array_data(size=(1280, 720)) - - # send and capture frames - for frame_sent in frames_data: - # send and capture frames - writer.write(frame_sent) - + # capture 10 camera frames + for i in range(10): # grab the bgr24 frame from the decoder frame_recv = next(decoder.generateFrame(), None) - # check if frame is None if frame_recv is None: raise AssertionError("Test Failed!") except Exception as e: + # catch errors pytest.fail(str(e)) + finally: + # terminate + onetime_setup.process.terminate() + decoder.terminate() From 3276535202a037bd51537fd6e38a6fa62b15886e Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 12:25:44 +0530 Subject: [PATCH 36/76] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20CI:=20Fixed=20typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_ffdecoder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index b7e7e22..af0e40e 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -74,7 +74,7 @@ def __init__(self): "v4l2", "-pix_fmt", "yuv420p", - "/dev/video2", + "/dev/video0", ] ) From b2399e96cc3f0a477ca2580d0dc764ffed5b41aa Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 12:54:32 +0530 Subject: [PATCH 37/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 3 +-- tests/test_ffdecoder.py | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index c69d7bb..418ee24 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,10 +48,9 @@ jobs: sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix git -y sudo apt-get install ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y - sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' sudo adduser $(whoami) video sudo usermod -a -G video $(whoami) - exec sudo su -l $USER + sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices - name: Prepare Bash scripts run: | diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index af0e40e..b95db97 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -57,6 +57,8 @@ def __init__(self): # create image img = Image.new("RGB", (1280, 720), (255, 255, 255)) img.save("image.png", "PNG") + # validate image + assert os.isfile("image.png") # create process to loopback image self.process = sp.Popen( @@ -377,4 +379,4 @@ def test_camera_capture(onetime_setup): finally: # terminate onetime_setup.process.terminate() - decoder.terminate() + not (decoder is None) and decoder.terminate() From f62da25fc90c2e73e3a789186f638ed0e3428e74 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 13:09:45 +0530 Subject: [PATCH 38/76] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20CI:=20Fixed=20typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_ffdecoder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index b95db97..4157d0f 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -58,7 +58,7 @@ def __init__(self): img = Image.new("RGB", (1280, 720), (255, 255, 255)) img.save("image.png", "PNG") # validate image - assert os.isfile("image.png") + assert os.path.isfile("image.png") # create process to loopback image self.process = sp.Popen( From 0efaf9eeb79191ef701f170f91f3fce4a6d26673 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 13:16:13 +0530 Subject: [PATCH 39/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 418ee24..2f1dbcb 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,10 +48,11 @@ jobs: sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix git -y sudo apt-get install ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y - sudo adduser $(whoami) video - sudo usermod -a -G video $(whoami) sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices + sudo adduser $(whoami) video + sudo usermod -a -G video $(whoami) + exec sudo su -l $(whoami) - name: Prepare Bash scripts run: | dos2unix scripts/bash/prepare_dataset.sh From f18cf4ef53357e810c070ad505af101b08b5e6e1 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 13:24:02 +0530 Subject: [PATCH 40/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 2f1dbcb..7fb6a75 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -53,6 +53,7 @@ jobs: sudo adduser $(whoami) video sudo usermod -a -G video $(whoami) exec sudo su -l $(whoami) + sudo chmod 777 /dev/video0 - name: Prepare Bash scripts run: | dos2unix scripts/bash/prepare_dataset.sh From fc427d322b647b63d8e71a731530f8df08d7084a Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 13:30:06 +0530 Subject: [PATCH 41/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 7fb6a75..aba0cc3 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,12 +48,8 @@ jobs: sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix git -y sudo apt-get install ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y - sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' - sudo v4l2-ctl --list-devices - sudo adduser $(whoami) video - sudo usermod -a -G video $(whoami) - exec sudo su -l $(whoami) - sudo chmod 777 /dev/video0 + modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' + v4l2-ctl --list-devices - name: Prepare Bash scripts run: | dos2unix scripts/bash/prepare_dataset.sh From 4fc9d9414e2b9ac29e6ec80ae54a2588eb6da2c9 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 18:09:26 +0530 Subject: [PATCH 42/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 2 +- tests/test_ffdecoder.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index aba0cc3..5e6e09c 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,7 +48,7 @@ jobs: sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix git -y sudo apt-get install ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y - modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' + sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' v4l2-ctl --list-devices - name: Prepare Bash scripts run: | diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index 4157d0f..b8231d4 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -63,6 +63,7 @@ def __init__(self): # create process to loopback image self.process = sp.Popen( [ + "sudo", "ffmpeg", "-hide_banner", "-loglevel", From 59460a0d0e2176eb5697cb270089fe8200cc26d0 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 18:12:30 +0530 Subject: [PATCH 43/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 5e6e09c..2dbe0ec 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -49,6 +49,9 @@ jobs: sudo apt-get install -qq dos2unix git -y sudo apt-get install ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' + sudo adduser $(whoami) video + sudo usermod -a -G video $(whoami) + exec sudo su -l $USER v4l2-ctl --list-devices - name: Prepare Bash scripts run: | From d8dacce928653dde8784d38b46ec8bb6532eedb3 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 18:34:55 +0530 Subject: [PATCH 44/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20Moved=20ffmpeg=20v4l?= =?UTF-8?q?2loopback=20command=20to=20bash=20script.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Removed dead code. --- .github/workflows/CIlinux.yml | 3 +-- scripts/bash/prepare_dataset.sh | 6 +++++ tests/test_ffdecoder.py | 48 +-------------------------------- 3 files changed, 8 insertions(+), 49 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 2dbe0ec..225f73d 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -51,8 +51,7 @@ jobs: sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' sudo adduser $(whoami) video sudo usermod -a -G video $(whoami) - exec sudo su -l $USER - v4l2-ctl --list-devices + sudo v4l2-ctl --list-devices - name: Prepare Bash scripts run: | dos2unix scripts/bash/prepare_dataset.sh diff --git a/scripts/bash/prepare_dataset.sh b/scripts/bash/prepare_dataset.sh index a8d8698..7dc95a2 100644 --- a/scripts/bash/prepare_dataset.sh +++ b/scripts/bash/prepare_dataset.sh @@ -104,3 +104,9 @@ curl -L https://github.com/abhiTronix/Imbakup/releases/download/vid-001/jellyfis curl -L https://github.com/abhiTronix/Imbakup/releases/download/vid-001/jellyfish-90-mbps-hd-hevc-10bit.mkv -o 90_mbps_hd_hevc_10bit.mkv curl -L https://github.com/abhiTronix/Imbakup/releases/download/vid-001/jellyfish-120-mbps-4k-uhd-h264.mkv -o 120_mbps_4k_uhd_h264.mkv echo "Done Downloading Test-Data!" + +if [ $OS_NAME = "linux" ]; then + echo "Setting up ffmpeg v4l2loopback" + nohup ffmpeg -hide_banner -loglevel error -stream_loop 10 -re -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -f v4l2 -pix_fmt yuv420p /dev/video0 & + echo "Done" +fi diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index b8231d4..c685658 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -46,52 +46,6 @@ logger.setLevel(logging.DEBUG) -# One time setup class -class OnetimeSetup: - def __init__(self): - # imports - import time - import subprocess as sp - from PIL import Image - - # create image - img = Image.new("RGB", (1280, 720), (255, 255, 255)) - img.save("image.png", "PNG") - # validate image - assert os.path.isfile("image.png") - - # create process to loopback image - self.process = sp.Popen( - [ - "sudo", - "ffmpeg", - "-hide_banner", - "-loglevel", - "error", - "-loop", - "1", - "-re", - "-i", - "image.png", - "-f", - "v4l2", - "-pix_fmt", - "yuv420p", - "/dev/video0", - ] - ) - - # wait for streaming to start - time.sleep(5) - - -# Fixture -@pytest.fixture(scope="session") -def onetime_setup(): - logger.debug("Running setup!") - return OnetimeSetup() - - @pytest.mark.parametrize( "source, output", [ @@ -357,7 +311,7 @@ def test_FFdecoder_params(source, extraparams, result): (platform.system() != "Linux"), reason="This test not supported yet on platforms other than Linux!", ) -def test_camera_capture(onetime_setup): +def test_camera_capture(): """ Tests FFdecoder's realtime camera playback capabilities """ From c75854fbaf616f4937726f25cb00a6f7fceef5e8 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 18:40:43 +0530 Subject: [PATCH 45/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20tests=20bugs?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 2 +- tests/test_ffdecoder.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 225f73d..ca34664 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -55,7 +55,7 @@ jobs: - name: Prepare Bash scripts run: | dos2unix scripts/bash/prepare_dataset.sh - chmod +x scripts/bash/prepare_dataset.sh + sudo chmod +x scripts/bash/prepare_dataset.sh - name: Install Pip Dependencies run: | pip install -U pip wheel numpy diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index c685658..e365fda 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -333,5 +333,4 @@ def test_camera_capture(): pytest.fail(str(e)) finally: # terminate - onetime_setup.process.terminate() not (decoder is None) and decoder.terminate() From ca26ddfb3f9846d01c8256dd1b46c742becceac2 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 18:56:59 +0530 Subject: [PATCH 46/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20tests=20bugs?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 4 ---- scripts/bash/prepare_dataset.sh | 4 +++- tests/test_ffdecoder.py | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index ca34664..c6131b7 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -48,10 +48,6 @@ jobs: sudo apt-get install -qq unzip curl -y sudo apt-get install -qq dos2unix git -y sudo apt-get install ffmpeg v4l2loopback-dkms v4l2loopback-utils linux-modules-extra-$(uname -r) -y - sudo modprobe v4l2loopback devices=1 exclusive_caps=1 card_label='VCamera' - sudo adduser $(whoami) video - sudo usermod -a -G video $(whoami) - sudo v4l2-ctl --list-devices - name: Prepare Bash scripts run: | dos2unix scripts/bash/prepare_dataset.sh diff --git a/scripts/bash/prepare_dataset.sh b/scripts/bash/prepare_dataset.sh index 7dc95a2..5cab947 100644 --- a/scripts/bash/prepare_dataset.sh +++ b/scripts/bash/prepare_dataset.sh @@ -107,6 +107,8 @@ echo "Done Downloading Test-Data!" if [ $OS_NAME = "linux" ]; then echo "Setting up ffmpeg v4l2loopback" - nohup ffmpeg -hide_banner -loglevel error -stream_loop 10 -re -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -f v4l2 -pix_fmt yuv420p /dev/video0 & + modprobe v4l2loopback devices=1 video_nr=2 exclusive_caps=1 card_label='VCamera' + v4l2-ctl --list-devices + nohup ffmpeg -hide_banner -loglevel error -re -stream_loop 10 -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -f v4l2 -pix_fmt yuv420p /dev/video2 & echo "Done" fi diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index e365fda..404eded 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -319,7 +319,7 @@ def test_camera_capture(): try: # initialize and formulate the decode with suitable source decoder = FFdecoder( - "/dev/video0", source_demuxer="v4l2", frame_format="bgr24" + "/dev/video2", source_demuxer="v4l2", frame_format="bgr24" ).formulate() # capture 10 camera frames for i in range(10): From 2ba694d07db7bfa11c351e58697735722e8fb1c7 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 19:01:00 +0530 Subject: [PATCH 47/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20bugs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/bash/prepare_dataset.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/bash/prepare_dataset.sh b/scripts/bash/prepare_dataset.sh index 5cab947..1aeb6a7 100644 --- a/scripts/bash/prepare_dataset.sh +++ b/scripts/bash/prepare_dataset.sh @@ -107,8 +107,8 @@ echo "Done Downloading Test-Data!" if [ $OS_NAME = "linux" ]; then echo "Setting up ffmpeg v4l2loopback" - modprobe v4l2loopback devices=1 video_nr=2 exclusive_caps=1 card_label='VCamera' - v4l2-ctl --list-devices + sudo modprobe v4l2loopback devices=1 video_nr=2 exclusive_caps=1 card_label='VCamera' + sudo v4l2-ctl --list-devices nohup ffmpeg -hide_banner -loglevel error -re -stream_loop 10 -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -f v4l2 -pix_fmt yuv420p /dev/video2 & echo "Done" fi From fa727bf061b7665f0996f9cbb1a8db027b49766d Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 19:08:54 +0530 Subject: [PATCH 48/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/bash/prepare_dataset.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bash/prepare_dataset.sh b/scripts/bash/prepare_dataset.sh index 1aeb6a7..fc1a8db 100644 --- a/scripts/bash/prepare_dataset.sh +++ b/scripts/bash/prepare_dataset.sh @@ -109,6 +109,6 @@ if [ $OS_NAME = "linux" ]; then echo "Setting up ffmpeg v4l2loopback" sudo modprobe v4l2loopback devices=1 video_nr=2 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices - nohup ffmpeg -hide_banner -loglevel error -re -stream_loop 10 -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -f v4l2 -pix_fmt yuv420p /dev/video2 & + nohup sudo ffmpeg -hide_banner -re -stream_loop 10 -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -f v4l2 -pix_fmt yuv420p /dev/video2 & echo "Done" fi From 3781df1a08e8bc9a1b46b3602243bfe346ed54e7 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 19:13:04 +0530 Subject: [PATCH 49/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/bash/prepare_dataset.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bash/prepare_dataset.sh b/scripts/bash/prepare_dataset.sh index fc1a8db..d2193e1 100644 --- a/scripts/bash/prepare_dataset.sh +++ b/scripts/bash/prepare_dataset.sh @@ -109,6 +109,6 @@ if [ $OS_NAME = "linux" ]; then echo "Setting up ffmpeg v4l2loopback" sudo modprobe v4l2loopback devices=1 video_nr=2 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices - nohup sudo ffmpeg -hide_banner -re -stream_loop 10 -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -f v4l2 -pix_fmt yuv420p /dev/video2 & + nohup sudo ffmpeg -hide_banner -loglevel error -re -stream_loop 20 -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -f v4l2 -pix_fmt yuv420p /dev/video2 & echo "Done" fi From 498cea947c9fc6fc8abf2732279e458fc1912b89 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 19:18:54 +0530 Subject: [PATCH 50/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/bash/prepare_dataset.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bash/prepare_dataset.sh b/scripts/bash/prepare_dataset.sh index d2193e1..d318bb9 100644 --- a/scripts/bash/prepare_dataset.sh +++ b/scripts/bash/prepare_dataset.sh @@ -109,6 +109,6 @@ if [ $OS_NAME = "linux" ]; then echo "Setting up ffmpeg v4l2loopback" sudo modprobe v4l2loopback devices=1 video_nr=2 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices - nohup sudo ffmpeg -hide_banner -loglevel error -re -stream_loop 20 -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -f v4l2 -pix_fmt yuv420p /dev/video2 & + nohup sudo ffmpeg -hide_banner -re -stream_loop -1 -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -vcodec copy -f v4l2 -pix_fmt yuv420p /dev/video2 & echo "Done" fi From 8470b326fa869f005690ae778aff82aa3f3940f5 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 19:22:14 +0530 Subject: [PATCH 51/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/bash/prepare_dataset.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bash/prepare_dataset.sh b/scripts/bash/prepare_dataset.sh index d318bb9..41d4f3e 100644 --- a/scripts/bash/prepare_dataset.sh +++ b/scripts/bash/prepare_dataset.sh @@ -109,6 +109,6 @@ if [ $OS_NAME = "linux" ]; then echo "Setting up ffmpeg v4l2loopback" sudo modprobe v4l2loopback devices=1 video_nr=2 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices - nohup sudo ffmpeg -hide_banner -re -stream_loop -1 -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -vcodec copy -f v4l2 -pix_fmt yuv420p /dev/video2 & + nohup sudo ffmpeg -hide_banner -re -stream_loop -1 -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 -f v4l2 -pix_fmt yuv420p /dev/video2 & echo "Done" fi From d6e9f7ff8aaa337f153ce6c5ec3826edf1587f75 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 19:30:02 +0530 Subject: [PATCH 52/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20Enabled=20debugging.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/sourcer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index 534974c..2fb8355 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -155,6 +155,7 @@ def probe_stream(self, default_stream_indexes=(0, 0)): self.__forcevalidatesource if self.__source_demuxer is None else True ), ) + logger.exception(self.__ffsp_output) # parse resolution and framerate video_rfparams = self.__extract_resolution_framerate( default_stream=default_stream_indexes[0] From 634ebab3dfc2d198d85ff6b92e5dcf965917cf4a Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 19:33:55 +0530 Subject: [PATCH 53/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index c6131b7..4873126 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -65,7 +65,7 @@ jobs: shell: bash - name: Run pytest and flake8 run: | - timeout 1200 pytest --verbose --cov=deffcode --cov-report=xml --cov-report term-missing tests/ || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; else echo "EXIT_CODE=$code" >>$GITHUB_ENV; fi + timeout 1200 sudo pytest --verbose --cov=deffcode --cov-report=xml --cov-report term-missing 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() - name: Upload coverage to Codecov From 2c2644ad3b6bd7650619379f9c9895e64a73ec62 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 19:37:31 +0530 Subject: [PATCH 54/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20bugs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 4873126..19fdea5 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -65,7 +65,7 @@ jobs: shell: bash - name: Run pytest and flake8 run: | - timeout 1200 sudo pytest --verbose --cov=deffcode --cov-report=xml --cov-report term-missing tests/ || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; else echo "EXIT_CODE=$code" >>$GITHUB_ENV; fi + timeout 1200 sudo python -m pytest --verbose --cov=deffcode --cov-report=xml --cov-report term-missing 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() - name: Upload coverage to Codecov From a443076ef22d5138fc269839336dbbb4ce089a0c Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 19:43:23 +0530 Subject: [PATCH 55/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20bugs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CIlinux.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/CIlinux.yml b/.github/workflows/CIlinux.yml index 19fdea5..d118185 100644 --- a/.github/workflows/CIlinux.yml +++ b/.github/workflows/CIlinux.yml @@ -54,11 +54,11 @@ jobs: sudo chmod +x scripts/bash/prepare_dataset.sh - name: Install Pip Dependencies run: | - pip install -U pip wheel numpy - pip install -U . - pip install git+https://github.com/abhiTronix/vidgear@testing#egg=vidgear[core] - pip install -U opencv-python-headless - pip install -U flake8 six codecov pytest pytest-cov + sudo pip install -U pip wheel numpy + sudo pip install -U . + sudo pip install git+https://github.com/abhiTronix/vidgear@testing#egg=vidgear[core] + sudo pip install -U opencv-python-headless + sudo pip install -U flake8 six codecov pytest pytest-cov if: success() - name: Run prepare_dataset Bash script run: bash scripts/bash/prepare_dataset.sh From 0c026ed8b5b9f8777e59d8193cfa585f3c825675 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 19:56:42 +0530 Subject: [PATCH 56/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20tests=20bugs?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/essentials.py | 7 ++++++- tests/test_ffdecoder.py | 6 ++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/essentials.py b/tests/essentials.py index 2280bb3..1b77b66 100644 --- a/tests/essentials.py +++ b/tests/essentials.py @@ -94,7 +94,12 @@ def return_generated_frames_path(path): # check if empty if not os.listdir(frame_dir): # Define writer with default parameters - writer = WriteGear(output_filename="Output.mp4", custom_ffmpeg=path) + writer = WriteGear( + output_filename=os.path.join( + *[tempfile.gettempdir(), "temp_write", "Output.mp4"] + ), + custom_ffmpeg=path, + ) # execute FFmpeg command writer.execute_ffmpeg_cmd(["-i", video_path, frames_path]) # safely close writer diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index 404eded..c90375e 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -36,7 +36,6 @@ ) from PIL import Image from deffcode import FFdecoder -from vidgear.gears import WriteGear from deffcode.utils import logger_handler # define test logger @@ -45,7 +44,6 @@ logger.addHandler(logger_handler()) logger.setLevel(logging.DEBUG) - @pytest.mark.parametrize( "source, output", [ @@ -218,13 +216,13 @@ def test_seek_n_save(extraparams, pixfmts): # check if frame is None if not (frame is None) and pixfmts == "rgba": # Convert and save our output - filename = os.path.abspath("filename_rgba.jpeg") + filename = os.path.abspath(os.path.join(*[tempfile.gettempdir(), "temp_write", "filename_rgba.jpeg"])) im = Image.fromarray(frame) im = im.convert("RGB") im.save(filename) elif not (frame is None) and pixfmts == "gray": # Convert and save our output - filename = os.path.abspath("filename_gray.png") + filename = os.path.abspath(os.path.join(*[tempfile.gettempdir(), "temp_write", "filename_gray.png"])) cv2.imwrite(filename, frame) else: raise AssertionError("Test Failed!") From 7deef9d163b7cbd954d10cacc7b6b2fac30039c0 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 20:54:25 +0530 Subject: [PATCH 57/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20bugs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/bash/prepare_dataset.sh | 1 + tests/essentials.py | 15 --------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/scripts/bash/prepare_dataset.sh b/scripts/bash/prepare_dataset.sh index 41d4f3e..fb681f3 100644 --- a/scripts/bash/prepare_dataset.sh +++ b/scripts/bash/prepare_dataset.sh @@ -106,6 +106,7 @@ curl -L https://github.com/abhiTronix/Imbakup/releases/download/vid-001/jellyfis echo "Done Downloading Test-Data!" if [ $OS_NAME = "linux" ]; then + ffmpeg -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 "$TMPFOLDER"/temp_images/out%d.png echo "Setting up ffmpeg v4l2loopback" sudo modprobe v4l2loopback devices=1 video_nr=2 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices diff --git a/tests/essentials.py b/tests/essentials.py index 1b77b66..90de90a 100644 --- a/tests/essentials.py +++ b/tests/essentials.py @@ -87,23 +87,8 @@ def return_generated_frames_path(path): """ returns Test video path """ - # create paths - video_path = return_testvideo_path(fmt="vo") frame_dir = "{}/temp_images".format(tempfile.gettempdir()) frames_path = os.path.join(frame_dir, "out%d.png") - # check if empty - if not os.listdir(frame_dir): - # Define writer with default parameters - writer = WriteGear( - output_filename=os.path.join( - *[tempfile.gettempdir(), "temp_write", "Output.mp4"] - ), - custom_ffmpeg=path, - ) - # execute FFmpeg command - writer.execute_ffmpeg_cmd(["-i", video_path, frames_path]) - # safely close writer - writer.close() # return path return frames_path From 15cc07000f28347ae9dce2ef85b5fcad2ac36703 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 21:07:07 +0530 Subject: [PATCH 58/76] =?UTF-8?q?=F0=9F=94=87=20Sourcer:=20Disabled=20volu?= =?UTF-8?q?ntary=20logging.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/sourcer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index 2fb8355..534974c 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -155,7 +155,6 @@ def probe_stream(self, default_stream_indexes=(0, 0)): self.__forcevalidatesource if self.__source_demuxer is None else True ), ) - logger.exception(self.__ffsp_output) # parse resolution and framerate video_rfparams = self.__extract_resolution_framerate( default_stream=default_stream_indexes[0] From af5153e40ad4f8c2046b475c8a28cb567ba3657a Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 21:08:54 +0530 Subject: [PATCH 59/76] =?UTF-8?q?=F0=9F=90=9B=20Bash:=20Fixed=20bugs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/bash/prepare_dataset.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/bash/prepare_dataset.sh b/scripts/bash/prepare_dataset.sh index fb681f3..e6c1f3e 100644 --- a/scripts/bash/prepare_dataset.sh +++ b/scripts/bash/prepare_dataset.sh @@ -105,8 +105,11 @@ curl -L https://github.com/abhiTronix/Imbakup/releases/download/vid-001/jellyfis curl -L https://github.com/abhiTronix/Imbakup/releases/download/vid-001/jellyfish-120-mbps-4k-uhd-h264.mkv -o 120_mbps_4k_uhd_h264.mkv echo "Done Downloading Test-Data!" +echo "Preparing images from video" +ffmpeg -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 "$TMPFOLDER"/temp_images/out%d.png +echo "Done" + if [ $OS_NAME = "linux" ]; then - ffmpeg -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 "$TMPFOLDER"/temp_images/out%d.png echo "Setting up ffmpeg v4l2loopback" sudo modprobe v4l2loopback devices=1 video_nr=2 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices From 6b9e346f3c5fd4bba45feb5ec219756d25a19285 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sat, 9 Jul 2022 21:13:08 +0530 Subject: [PATCH 60/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20image=20sets?= =?UTF-8?q?=20not=20creating=20for=20non-linux=20envs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/bash/prepare_dataset.sh | 6 ++---- tests/essentials.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/scripts/bash/prepare_dataset.sh b/scripts/bash/prepare_dataset.sh index e6c1f3e..15e049e 100644 --- a/scripts/bash/prepare_dataset.sh +++ b/scripts/bash/prepare_dataset.sh @@ -105,11 +105,9 @@ curl -L https://github.com/abhiTronix/Imbakup/releases/download/vid-001/jellyfis curl -L https://github.com/abhiTronix/Imbakup/releases/download/vid-001/jellyfish-120-mbps-4k-uhd-h264.mkv -o 120_mbps_4k_uhd_h264.mkv echo "Done Downloading Test-Data!" -echo "Preparing images from video" -ffmpeg -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 "$TMPFOLDER"/temp_images/out%d.png -echo "Done" - if [ $OS_NAME = "linux" ]; then + echo "Preparing images from video" + ffmpeg -i "$TMPFOLDER"/Downloads/Test_videos/BigBuckBunny_4sec_VO.mp4 "$TMPFOLDER"/temp_images/out%d.png echo "Setting up ffmpeg v4l2loopback" sudo modprobe v4l2loopback devices=1 video_nr=2 exclusive_caps=1 card_label='VCamera' sudo v4l2-ctl --list-devices diff --git a/tests/essentials.py b/tests/essentials.py index 90de90a..7227dec 100644 --- a/tests/essentials.py +++ b/tests/essentials.py @@ -87,8 +87,23 @@ def return_generated_frames_path(path): """ returns Test video path """ + # create paths frame_dir = "{}/temp_images".format(tempfile.gettempdir()) frames_path = os.path.join(frame_dir, "out%d.png") + # check if empty + if platform.system() != "Linux" and not os.listdir(frame_dir): + video_path = return_testvideo_path(fmt="vo") + # Define writer with default parameters + writer = WriteGear( + output_filename=os.path.join( + *[tempfile.gettempdir(), "temp_write", "Output.mp4"] + ), + custom_ffmpeg=path, + ) + # execute FFmpeg command + writer.execute_ffmpeg_cmd(["-i", video_path, frames_path]) + # safely close writer + writer.close() # return path return frames_path From 8a7cf0c7e939f2bc0e0973fb96f5f8b888534d4f Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sun, 10 Jul 2022 00:24:20 +0530 Subject: [PATCH 61/76] =?UTF-8?q?=F0=9F=90=9B=20Sourcer:=20Enabled=20debug?= =?UTF-8?q?ging=20for=20Darwin=20systems.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/sourcer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index 534974c..444d029 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -19,7 +19,7 @@ """ # import required libraries -import re, logging, os +import re, logging, os, platform import numpy as np # import utils packages @@ -155,6 +155,7 @@ def probe_stream(self, default_stream_indexes=(0, 0)): self.__forcevalidatesource if self.__source_demuxer is None else True ), ) + platform.system() == "Darwin" and logger.exception(self.__ffsp_output) # parse resolution and framerate video_rfparams = self.__extract_resolution_framerate( default_stream=default_stream_indexes[0] From 6d157e5c22b175fea6bc442d19e59d2e673e1826 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sun, 10 Jul 2022 08:44:26 +0530 Subject: [PATCH 62/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/sourcer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index 444d029..ba3876f 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -155,7 +155,6 @@ def probe_stream(self, default_stream_indexes=(0, 0)): self.__forcevalidatesource if self.__source_demuxer is None else True ), ) - platform.system() == "Darwin" and logger.exception(self.__ffsp_output) # parse resolution and framerate video_rfparams = self.__extract_resolution_framerate( default_stream=default_stream_indexes[0] @@ -197,6 +196,7 @@ def probe_stream(self, default_stream_indexes=(0, 0)): elif self.__default_audio_bitrate or self.__default_audio_samplerate: self.__contains_audio = True else: + logger.exception("Extracted Metadata: {}".format(self.__ffsp_output)) raise IOError( "Invalid source provided. No usable Audio/Video stream detected. Aborting!!!" ) From 11ed026b57ce445c4e82c9ae3d1771b472484151 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sun, 10 Jul 2022 11:11:08 +0530 Subject: [PATCH 63/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/sourcer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index ba3876f..9f963b7 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -286,6 +286,7 @@ def __validate_source(self, source, source_demuxer=None, forced_validate=False): logger.error("`source` value is unusable or unsupported!") # discard the value otherwise raise ValueError("Input source is invalid. Aborting!") + logger.debug("Source was: {}".format(source)) # extract metadata metadata = check_sp_output( [self.__ffmpeg, "-hide_banner"] @@ -293,6 +294,7 @@ def __validate_source(self, source, source_demuxer=None, forced_validate=False): + ["-i", source], force_retrieve_stderr=True, ) + logger.debug("Metadata was: {}".format(metadata.decode("utf-8").strip())) # filter and return return metadata.decode("utf-8").strip() From 26702ed79dd34dac9fca219a4dcf2c8195a27a54 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sun, 10 Jul 2022 11:20:37 +0530 Subject: [PATCH 64/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/ffhelper.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/deffcode/ffhelper.py b/deffcode/ffhelper.py index af6b56e..b55b6bf 100644 --- a/deffcode/ffhelper.py +++ b/deffcode/ffhelper.py @@ -488,6 +488,8 @@ def check_sp_output(*args, **kwargs): output, stderr = process.communicate() retcode = process.poll() + logger.debug(retcode) + # handle return code if retcode and not (retrieve_stderr): cmd = kwargs.get("args") @@ -497,4 +499,7 @@ def check_sp_output(*args, **kwargs): error.output = output raise error + logger.debug(output.decode("utf-8")) + logger.exception(stderr.decode("utf-8")) + return output if not (retrieve_stderr) else stderr From 7d6f3800e715652fb1aa094f5abac1b8f542ffcd Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sun, 10 Jul 2022 11:43:56 +0530 Subject: [PATCH 65/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20bugs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/ffhelper.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deffcode/ffhelper.py b/deffcode/ffhelper.py index b55b6bf..2e78cf3 100644 --- a/deffcode/ffhelper.py +++ b/deffcode/ffhelper.py @@ -489,7 +489,7 @@ def check_sp_output(*args, **kwargs): retcode = process.poll() logger.debug(retcode) - + # handle return code if retcode and not (retrieve_stderr): cmd = kwargs.get("args") @@ -499,7 +499,7 @@ def check_sp_output(*args, **kwargs): error.output = output raise error - logger.debug(output.decode("utf-8")) - logger.exception(stderr.decode("utf-8")) + logger.debug("Output is None" if output is None else output.decode("utf-8")) + logger.exception("Stderr is None" if stderr is None else stderr.decode("utf-8")) return output if not (retrieve_stderr) else stderr From 974604e18e97dadce65303013dddebd1bdea4dd2 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sun, 10 Jul 2022 12:06:40 +0530 Subject: [PATCH 66/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20bugs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/ffhelper.py | 2 ++ tests/test_ffdecoder.py | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/deffcode/ffhelper.py b/deffcode/ffhelper.py index 2e78cf3..cc26194 100644 --- a/deffcode/ffhelper.py +++ b/deffcode/ffhelper.py @@ -478,6 +478,8 @@ def check_sp_output(*args, **kwargs): # handle additional params retrieve_stderr = kwargs.pop("force_retrieve_stderr", False) + logger.debug(*args) + # execute command in subprocess process = sp.Popen( stdout=sp.PIPE, diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index c90375e..2c154b6 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -44,6 +44,7 @@ logger.addHandler(logger_handler()) logger.setLevel(logging.DEBUG) + @pytest.mark.parametrize( "source, output", [ @@ -73,7 +74,7 @@ def test_source_playback(source, output): instance = FFdecoder( source, frame_format="bgr24", - custom_ffmpeg=return_static_ffmpeg(), + custom_ffmpeg=return_static_ffmpeg() if platform.system() != "Darwin" else "", verbose=True, ) # force unknown number of frames(like camera) {special case} @@ -216,13 +217,21 @@ def test_seek_n_save(extraparams, pixfmts): # check if frame is None if not (frame is None) and pixfmts == "rgba": # Convert and save our output - filename = os.path.abspath(os.path.join(*[tempfile.gettempdir(), "temp_write", "filename_rgba.jpeg"])) + filename = os.path.abspath( + os.path.join( + *[tempfile.gettempdir(), "temp_write", "filename_rgba.jpeg"] + ) + ) im = Image.fromarray(frame) im = im.convert("RGB") im.save(filename) elif not (frame is None) and pixfmts == "gray": # Convert and save our output - filename = os.path.abspath(os.path.join(*[tempfile.gettempdir(), "temp_write", "filename_gray.png"])) + filename = os.path.abspath( + os.path.join( + *[tempfile.gettempdir(), "temp_write", "filename_gray.png"] + ) + ) cv2.imwrite(filename, frame) else: raise AssertionError("Test Failed!") From 7556847ecadc6f8bd8487880390d14615377c1e5 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sun, 10 Jul 2022 12:20:15 +0530 Subject: [PATCH 67/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20bugs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_ffdecoder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index 2c154b6..e241b0f 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -74,7 +74,7 @@ def test_source_playback(source, output): instance = FFdecoder( source, frame_format="bgr24", - custom_ffmpeg=return_static_ffmpeg() if platform.system() != "Darwin" else "", + custom_ffmpeg="", verbose=True, ) # force unknown number of frames(like camera) {special case} From f4994ed82269ef05a3efe313e6f59c432e5df866 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Sun, 10 Jul 2022 12:29:29 +0530 Subject: [PATCH 68/76] =?UTF-8?q?=F0=9F=91=B7=20CI:=20More=20changes.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_ffdecoder.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index e241b0f..6f664d2 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -74,7 +74,6 @@ def test_source_playback(source, output): instance = FFdecoder( source, frame_format="bgr24", - custom_ffmpeg="", verbose=True, ) # force unknown number of frames(like camera) {special case} @@ -86,7 +85,6 @@ def test_source_playback(source, output): decoder = FFdecoder( source, frame_format="bgr24", - custom_ffmpeg=return_static_ffmpeg(), verbose=True, ).formulate() From 4fb36ac4d3c56ee28c7005e50083cc9816514cd4 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Tue, 12 Jul 2022 08:03:09 +0530 Subject: [PATCH 69/76] =?UTF-8?q?=F0=9F=94=A8=20Bash=20Script:=20Updated?= =?UTF-8?q?=20FFmpeg=20Static=20Binaries=20links=20to=20latest.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ⚡️ Updated download links to abhiTronix/ffmpeg-static-builds - hosting latest available versions. - 🔖 Updated date/version tag to `12-07-2022`. - 🔥 Removed depreciated binaries download links and code. --- scripts/bash/prepare_dataset.sh | 34 ++++++++++----------------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/scripts/bash/prepare_dataset.sh b/scripts/bash/prepare_dataset.sh index 15e049e..c9a7aa8 100644 --- a/scripts/bash/prepare_dataset.sh +++ b/scripts/bash/prepare_dataset.sh @@ -31,7 +31,7 @@ mkdir -p "$TMPFOLDER"/Downloads/Test_videos MACHINE_BIT=$(uname -m) #Defining alternate ffmpeg static binaries date/version -ALTBINARIES_DATE=02-12-19 +ALTBINARIES_DATE="12-07-2022" # Acknowledging machine OS type case $(uname | tr '[:upper:]' '[:lower:]') in @@ -55,37 +55,23 @@ cd "$TMPFOLDER"/Downloads/FFmpeg_static if [ $OS_NAME = "linux" ]; then echo "Downloading Linux Static FFmpeg Binaries..." - if [ "$MACHINE_BIT" = "x86_64" ]; then - curl -L https://github.com/abhiTronix/ffmpeg-static-builds/raw/master/$ALTBINARIES_DATE/ffmpeg-release-amd64-static.tar.xz -o ffmpeg-release-amd64-static.tar.xz - tar -xJf ffmpeg-release-amd64-static.tar.xz - rm *.tar.* - mv ffmpeg* ffmpeg - else - curl -L https://github.com/abhiTronix/ffmpeg-static-builds/raw/master/$ALTBINARIES_DATE/ffmpeg-release-i686-static.tar.xz -o ffmpeg-release-i686-static.tar.xz - tar -xJf ffmpeg-release-i686-static.tar.xz - rm *.tar.* - mv ffmpeg* ffmpeg - fi + curl -LO https://github.com/abhiTronix/ffmpeg-static-builds/raw/master/$ALTBINARIES_DATE/linux/ffmpeg-git-amd64-static.tar.xz + tar -xJf ffmpeg-git-amd64-static.tar.xz + rm *.tar.* + mv ffmpeg* ffmpeg elif [ $OS_NAME = "windows" ]; then echo "Downloading Windows Static FFmpeg Binaries..." - if [ "$MACHINE_BIT" = "x86_64" ]; then - curl -L https://github.com/abhiTronix/ffmpeg-static-builds/raw/master/$ALTBINARIES_DATE/ffmpeg-latest-win64-static.zip -o ffmpeg-latest-win64-static.zip - unzip -qq ffmpeg-latest-win64-static.zip - rm ffmpeg-latest-win64-static.zip - mv ffmpeg-latest-win64-static ffmpeg - else - curl -L https://github.com/abhiTronix/ffmpeg-static-builds/raw/master/$ALTBINARIES_DATE/ffmpeg-latest-win32-static.zip -o ffmpeg-latest-win32-static.zip - unzip -qq ffmpeg-latest-win32-static.zip - rm ffmpeg-latest-win32-static.zip - mv ffmpeg-latest-win32-static ffmpeg - fi + curl -LO https://github.com/abhiTronix/ffmpeg-static-builds/raw/master/$ALTBINARIES_DATE/windows/ffmpeg-latest-win64-static.zip + unzip -qq ffmpeg-latest-win64-static.zip + rm ffmpeg-latest-win64-static.zip + mv ffmpeg-latest-win64-static ffmpeg else echo "Downloading MacOS64 Static FFmpeg Binary..." - curl -LO https://github.com/abhiTronix/ffmpeg-static-builds/raw/master/$ALTBINARIES_DATE/ffmpeg-latest-macos64-static.zip + curl -LO https://github.com/abhiTronix/ffmpeg-static-builds/raw/master/$ALTBINARIES_DATE/macOS/ffmpeg-latest-macos64-static.zip unzip -qq ffmpeg-latest-macos64-static.zip rm ffmpeg-latest-macos64-static.zip mv ffmpeg-latest-macos64-static ffmpeg From 12d7aa65b76197c3b3ad09345fb0f78433941a26 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Tue, 12 Jul 2022 08:05:02 +0530 Subject: [PATCH 70/76] =?UTF-8?q?=E2=8F=AA=EF=B8=8F=20CI:=20Reverted=20rec?= =?UTF-8?q?ent=20changes=20to=20tests.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_ffdecoder.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index 6f664d2..4200cfd 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -74,6 +74,7 @@ def test_source_playback(source, output): instance = FFdecoder( source, frame_format="bgr24", + custom_ffmpeg=return_static_ffmpeg(), verbose=True, ) # force unknown number of frames(like camera) {special case} @@ -85,6 +86,7 @@ def test_source_playback(source, output): decoder = FFdecoder( source, frame_format="bgr24", + custom_ffmpeg=return_static_ffmpeg(), verbose=True, ).formulate() From c5b95001fbd20645753e8c8128918d858fe7bf09 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Tue, 12 Jul 2022 08:15:45 +0530 Subject: [PATCH 71/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Updated=20test=20to?= =?UTF-8?q?=20fix=20bug.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_ffdecoder.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index 4200cfd..c78aa8b 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -46,22 +46,24 @@ @pytest.mark.parametrize( - "source, output", + "source, custom_ffmpeg, output", [ (return_testvideo_path(fmt="av"), True), ( "https://raw.githubusercontent.com/abhiTronix/Imbakup/master/Images/starship.mkv", + "", True, ), - ("unknown://invalid.com/", False), - (return_testvideo_path(fmt="ao"), False), + ("unknown://invalid.com/", return_static_ffmpeg(), False), + (return_testvideo_path(fmt="ao"), return_static_ffmpeg(), False), ( return_generated_frames_path(return_static_ffmpeg()), + return_static_ffmpeg(), True, ), ], ) -def test_source_playback(source, output): +def test_source_playback(source, custom_ffmpeg, output): """ Paths Source Playback - Test playback of various source paths/urls supported by FFdecoder API """ @@ -74,7 +76,7 @@ def test_source_playback(source, output): instance = FFdecoder( source, frame_format="bgr24", - custom_ffmpeg=return_static_ffmpeg(), + custom_ffmpeg=custom_ffmpeg, verbose=True, ) # force unknown number of frames(like camera) {special case} @@ -86,7 +88,7 @@ def test_source_playback(source, output): decoder = FFdecoder( source, frame_format="bgr24", - custom_ffmpeg=return_static_ffmpeg(), + custom_ffmpeg=custom_ffmpeg, verbose=True, ).formulate() From 918102e6de0713ff626e6c98d3414c2743eb2c02 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Tue, 12 Jul 2022 08:30:47 +0530 Subject: [PATCH 72/76] =?UTF-8?q?=F0=9F=90=9B=20CI:=20Fixed=20missing=20pa?= =?UTF-8?q?rameter=20bug.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_ffdecoder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_ffdecoder.py b/tests/test_ffdecoder.py index c78aa8b..9ca19eb 100644 --- a/tests/test_ffdecoder.py +++ b/tests/test_ffdecoder.py @@ -48,13 +48,13 @@ @pytest.mark.parametrize( "source, custom_ffmpeg, output", [ - (return_testvideo_path(fmt="av"), True), + (return_testvideo_path(fmt="av"), return_static_ffmpeg(), True), ( "https://raw.githubusercontent.com/abhiTronix/Imbakup/master/Images/starship.mkv", "", True, ), - ("unknown://invalid.com/", return_static_ffmpeg(), False), + ("unknown://invalid.com/", "", False), (return_testvideo_path(fmt="ao"), return_static_ffmpeg(), False), ( return_generated_frames_path(return_static_ffmpeg()), From dfee8ab72230b0a4b4c55e257c3d88a3cdb52440 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Wed, 13 Jul 2022 22:49:31 +0530 Subject: [PATCH 73/76] =?UTF-8?q?=F0=9F=94=87=20Maintenance:=20Removed=20r?= =?UTF-8?q?edundant=20logging.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 📝 Docs: Updated roadmap. --- README.md | 2 +- deffcode/ffhelper.py | 13 ++----------- deffcode/sourcer.py | 3 --- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 298cd2f..a098d28 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ For more examples and in-depth usage guide, kindly refer our **[Basic Recipes - [x] Add project Issue and PR templates. - [x] Add related unit tests with `pytests`. - [x] Automate stuff with Continuous Integration. -- [ ] Add Devices and Screen Capture support. [:construction:WIP] +- [x] Add Devices and Screen Capture support. - [ ] Add Multiple Source Inputs support. - [ ] Resolve High CPU usage issue with WriteGear API. - [ ] Add more parameters to Sourcer API's metadata. diff --git a/deffcode/ffhelper.py b/deffcode/ffhelper.py index cc26194..9b42b22 100644 --- a/deffcode/ffhelper.py +++ b/deffcode/ffhelper.py @@ -474,12 +474,8 @@ def check_sp_output(*args, **kwargs): if platform.system() == "Windows": # see comment https://bugs.python.org/msg370334 sp._cleanup = lambda: None - # handle additional params retrieve_stderr = kwargs.pop("force_retrieve_stderr", False) - - logger.debug(*args) - # execute command in subprocess process = sp.Popen( stdout=sp.PIPE, @@ -487,11 +483,9 @@ def check_sp_output(*args, **kwargs): *args, **kwargs, ) + # communicate and poll process output, stderr = process.communicate() retcode = process.poll() - - logger.debug(retcode) - # handle return code if retcode and not (retrieve_stderr): cmd = kwargs.get("args") @@ -500,8 +494,5 @@ def check_sp_output(*args, **kwargs): error = sp.CalledProcessError(retcode, cmd) error.output = output raise error - - logger.debug("Output is None" if output is None else output.decode("utf-8")) - logger.exception("Stderr is None" if stderr is None else stderr.decode("utf-8")) - + # return output return output if not (retrieve_stderr) else stderr diff --git a/deffcode/sourcer.py b/deffcode/sourcer.py index 9f963b7..e586721 100644 --- a/deffcode/sourcer.py +++ b/deffcode/sourcer.py @@ -196,7 +196,6 @@ def probe_stream(self, default_stream_indexes=(0, 0)): elif self.__default_audio_bitrate or self.__default_audio_samplerate: self.__contains_audio = True else: - logger.exception("Extracted Metadata: {}".format(self.__ffsp_output)) raise IOError( "Invalid source provided. No usable Audio/Video stream detected. Aborting!!!" ) @@ -286,7 +285,6 @@ def __validate_source(self, source, source_demuxer=None, forced_validate=False): logger.error("`source` value is unusable or unsupported!") # discard the value otherwise raise ValueError("Input source is invalid. Aborting!") - logger.debug("Source was: {}".format(source)) # extract metadata metadata = check_sp_output( [self.__ffmpeg, "-hide_banner"] @@ -294,7 +292,6 @@ def __validate_source(self, source, source_demuxer=None, forced_validate=False): + ["-i", source], force_retrieve_stderr=True, ) - logger.debug("Metadata was: {}".format(metadata.decode("utf-8").strip())) # filter and return return metadata.decode("utf-8").strip() From c8ce9159f9b4697b9e91ea8c492b06581c4ab61a Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Thu, 14 Jul 2022 08:07:02 +0530 Subject: [PATCH 74/76] =?UTF-8?q?=F0=9F=94=8A=20FFhelper:=20Logged=20error?= =?UTF-8?q?=20message=20on=20metadata=20extraction=20failure.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deffcode/ffhelper.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/deffcode/ffhelper.py b/deffcode/ffhelper.py index 9b42b22..cf31a5d 100644 --- a/deffcode/ffhelper.py +++ b/deffcode/ffhelper.py @@ -494,5 +494,9 @@ def check_sp_output(*args, **kwargs): error = sp.CalledProcessError(retcode, cmd) error.output = output raise error - # return output + # raise error if no output + bool(output) or bool(stderr) or logger.error( + "FFmpeg Pipline failed to exact any metadata!" + ) + # return output otherwise return output if not (retrieve_stderr) else stderr From 9aef1bed8c38941b85633c6cbc71bb252962542b Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Thu, 14 Jul 2022 13:06:25 +0530 Subject: [PATCH 75/76] =?UTF-8?q?=F0=9F=93=9D=20Docs:=20Updated=20Changelo?= =?UTF-8?q?g.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/changelog.md | 123 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 102 insertions(+), 21 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 01785e6..54dd672 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -21,6 +21,88 @@ limitations under the License. # Release Notes +## v0.2.1 (2022-07-14) :material-new-box: + +??? tip "New Features" + - [x] **Sourcer API:** + * Implemented support for extracting metadata from live input devices/sources. + * Added new `source_demuxer` and `forced_validate` parameters to `validate_source` internal method. + * Implemented logic to validate `source_demuxer` value against FFmpeg supported demuxers. + * Rearranged metadata dict. + * Updated Code comments. + - [x] **FFdecoder API:** + * Implemented functionality to supported live devices by allowing device path and respective demuxer into pipeline. + * Included `-f` FFmpeg parameter into pipeline to specify source device demuxer. + * Added special case for discarding `-framerate` value with Nonetype. + - [x] **CI:** + * Added new unittest `test_camera_capture()` to test support for live Virtual Camera devices. + * Added new `v4l2loopback-dkms`, `v4l2loopback-utils` and kernel related APT dependencies. + - [x] **Bash Script:** + * Added new FFmpeg command to extract image datasets from given video on Linux envs. + * Created live Virtual Camera devices through `v4l2loopback` library on Github Actions Linux envs. + * Added `v4l2loopback` modprobe command to setup Virtual Camera named `VCamera` dynamically at `/dev/video2`. + * Added `v4l2-ctl --list-devices` command for debugging. + * Implemented FFmpeg command through `nohup`(no hangup) to feed video loop input to Virtual Camera in the background. + +??? success "Updates/Improvements" + - [x] Sourcer API: + * Only either `source_demuxer` or `source_extension` attribute can be present in metadata. + * Enforced `forced_validate` for live input devices/sources in `validate_source` internal method. + - [x] FFdecoder API: + * Rearranged FFmpeg parameters in pipeline. + * Removed redundant code. + * Updated Code comments. + - [x] FFhelper API: + * Logged error message on metadata extraction failure. + - [x] CI: + * Restricted `test_camera_capture()` unittest to Linux envs only. + * Removed `return_generated_frames_path()` method support for Linux envs. + * Pinned jinja2 `3.1.0` or above breaking mkdocs. + * `jinja2>=3.1.0` breaks mkdocs (mkdocs/mkdocs#2799), therefore pinned jinja2 version to `<3.1.0`. + - [x] Bash Script: + * Updated to latest FFmpeg Static Binaries links. + * Updated download links to abhiTronix/ffmpeg-static-builds * hosting latest available versions. + * Updated date/version tag to `12-07-2022`. + * Removed depreciated binaries download links and code. + - [x] Setup: + * Bumped version to 0.2.1. + - [x] Docs: + * Updated Changelog.md + * Updated Roadmap in README.md + +??? danger "Breaking Updates/Changes" + - [x] :skull_crossbones: **Implement support for live input devices/sources.** + * `source` parameter now accepts device name or path. + * Added `source_demuxer` parameter to specify demuxer for live input devices/sources. + * Implemented Automated inserting of `-f` FFmpeg parameter whenever `source_demuxer` is specified by the user. + +??? bug "Bug-fixes" + - [x] Sourcer API: + * Fixed Nonetype value bug in `source_demuxer` assertion logic. + * Fixed typos in parameter names. + * Added missing import. + - [x] FFhelper API: + * Logged error message on metadata extraction failure. + * Fixed bug with `get_supported_demuxers` not detecting name patterns with commas. + * Removed redundant logging. + - [x] CI: + * Fixed critical permission bug causing `v4l2loopback` to fail on Github Actions Linux envs. + * Elevated privileges to `root` by adding `sudo` to all commands(including bash scripts and python commands). + * Updated vidgear dependency to pip install from its git `testing` branch with recent bug fixes. + * Replaced relative paths with absolute paths in unit tests. + * Fixed WriteGear API unable to write frames due to permission errors. + * Fixed `test_source_playback()` test failing on Darwin envs with OLD FFmpeg binaries. + * Removed `custom_ffmpeg` value for Darwin envs. + * Fixed various naming typos. + * Fixed missing APT dependencies. + +??? question "Pull Requests" + * PR #17 + +  + +  + ## v0.2.0 (2022-03-21) ??? tip "New Features" @@ -190,20 +272,19 @@ limitations under the License. - 🔧 Imported prepare_dataset.sh from vidgear for downloading pytest datasets to `temp` dir. ??? success "Updates/Improvements" - - [x] API: - - FFdecoder API: - - Removed redundant forcing `-r` FFmpeg parameter for image sequences as source. - - Removed redundant checks on `-vf` FFmpeg parameter. - - FFmpeg parameter `-s` will be discarded in favor of `-custom_resolution` attribute. - - Replaced `-constant_framerate` with FFmpeg `-framerate` attribute. - - Replaced `-custom_source_params` with correct `-custom_sourcer_params` attribute. - - Renamed `operational_mode` metadata parameter to `ffdecoder_operational_mode`. - - Sourcer API: - - Converted all Sourcer APIs public available variables into private ones for stability. - * All Sourcer's publicly accessed variable metadata values in FFdecoder, therefore replaced with dictionary counterparts. - - Moved FFmpeg path validation and handling to Sourcer from FFdecoder API. - * Moved `-ffmpeg_download_path` dictionary attribute to Sourcer API's `sourcer_params` parameter. - * Moved dependencies and related functions. + - [x] FFdecoder API: + - Removed redundant forcing `-r` FFmpeg parameter for image sequences as source. + - Removed redundant checks on `-vf` FFmpeg parameter. + - FFmpeg parameter `-s` will be discarded in favor of `-custom_resolution` attribute. + - Replaced `-constant_framerate` with FFmpeg `-framerate` attribute. + - Replaced `-custom_source_params` with correct `-custom_sourcer_params` attribute. + - Renamed `operational_mode` metadata parameter to `ffdecoder_operational_mode`. + - [x] Sourcer API: + - Converted all Sourcer APIs public available variables into private ones for stability. + * All Sourcer's publicly accessed variable metadata values in FFdecoder, therefore replaced with dictionary counterparts. + - Moved FFmpeg path validation and handling to Sourcer from FFdecoder API. + * Moved `-ffmpeg_download_path` dictionary attribute to Sourcer API's `sourcer_params` parameter. + * Moved dependencies and related functions. - [x] CI: - Excluded `dev` branch from triggering workflow on any environment. - Updated yaml files to exclude beta `dev` branch from triggering workflow on any environment. @@ -256,11 +337,11 @@ limitations under the License. - Added useful comments for convenience. ??? danger "Breaking Updates/Changes" - - [ ] Sourcer API will now raises Assertion error if `probe_stream()` not called before calling `retrieve_metadata()`. - - [ ] Only `-framerate` values greater than `0.0` are now valid. - - [ ] Renamed `decode_stream` to `probe_stream` in Sourcer API. - - [ ] Any of _video bitrate_ or _video framerate_ are sufficient to validate if source contains valid video stream(s). - - [ ] Any of _audio bitrate_ or _audio samplerate_ are sufficient to validate if source contains valid audio stream(s). + - [x] :skull_crossbones: Sourcer API will now raises Assertion error if `probe_stream()` not called before calling `retrieve_metadata()`. + - [x] :skull_crossbones: Only `-framerate` values greater than `0.0` are now valid. + - [x] :skull_crossbones: Renamed `decode_stream` to `probe_stream` in Sourcer API. + - [x] :skull_crossbones: Any of _video bitrate_ or _video framerate_ are sufficient to validate if source contains valid video stream(s). + - [x] :skull_crossbones: Any of _audio bitrate_ or _audio samplerate_ are sufficient to validate if source contains valid audio stream(s). ??? bug "Bug-fixes" - [x] APIs: @@ -330,12 +411,12 @@ limitations under the License. * Added `.gitignore` ??? success "Updates/Improvements" - - [x] **Maintenance:** + - [x] Maintenance: * Bumped version to `0.1.0` * Updated LICENSE notice to add vidgear code usage notice. ??? danger "Breaking Updates/Changes" - - [ ] **Fixed support for Python-3.7 and above legacies only.** + - [x] :skull_crossbones: **Fixed support for Python-3.7 and above legacies only.** ??? bug "Bug-fixes" - [x] Docs: From a22465f6dd78255b1df22ab479305148afcb2204 Mon Sep 17 00:00:00 2001 From: abhiTronix Date: Thu, 14 Jul 2022 13:43:20 +0530 Subject: [PATCH 76/76] =?UTF-8?q?=F0=9F=9A=A7=20Setup:=20Updated=20metadat?= =?UTF-8?q?a.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 6a1d1f2..13ca9bd 100644 --- a/setup.py +++ b/setup.py @@ -41,7 +41,7 @@ name="deffcode", packages=["deffcode"], version=pkg_version["__version__"], - description="High-performance Real-time Video frames Generator for generating blazingly fast video frames in python.", + description="High-performance Real-time FFmpeg based Video-Decoder in python.", license="Apache License 2.0", author="Abhishek Thakur", install_requires=[ @@ -57,8 +57,10 @@ url="https://abhitronix.github.io/deffcode", keywords=[ "FFmpeg", + "Decoder", "Video Processing", "Computer Vision", + "Video Decoding", ], classifiers=[ "Development Status :: 5 - Production/Stable",