framesource 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- framesource-0.3.0/.github/workflows/ci.yml +80 -0
- framesource-0.3.0/.github/workflows/publish.yaml +45 -0
- framesource-0.3.0/.github/workflows/release.yml +41 -0
- framesource-0.3.0/.gitignore +104 -0
- framesource-0.3.0/CHANGELOG.md +129 -0
- framesource-0.3.0/LICENSE +21 -0
- framesource-0.3.0/MANIFEST.in +5 -0
- framesource-0.3.0/PKG-INFO +787 -0
- framesource-0.3.0/README.md +712 -0
- framesource-0.3.0/example.py +498 -0
- framesource-0.3.0/examples/README.md +156 -0
- framesource-0.3.0/examples/audio_spectrogram_example.py +187 -0
- framesource-0.3.0/examples/camera_360_example.py +286 -0
- framesource-0.3.0/examples/fisheye_ptz_example.py +264 -0
- framesource-0.3.0/examples/image_folder_example.py +88 -0
- framesource-0.3.0/examples/industrial_cameras_example.py +133 -0
- framesource-0.3.0/examples/inference_pipeline_example.py +171 -0
- framesource-0.3.0/examples/ipcamera_example.py +92 -0
- framesource-0.3.0/examples/multiple_cameras_example.py +151 -0
- framesource-0.3.0/examples/multiple_cameras_external_threading.py +235 -0
- framesource-0.3.0/examples/realsense_example.py +81 -0
- framesource-0.3.0/examples/record_replay_example.py +193 -0
- framesource-0.3.0/examples/run_examples.py +71 -0
- framesource-0.3.0/examples/screen_capture_example.py +66 -0
- framesource-0.3.0/examples/source_swap_example.py +161 -0
- framesource-0.3.0/examples/test_window_discovery.py +107 -0
- framesource-0.3.0/examples/threading_utils_examples.py +159 -0
- framesource-0.3.0/examples/video_file_example.py +75 -0
- framesource-0.3.0/examples/webcam_example.py +127 -0
- framesource-0.3.0/media/demo.gif +0 -0
- framesource-0.3.0/media/geti_demo.mp4 +0 -0
- framesource-0.3.0/media/image_seq/1000_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1000_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/100_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/100_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/1010_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1020_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1030_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1040_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1050_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1060_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1070_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1080_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1090_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1100_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1100_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/110_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1110_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1120_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1130_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1140_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1150_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1160_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1170_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1180_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1190_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1200_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1200_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/120_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1210_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1220_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1230_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1240_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1250_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1260_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1270_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1280_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1290_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1300_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1300_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/130_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1310_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1320_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1330_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1340_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1350_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1360_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1370_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1380_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1390_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1400_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1400_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/140_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1410_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1420_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1430_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1440_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1450_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1460_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1470_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1480_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1490_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1500_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1500_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/150_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1510_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1520_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1530_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1540_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1600_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1600_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/160_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1700_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1700_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/170_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1800_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1800_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/180_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1900_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/1900_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/190_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2000_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2000_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/200_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/200_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/2100_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2100_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/210_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2200_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2200_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/220_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2300_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2300_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/230_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2400_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2400_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/240_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2500_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2500_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/250_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2600_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2600_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/260_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2700_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2700_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/270_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2800_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2800_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/280_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2900_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/2900_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/290_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/3000_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/3000_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/300_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/300_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/3100_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/310_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/320_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/330_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/340_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/350_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/360_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/370_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/380_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/390_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/400_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/400_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/410_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/420_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/430_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/440_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/450_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/460_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/470_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/480_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/490_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/500_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/500_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/510_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/520_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/530_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/540_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/550_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/560_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/570_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/580_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/590_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/600_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/600_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/610_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/620_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/630_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/640_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/650_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/660_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/670_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/680_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/690_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/700_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/700_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/710_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/720_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/730_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/740_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/750_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/760_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/770_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/780_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/790_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/800_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/800_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/810_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/820_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/830_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/840_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/850_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/860_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/870_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/880_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/890_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/900_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/900_71024__1.jpg +0 -0
- framesource-0.3.0/media/image_seq/90_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/910_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/920_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/930_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/940_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/950_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/960_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/970_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/980_71024.jpg +0 -0
- framesource-0.3.0/media/image_seq/990_71024.jpg +0 -0
- framesource-0.3.0/media/interactive_360_demo.gif +0 -0
- framesource-0.3.0/pyproject.toml +140 -0
- framesource-0.3.0/setup.cfg +4 -0
- framesource-0.3.0/src/frame_processors/__init__.py +37 -0
- framesource-0.3.0/src/frame_source/__init__.py +50 -0
- framesource-0.3.0/src/framesource/__init__.py +93 -0
- framesource-0.3.0/src/framesource/_msmf_config.py +26 -0
- framesource-0.3.0/src/framesource/_version.py +24 -0
- framesource-0.3.0/src/framesource/discovery.py +109 -0
- framesource-0.3.0/src/framesource/errors.py +82 -0
- framesource-0.3.0/src/framesource/factory.py +290 -0
- framesource-0.3.0/src/framesource/processors/__init__.py +34 -0
- framesource-0.3.0/src/framesource/processors/equirectangular360_processor.py +577 -0
- framesource-0.3.0/src/framesource/processors/fisheye2equirectangular_processor.py +328 -0
- framesource-0.3.0/src/framesource/processors/frame_processor.py +30 -0
- framesource-0.3.0/src/framesource/processors/hyperspectral_processor.py +23 -0
- framesource-0.3.0/src/framesource/processors/realsense_depth_processor.py +90 -0
- framesource-0.3.0/src/framesource/py.typed +0 -0
- framesource-0.3.0/src/framesource/sources/__init__.py +40 -0
- framesource-0.3.0/src/framesource/sources/audiospectrogram_capture.py +1068 -0
- framesource-0.3.0/src/framesource/sources/basler_capture.py +477 -0
- framesource-0.3.0/src/framesource/sources/folder_capture.py +920 -0
- framesource-0.3.0/src/framesource/sources/genicam_capture.py +681 -0
- framesource-0.3.0/src/framesource/sources/huateng_capture.py +245 -0
- framesource-0.3.0/src/framesource/sources/ipcamera_capture.py +254 -0
- framesource-0.3.0/src/framesource/sources/mvsdk.py +2454 -0
- framesource-0.3.0/src/framesource/sources/realsense_capture.py +565 -0
- framesource-0.3.0/src/framesource/sources/screen_capture.py +800 -0
- framesource-0.3.0/src/framesource/sources/video_capture_base.py +560 -0
- framesource-0.3.0/src/framesource/sources/video_file_capture.py +259 -0
- framesource-0.3.0/src/framesource/sources/webcam_capture.py +511 -0
- framesource-0.3.0/src/framesource/sources/ximea_capture.py +299 -0
- framesource-0.3.0/src/framesource/threading_utils.py +790 -0
- framesource-0.3.0/src/framesource.egg-info/PKG-INFO +787 -0
- framesource-0.3.0/src/framesource.egg-info/SOURCES.txt +280 -0
- framesource-0.3.0/src/framesource.egg-info/dependency_links.txt +1 -0
- framesource-0.3.0/src/framesource.egg-info/requires.txt +34 -0
- framesource-0.3.0/src/framesource.egg-info/scm_file_list.json +276 -0
- framesource-0.3.0/src/framesource.egg-info/scm_version.json +8 -0
- framesource-0.3.0/src/framesource.egg-info/top_level.txt +3 -0
- framesource-0.3.0/tests/conftest.py +82 -0
- framesource-0.3.0/tests/test_base_capabilities.py +166 -0
- framesource-0.3.0/tests/test_contract.py +87 -0
- framesource-0.3.0/tests/test_discovery.py +46 -0
- framesource-0.3.0/tests/test_discovery_info.py +97 -0
- framesource-0.3.0/tests/test_errors.py +186 -0
- framesource-0.3.0/tests/test_factory.py +62 -0
- framesource-0.3.0/tests/test_frame.py +83 -0
- framesource-0.3.0/tests/test_frame_source_shim.py +67 -0
- framesource-0.3.0/tests/test_from_config.py +124 -0
- framesource-0.3.0/tests/test_grayscale.py +38 -0
- framesource-0.3.0/tests/test_high_frequency.py +59 -0
- framesource-0.3.0/tests/test_msmf_config.py +48 -0
- framesource-0.3.0/tests/test_opencv_api_compatibility.py +102 -0
- framesource-0.3.0/tests/test_opencv_compat.py +47 -0
- framesource-0.3.0/tests/test_simple_external_threading.py +98 -0
- framesource-0.3.0/tests/test_threading_utils.py +229 -0
- framesource-0.3.0/tests/test_typed_constructors.py +498 -0
- framesource-0.3.0/tests/test_webcam_backend.py +56 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, tidy]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: test (${{ matrix.os }}, py${{ matrix.python-version }})
|
|
12
|
+
runs-on: ${{ matrix.os }}
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
os: [ubuntu-latest, windows-latest]
|
|
17
|
+
python-version: ["3.9", "3.11", "3.13"]
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 0 # setuptools_scm needs history/tags for the version
|
|
22
|
+
|
|
23
|
+
- uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ matrix.python-version }}
|
|
26
|
+
|
|
27
|
+
- name: Install system libraries for headless OpenCV
|
|
28
|
+
if: runner.os == 'Linux'
|
|
29
|
+
run: sudo apt-get update && sudo apt-get install -y libgl1 libglib2.0-0
|
|
30
|
+
|
|
31
|
+
# The audio extra is deliberately not installed: pyaudio needs portaudio
|
|
32
|
+
# system packages, and the audio tests importorskip their dependencies.
|
|
33
|
+
- name: Install package
|
|
34
|
+
run: |
|
|
35
|
+
python -m pip install --upgrade pip
|
|
36
|
+
pip install -e .
|
|
37
|
+
pip install pytest
|
|
38
|
+
|
|
39
|
+
- name: Run hardware-free test suite
|
|
40
|
+
run: pytest -m "not hardware"
|
|
41
|
+
|
|
42
|
+
lint:
|
|
43
|
+
name: lint (ruff)
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v4
|
|
47
|
+
- uses: actions/setup-python@v5
|
|
48
|
+
with:
|
|
49
|
+
python-version: "3.12"
|
|
50
|
+
- run: pip install ruff
|
|
51
|
+
- run: ruff check .
|
|
52
|
+
- run: ruff format --check .
|
|
53
|
+
|
|
54
|
+
typecheck:
|
|
55
|
+
name: mypy (non-blocking)
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
continue-on-error: true
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
- uses: actions/setup-python@v5
|
|
61
|
+
with:
|
|
62
|
+
python-version: "3.12"
|
|
63
|
+
- run: |
|
|
64
|
+
pip install mypy
|
|
65
|
+
pip install -e .
|
|
66
|
+
- run: mypy src/framesource
|
|
67
|
+
|
|
68
|
+
build:
|
|
69
|
+
name: build & twine check
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
steps:
|
|
72
|
+
- uses: actions/checkout@v4
|
|
73
|
+
with:
|
|
74
|
+
fetch-depth: 0
|
|
75
|
+
- uses: actions/setup-python@v5
|
|
76
|
+
with:
|
|
77
|
+
python-version: "3.12"
|
|
78
|
+
- run: pip install build twine
|
|
79
|
+
- run: python -m build
|
|
80
|
+
- run: twine check dist/*
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
# Manual runs must be dispatched from a tag ref (e.g. v0.3.0), otherwise
|
|
8
|
+
# setuptools_scm produces a dev version that PyPI rejects.
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0 # setuptools_scm derives the version from the tag
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
- run: pip install build twine
|
|
22
|
+
- run: python -m build
|
|
23
|
+
- run: twine check dist/*
|
|
24
|
+
- uses: actions/upload-artifact@v4
|
|
25
|
+
with:
|
|
26
|
+
name: dist
|
|
27
|
+
path: dist/
|
|
28
|
+
|
|
29
|
+
publish:
|
|
30
|
+
needs: build
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
environment:
|
|
33
|
+
name: pypi
|
|
34
|
+
url: https://pypi.org/p/framesource
|
|
35
|
+
# Trusted publishing: on pypi.org, add this repo as a trusted publisher
|
|
36
|
+
# for the "framesource" project with workflow name "publish.yaml" and
|
|
37
|
+
# environment "pypi" (one-time, manual). No API token is stored in the repo.
|
|
38
|
+
permissions:
|
|
39
|
+
id-token: write
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/download-artifact@v4
|
|
42
|
+
with:
|
|
43
|
+
name: dist
|
|
44
|
+
path: dist/
|
|
45
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
with:
|
|
14
|
+
fetch-depth: 0 # setuptools_scm derives the version from the tag
|
|
15
|
+
- uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
- run: pip install build twine
|
|
19
|
+
- run: python -m build
|
|
20
|
+
- run: twine check dist/*
|
|
21
|
+
- uses: actions/upload-artifact@v4
|
|
22
|
+
with:
|
|
23
|
+
name: dist
|
|
24
|
+
path: dist/
|
|
25
|
+
|
|
26
|
+
# PyPI publishing lives in publish.yaml (same v* tag trigger).
|
|
27
|
+
|
|
28
|
+
github-release:
|
|
29
|
+
needs: build
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
permissions:
|
|
32
|
+
contents: write
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/download-artifact@v4
|
|
35
|
+
with:
|
|
36
|
+
name: dist
|
|
37
|
+
path: dist/
|
|
38
|
+
- uses: softprops/action-gh-release@v2
|
|
39
|
+
with:
|
|
40
|
+
files: dist/*
|
|
41
|
+
generate_release_notes: true
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# setuptools_scm generated version file
|
|
7
|
+
src/framesource/_version.py
|
|
8
|
+
|
|
9
|
+
# C extensions
|
|
10
|
+
*.so
|
|
11
|
+
|
|
12
|
+
# Distribution / packaging
|
|
13
|
+
.Python
|
|
14
|
+
env/
|
|
15
|
+
build/
|
|
16
|
+
develop-eggs/
|
|
17
|
+
dist/
|
|
18
|
+
downloads/
|
|
19
|
+
eggs/
|
|
20
|
+
.eggs/
|
|
21
|
+
lib/
|
|
22
|
+
lib64/
|
|
23
|
+
parts/
|
|
24
|
+
sdist/
|
|
25
|
+
var/
|
|
26
|
+
*.egg-info/
|
|
27
|
+
.installed.cfg
|
|
28
|
+
*.egg
|
|
29
|
+
MANIFEST
|
|
30
|
+
|
|
31
|
+
# Virtual environments
|
|
32
|
+
venv/
|
|
33
|
+
ENV/
|
|
34
|
+
env.bak/
|
|
35
|
+
venv.bak/
|
|
36
|
+
.venv/
|
|
37
|
+
.github/prompts/
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# PyInstaller
|
|
41
|
+
# Usually these files are written by a python script from a template
|
|
42
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
43
|
+
build/
|
|
44
|
+
dist/
|
|
45
|
+
*.spec
|
|
46
|
+
|
|
47
|
+
# Installer logs
|
|
48
|
+
debug.log
|
|
49
|
+
|
|
50
|
+
# Unit test / coverage reports
|
|
51
|
+
htmlcov/
|
|
52
|
+
.tox/
|
|
53
|
+
.nox/
|
|
54
|
+
.coverage
|
|
55
|
+
.coverage.*
|
|
56
|
+
.cache
|
|
57
|
+
nosetests.xml
|
|
58
|
+
coverage.xml
|
|
59
|
+
*.cover
|
|
60
|
+
.hypothesis/
|
|
61
|
+
.pytest_cache/
|
|
62
|
+
|
|
63
|
+
# Jupyter Notebook
|
|
64
|
+
.ipynb_checkpoints
|
|
65
|
+
|
|
66
|
+
# pyenv
|
|
67
|
+
.python-version
|
|
68
|
+
|
|
69
|
+
# pipenv
|
|
70
|
+
Pipfile.lock
|
|
71
|
+
|
|
72
|
+
# mypy
|
|
73
|
+
.mypy_cache/
|
|
74
|
+
.dmypy.json
|
|
75
|
+
|
|
76
|
+
# Pyre type checker
|
|
77
|
+
.pyre/
|
|
78
|
+
|
|
79
|
+
# VS Code
|
|
80
|
+
.vscode/
|
|
81
|
+
|
|
82
|
+
# Windows
|
|
83
|
+
Thumbs.db
|
|
84
|
+
Desktop.ini
|
|
85
|
+
$RECYCLE.BIN/
|
|
86
|
+
|
|
87
|
+
# macOS
|
|
88
|
+
.DS_Store
|
|
89
|
+
.AppleDouble
|
|
90
|
+
.LSOverride
|
|
91
|
+
|
|
92
|
+
# Linux
|
|
93
|
+
*~
|
|
94
|
+
|
|
95
|
+
# Logs
|
|
96
|
+
*.log
|
|
97
|
+
|
|
98
|
+
# Other
|
|
99
|
+
*.swp
|
|
100
|
+
*.swo
|
|
101
|
+
|
|
102
|
+
# Project-specific
|
|
103
|
+
src/*/__pycache__/
|
|
104
|
+
src/__pycache__/folder_capture.cpython-311.pyc
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `WebcamCapture` gains `backend` and `fourcc` constructor keyword arguments.
|
|
13
|
+
`backend` selects the OpenCV capture backend by name (`'msmf'`, `'dshow'`,
|
|
14
|
+
`'v4l2'`, `'avfoundation'`, `'gstreamer'`, `'ffmpeg'`, `'any'`) or a raw
|
|
15
|
+
`cv2.CAP_*` int; `fourcc` (e.g. `'MJPG'`) requests a pixel format, applied
|
|
16
|
+
before the resolution so drivers don't reset it. Fixes uncompressed formats
|
|
17
|
+
(e.g. YUY2) saturating the USB link and throttling high-resolution capture
|
|
18
|
+
to single-digit frame rates. `connect()` now logs a warning when it detects
|
|
19
|
+
an uncompressed format negotiated at 720p or above, and `get_fourcc()`
|
|
20
|
+
reports the negotiated format.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Importing `framesource` now disables OpenCV MSMF hardware transforms on
|
|
25
|
+
Windows (`OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS=0`, via `setdefault` so
|
|
26
|
+
an explicit user value wins). This cuts webcam open time on affected devices
|
|
27
|
+
from 20+ seconds to a fraction of a second with no throughput cost. Only
|
|
28
|
+
effective when `framesource` is imported before `cv2` opens an MSMF device.
|
|
29
|
+
|
|
30
|
+
## [0.3.0] - 2026-07-12
|
|
31
|
+
|
|
32
|
+
The "synchronous core" release. The package was renamed, the internal
|
|
33
|
+
threading model was removed in favour of explicit, opt-in concurrency
|
|
34
|
+
helpers, and frames now carry metadata. Existing code keeps working: the
|
|
35
|
+
old import name, factory parameter names, and the OpenCV-compatible
|
|
36
|
+
`isOpened()` / `read()` / `release()` surface are all preserved.
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- `Frame` — an `np.ndarray` subclass returned by `read()`, carrying
|
|
41
|
+
`timestamp` (wall clock), `monotonic` (for latency/FPS math), `count`,
|
|
42
|
+
`uuid`, `source`, and a free-form `metadata` dict. Works in any
|
|
43
|
+
OpenCV/numpy call and survives pickling.
|
|
44
|
+
- `FrameSourceProtocol` — runtime-checkable protocol defining the minimal
|
|
45
|
+
source contract (`connect`/`disconnect`/`read`/`is_open`), so custom
|
|
46
|
+
sources can be duck-typed without inheriting `VideoCaptureBase`.
|
|
47
|
+
- `framesource.errors` — `FrameSourceError` base plus
|
|
48
|
+
`MissingDependencyError` (an `ImportError` carrying the pip-extra install
|
|
49
|
+
hint), `UnknownSourceTypeError` (a `ValueError`, raised by the factory),
|
|
50
|
+
and `NotConnectedError`. Existing `except ImportError/ValueError` clauses
|
|
51
|
+
keep working.
|
|
52
|
+
- `DeviceInfo` — typed, dict-compatible device descriptor returned by
|
|
53
|
+
`discover()` implementations.
|
|
54
|
+
- Typed constructors with explicit keyword parameters for the consumer
|
|
55
|
+
sources (`WebcamCapture`, `VideoFileCapture`, `FolderCapture`,
|
|
56
|
+
`IPCameraCapture`, `ScreenCapture`, `AudioSpectrogramCapture`) and the
|
|
57
|
+
vendor sources (`BaslerCapture`, `GenicamCapture`, `RealsenseCapture`,
|
|
58
|
+
`XimeaCapture`, `HuatengCapture`).
|
|
59
|
+
- Capability flags on every source (`supports_exposure`, `supports_gain`,
|
|
60
|
+
`supports_depth`) replacing `hasattr()` probing.
|
|
61
|
+
- Iterator protocol — `for frame in cap:` yields frames until the source is
|
|
62
|
+
exhausted.
|
|
63
|
+
- `wait_until_ready(timeout)` — poll until a source actually produces
|
|
64
|
+
frames (RTSP "connected but not yet streaming").
|
|
65
|
+
- `fps_actual()` — rolling-window measured FPS on the monotonic clock.
|
|
66
|
+
- `framesource.threading_utils` additions: `AsyncFrameSource` (asyncio
|
|
67
|
+
adapter), `SharedProducer` (one producer, N subscriber queues),
|
|
68
|
+
`ProducerConsumer` (joinable producer/consumer pair handle), and
|
|
69
|
+
`FrameProducer.get_stats()` now reports `avg_latency` and warns on high
|
|
70
|
+
drop rates.
|
|
71
|
+
- `FrameSourceFactory.from_config()` — create a source from a dict or a
|
|
72
|
+
`.json`/`.yaml` config file (YAML requires PyYAML to be installed).
|
|
73
|
+
- Optional-dependency extras: `audio`, `basler`, `realsense`, `genicam`,
|
|
74
|
+
`full`. `py.typed` marker shipped.
|
|
75
|
+
- Real-world examples: inference pipeline with back-pressure, record →
|
|
76
|
+
replay, and source swapping; CI (GitHub Actions) across
|
|
77
|
+
Ubuntu/Windows × Python 3.9/3.11/3.13; release automation via PyPI
|
|
78
|
+
trusted publishing.
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
|
|
82
|
+
- **Package renamed** to `framesource` (import and PyPI name now match),
|
|
83
|
+
with a `src/` layout and `sources`/`processors` subpackages.
|
|
84
|
+
- **Synchronous core**: capture classes no longer spawn internal threads.
|
|
85
|
+
Concurrency is explicit via `framesource.threading_utils`
|
|
86
|
+
(`simple_frame_producer`, `FrameProducer`, multiprocessing helper).
|
|
87
|
+
The sole exception is `AudioSpectrogramCapture`'s audio ring-buffer
|
|
88
|
+
thread, which is inherent to its I/O model.
|
|
89
|
+
- Factory parameters renamed for clarity: `capture_type` → `source_type`,
|
|
90
|
+
`source` → `source_id` (old names still work, see Deprecated).
|
|
91
|
+
- Library no longer calls `logging.basicConfig()` or prints to stdout; all
|
|
92
|
+
diagnostics go through per-module loggers.
|
|
93
|
+
- Python floor raised to 3.9 (3.8 is end-of-life).
|
|
94
|
+
- Versioning is tag-driven via `setuptools_scm`.
|
|
95
|
+
- Lint/format tooling consolidated on ruff (replacing black + isort).
|
|
96
|
+
|
|
97
|
+
### Deprecated
|
|
98
|
+
|
|
99
|
+
- `import frame_source` — use `import framesource`. The shim (including
|
|
100
|
+
deep imports like `frame_source.webcam_capture`) warns and will be
|
|
101
|
+
removed in a future major release.
|
|
102
|
+
- Factory params `capture_type=` / `source=` — use `source_type` /
|
|
103
|
+
`source_id`. Warn via `DeprecationWarning`; no removal scheduled within
|
|
104
|
+
0.x.
|
|
105
|
+
- `get_config_schema()` on all sources — UI form schemas belong in the
|
|
106
|
+
consuming application; typed constructors expose the same information.
|
|
107
|
+
Scheduled for removal in 0.4.0.
|
|
108
|
+
|
|
109
|
+
### Removed
|
|
110
|
+
|
|
111
|
+
- Web-UI residue: `get_available_sources()` and the `display_fields` class
|
|
112
|
+
attributes.
|
|
113
|
+
- Internal threading API: `start_async()`, `stop()`, `get_latest_frame()`,
|
|
114
|
+
`_background_capture` (deprecated behaviourally by the synchronous core;
|
|
115
|
+
the old methods no longer exist).
|
|
116
|
+
|
|
117
|
+
### Fixed
|
|
118
|
+
|
|
119
|
+
- `AudioSpectrogramCapture` accepts `freq_range` as a tuple/list as
|
|
120
|
+
documented, not only as a `"min,max"` string.
|
|
121
|
+
- `FrameSourceFactory.create(connect=False)` no longer leaks the `connect`
|
|
122
|
+
kwarg into the capture's config.
|
|
123
|
+
- `multiprocess_frame_producer` no longer raises `UnboundLocalError` when
|
|
124
|
+
source creation fails; queue-full handling is explicit.
|
|
125
|
+
- `readme.md` renamed to `README.md`, fixing sdist builds on
|
|
126
|
+
case-sensitive filesystems.
|
|
127
|
+
|
|
128
|
+
[Unreleased]: https://github.com/olkham/FrameSource/compare/v0.3.0...HEAD
|
|
129
|
+
[0.3.0]: https://github.com/olkham/FrameSource/releases/tag/v0.3.0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Oliver Hamilton
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|