Sometimes the number of recorded frames in the metadata is different to the number of frames that are actually recorded.
The following the config file
{
"application_config": {
"gui_config": {
"camera_update_rate": 20,
"camera_updates_per_display_update": 4,
"font_size": 12
},
"ffmpeg_config": {
"crf": 23,
"encoding_speed": "slow",
"compression_standard": "h265"
},
"paths_config": {
"ROOT": "C:\\Users\\alifa\\Documents\\pyMV-Local\\code",
"camera_dir": "C:\\Users\\alifa\\Documents\\pyMV-Local\\code\\config",
"encoder_dir": "C:\\Users\\alifa\\Documents\\pyMV-Local\\code\\config",
"data_dir": "C:\\Users\\alifa\\Documents\\pyMV-Local\\code\\data",
"config_dir": "C:\\Users\\alifa\\Documents\\pyMV-Local\\code\\config",
"icons_dir": "C:\\Users\\alifa\\Documents\\pyMV-Local\\code\\GUI\\icons"
},
"default_camera_config": {
"name": null,
"fps": 60,
"downsampling_factor": 1,
"exposure_time": 15000,
"gain": 0,
"external_trigger": false,
"pixel_format": "Mono"
}
},
"experiment_config": {
"data_dir": "data\\test-photo-1\\config_ncams_7_downsample_1_fps_60_update_20_upd_per_disp_4_crf_23_speed_slow_comp_h265",
"n_cameras": 7,
"n_columns": 1,
"cameras": [
{
"label": "18360349-spinnaker",
"subject_id": "recording-1"
},
{
"label": "16369381-spinnaker",
"subject_id": "recording-2"
},
{
"label": "16369379-spinnaker",
"subject_id": "recording-3"
},
{
"label": "21013409-spinnaker",
"subject_id": "recording-4"
},
{
"label": "18360348-spinnaker",
"subject_id": "recording-5"
},
{
"label": "21013402-spinnaker",
"subject_id": "recording-6"
},
{
"label": "21013401-spinnaker",
"subject_id": "recording-7"
}
]
},
"camera_config": [
{
"name": null,
"unique_id": "18360349-spinnaker",
"fps": 60,
"exposure_time": 15666,
"gain": 0,
"pixel_format": "Mono",
"downsampling_factor": 1
},
{
"name": null,
"unique_id": "16369381-spinnaker",
"fps": 60,
"exposure_time": 15666,
"gain": 0,
"pixel_format": "Mono",
"downsampling_factor": 1
},
{
"name": null,
"unique_id": "16369379-spinnaker",
"fps": 60,
"exposure_time": 15666,
"gain": 0,
"pixel_format": "Mono",
"downsampling_factor": 1
},
{
"name": null,
"unique_id": "21013409-spinnaker",
"fps": 60,
"exposure_time": 15666,
"gain": 0,
"pixel_format": "Mono",
"downsampling_factor": 1
},
{
"name": null,
"unique_id": "18360348-spinnaker",
"fps": 60,
"exposure_time": 15666,
"gain": 0,
"pixel_format": "Mono",
"downsampling_factor": 1
},
{
"name": null,
"unique_id": "21013402-spinnaker",
"fps": 60,
"exposure_time": 15666,
"gain": 0,
"pixel_format": "Mono",
"downsampling_factor": 1
},
{
"name": null,
"unique_id": "21013401-spinnaker",
"fps": 60,
"exposure_time": 15666,
"gain": 0,
"pixel_format": "Mono",
"downsampling_factor": 1
}
],
"record-on-startup": true,
"close_after": "00:30"
}
Used with the frame_counting_checking.py can produce the output:
Frame count mismatch. Recorded: 880, Actual: 884
Frame count mismatch. Recorded: 965, Actual: 969
Frame count matches recorded frame count.
Frame count matches recorded frame count.
Frame count matches recorded frame count.
Frame count matches recorded frame count.
Frame count matches recorded frame count.
from pathlib import Path
import json, sys, subprocess
from metadata_validation_script import get_video_frame_count
# config_path = r"C:\Users\alifa\Documents\pyMV-Local\code\data\test-photo-1\config_ncams_6_downsample_1_fps_120_update_20_upd_per_disp_2_crf_23_speed_slow_comp_h265\test_config.json"
config_path = r"C:\Users\alifa\Documents\pyMV-Local\code\data\test-photo-1\config_ncams_7_downsample_1_fps_60_update_20_upd_per_disp_4_crf_23_speed_slow_comp_h265\test_config.json"
# Load the JSON config file
with open(config_path, "r") as f:
config_data = json.load(f)
# Construct the command as a list of arguments
command = [
sys.executable, # Python executable
Path(".") / "pyMultiVideo_GUI.pyw", # Path to GUI
# Test options specified
"--experiment-config",
json.dumps(json.dumps(config_data["experiment_config"])), # Config file passed as JSON formatted string
"--camera-config",
json.dumps(json.dumps(config_data["camera_config"])), # Config file passed as JSON formatted string
"--application-config",
json.dumps(json.dumps(config_data["application_config"])), # Config file passed as JSON formatted string
"--record-on-startup",
config_data["record-on-startup"], # Application records on startup
"--close-after",
config_data["close_after"], # Time after which the application closes
]
# Join the list into a single string with spaces between each element
command = " ".join(map(str, command))
print(command)
# Start the process
process = subprocess.Popen(
command, stdin=subprocess.PIPE, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
) # Ensure it runs in a new process group
process.wait()
# Get all mp4 files in the folder containing the config file
mp4_files = list(Path(config_path).parent.glob("*.mp4"))
for mp4 in mp4_files:
metadata_file = mp4.parent / (mp4.stem + "_metadata.json")
with open(metadata_file, "r") as f:
metadata = json.load(f)
frame_count = get_video_frame_count(mp4)
if metadata_file.exists():
recorded_frames = metadata["recorded_frames"]
if frame_count == recorded_frames:
print("Frame count matches recorded frame count.")
else:
print(f"Frame count mismatch. Recorded: {recorded_frames}, Actual: {frame_count}")
Sometimes the number of recorded frames in the metadata is different to the number of frames that are actually recorded.
The following the config file
{ "application_config": { "gui_config": { "camera_update_rate": 20, "camera_updates_per_display_update": 4, "font_size": 12 }, "ffmpeg_config": { "crf": 23, "encoding_speed": "slow", "compression_standard": "h265" }, "paths_config": { "ROOT": "C:\\Users\\alifa\\Documents\\pyMV-Local\\code", "camera_dir": "C:\\Users\\alifa\\Documents\\pyMV-Local\\code\\config", "encoder_dir": "C:\\Users\\alifa\\Documents\\pyMV-Local\\code\\config", "data_dir": "C:\\Users\\alifa\\Documents\\pyMV-Local\\code\\data", "config_dir": "C:\\Users\\alifa\\Documents\\pyMV-Local\\code\\config", "icons_dir": "C:\\Users\\alifa\\Documents\\pyMV-Local\\code\\GUI\\icons" }, "default_camera_config": { "name": null, "fps": 60, "downsampling_factor": 1, "exposure_time": 15000, "gain": 0, "external_trigger": false, "pixel_format": "Mono" } }, "experiment_config": { "data_dir": "data\\test-photo-1\\config_ncams_7_downsample_1_fps_60_update_20_upd_per_disp_4_crf_23_speed_slow_comp_h265", "n_cameras": 7, "n_columns": 1, "cameras": [ { "label": "18360349-spinnaker", "subject_id": "recording-1" }, { "label": "16369381-spinnaker", "subject_id": "recording-2" }, { "label": "16369379-spinnaker", "subject_id": "recording-3" }, { "label": "21013409-spinnaker", "subject_id": "recording-4" }, { "label": "18360348-spinnaker", "subject_id": "recording-5" }, { "label": "21013402-spinnaker", "subject_id": "recording-6" }, { "label": "21013401-spinnaker", "subject_id": "recording-7" } ] }, "camera_config": [ { "name": null, "unique_id": "18360349-spinnaker", "fps": 60, "exposure_time": 15666, "gain": 0, "pixel_format": "Mono", "downsampling_factor": 1 }, { "name": null, "unique_id": "16369381-spinnaker", "fps": 60, "exposure_time": 15666, "gain": 0, "pixel_format": "Mono", "downsampling_factor": 1 }, { "name": null, "unique_id": "16369379-spinnaker", "fps": 60, "exposure_time": 15666, "gain": 0, "pixel_format": "Mono", "downsampling_factor": 1 }, { "name": null, "unique_id": "21013409-spinnaker", "fps": 60, "exposure_time": 15666, "gain": 0, "pixel_format": "Mono", "downsampling_factor": 1 }, { "name": null, "unique_id": "18360348-spinnaker", "fps": 60, "exposure_time": 15666, "gain": 0, "pixel_format": "Mono", "downsampling_factor": 1 }, { "name": null, "unique_id": "21013402-spinnaker", "fps": 60, "exposure_time": 15666, "gain": 0, "pixel_format": "Mono", "downsampling_factor": 1 }, { "name": null, "unique_id": "21013401-spinnaker", "fps": 60, "exposure_time": 15666, "gain": 0, "pixel_format": "Mono", "downsampling_factor": 1 } ], "record-on-startup": true, "close_after": "00:30" }Used with the
frame_counting_checking.pycan produce the output: