Compare commits

...

2 Commits

Author SHA1 Message Date
Josh Hawkins
1188d87588
Save detect dimensions to config on add camera wizard save (#22349)
Some checks are pending
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions
* add util for optimal detect resolution

* add detect to type

* save optimal detect resolution to config on wizard save

* use const
2026-03-09 15:50:46 -06:00
Josh Hawkins
c4a5ac0e77
fix go2rtc homekit handling (#22346)
file needs to be blank if not using homekit, not {}
it seems like go2rtc is not parsing {} as yaml
2026-03-09 10:33:14 -05:00
4 changed files with 89 additions and 16 deletions

View File

@ -55,7 +55,7 @@ function setup_homekit_config() {
if [[ ! -f "${config_path}" ]]; then if [[ ! -f "${config_path}" ]]; then
echo "[INFO] Creating empty config file for HomeKit..." echo "[INFO] Creating empty config file for HomeKit..."
echo '{}' > "${config_path}" : > "${config_path}"
fi fi
# Convert YAML to JSON for jq processing # Convert YAML to JSON for jq processing
@ -65,23 +65,25 @@ function setup_homekit_config() {
return 0 return 0
} }
# Use jq to filter and keep only the homekit section # Use jq to extract the homekit section, if it exists
local cleaned_json="/tmp/cache/homekit_cleaned.json" local homekit_json
jq ' homekit_json=$(jq '
# Keep only the homekit section if it exists, otherwise empty object if has("homekit") then {homekit: .homekit} else null end
if has("homekit") then {homekit: .homekit} else {} end ' "${temp_json}" 2>/dev/null) || homekit_json="null"
' "${temp_json}" > "${cleaned_json}" 2>/dev/null || {
echo '{}' > "${cleaned_json}"
}
# Convert back to YAML and write to the config file # If no homekit section, write an empty config file
yq eval -P "${cleaned_json}" > "${config_path}" 2>/dev/null || { if [[ "${homekit_json}" == "null" ]]; then
echo "[WARNING] Failed to convert cleaned config to YAML, creating minimal config" : > "${config_path}"
echo '{}' > "${config_path}" else
} # Convert homekit JSON back to YAML and write to the config file
echo "${homekit_json}" | yq eval -P - > "${config_path}" 2>/dev/null || {
echo "[WARNING] Failed to convert cleaned config to YAML, creating minimal config"
: > "${config_path}"
}
fi
# Clean up temp files # Clean up temp files
rm -f "${temp_json}" "${cleaned_json}" rm -f "${temp_json}"
} }
set_libva_version set_libva_version

View File

@ -20,7 +20,10 @@ import type {
CameraConfigData, CameraConfigData,
ConfigSetBody, ConfigSetBody,
} from "@/types/cameraWizard"; } from "@/types/cameraWizard";
import { processCameraName } from "@/utils/cameraUtil"; import {
processCameraName,
calculateDetectDimensions,
} from "@/utils/cameraUtil";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
type WizardState = { type WizardState = {
@ -203,6 +206,25 @@ export default function CameraWizardDialog({
}, },
}; };
// Calculate detect dimensions from the detect stream's probed resolution
const detectStream = wizardData.streams.find((stream) =>
stream.roles.includes("detect"),
);
if (detectStream?.testResult?.resolution) {
const [streamWidth, streamHeight] = detectStream.testResult.resolution
.split("x")
.map(Number);
if (streamWidth > 0 && streamHeight > 0) {
const detectDimensions = calculateDetectDimensions(
streamWidth,
streamHeight,
);
if (detectDimensions) {
configData.cameras[finalCameraName].detect = detectDimensions;
}
}
}
// Add live.streams configuration for go2rtc streams // Add live.streams configuration for go2rtc streams
if (wizardData.streams && wizardData.streams.length > 0) { if (wizardData.streams && wizardData.streams.length > 0) {
configData.cameras[finalCameraName].live = { configData.cameras[finalCameraName].live = {

View File

@ -162,6 +162,10 @@ export type CameraConfigData = {
input_args?: string; input_args?: string;
}[]; }[];
}; };
detect?: {
width: number;
height: number;
};
live?: { live?: {
streams: Record<string, string>; streams: Record<string, string>;
}; };

View File

@ -115,6 +115,51 @@ export type CameraAudioFeatures = {
* @param requireSecureContext - If true, two-way audio requires secure context (default: true) * @param requireSecureContext - If true, two-way audio requires secure context (default: true)
* @returns CameraAudioFeatures object with detected capabilities * @returns CameraAudioFeatures object with detected capabilities
*/ */
/**
* Calculates optimal detect dimensions from stream resolution.
*
* Scales dimensions to an efficient size for object detection while
* preserving the stream's aspect ratio. Does not upscale.
*
* @param streamWidth - Native stream width in pixels
* @param streamHeight - Native stream height in pixels
* @returns Detect dimensions with even values, or null if inputs are invalid
*/
// Target size for the smaller dimension (width or height) for detect streams
export const DETECT_TARGET_PX = 720;
export function calculateDetectDimensions(
streamWidth: number,
streamHeight: number,
): { width: number; height: number } | null {
if (
!Number.isFinite(streamWidth) ||
!Number.isFinite(streamHeight) ||
streamWidth <= 0 ||
streamHeight <= 0
) {
return null;
}
const smallerDim = Math.min(streamWidth, streamHeight);
const target = Math.min(DETECT_TARGET_PX, smallerDim);
const scale = target / smallerDim;
let width = Math.round(streamWidth * scale);
let height = Math.round(streamHeight * scale);
// Round down to even numbers (required for video processing)
width = width - (width % 2);
height = height - (height % 2);
if (width < 2 || height < 2) {
return null;
}
return { width, height };
}
export function detectCameraAudioFeatures( export function detectCameraAudioFeatures(
metadata: LiveStreamMetadata | null | undefined, metadata: LiveStreamMetadata | null | undefined,
requireSecureContext: boolean = true, requireSecureContext: boolean = true,