diff --git a/frigate/http.py b/frigate/http.py index b9708c8ff..04d6df00e 100644 --- a/frigate/http.py +++ b/frigate/http.py @@ -627,21 +627,21 @@ def ffprobe(camera_name): { "input_roles": input.roles, "return_code": ffprobe.returncode, - "stderr": ffprobe.stderr, - "stdout": ffprobe.stdout, + "stderr": ffprobe.stderr.decode().strip(), + "stdout": ffprobe.stdout.decode().strip(), } ) return jsonify(output) else: # user has single stream - ffprobe = ffprobe_stream(config.ffmpeg.inputs[0].path) + ffprobe: sp.CompletedProcess = ffprobe_stream(config.ffmpeg.inputs[0].path) return jsonify( { "input_roles": config.ffmpeg.inputs[0].roles, "return_code": ffprobe.returncode, - "stderr": ffprobe.stderr, - "stdout": ffprobe.stdout, + "stderr": ffprobe.stderr.decode().strip(), + "stdout": ffprobe.stdout.decode().strip(), } ) diff --git a/frigate/util.py b/frigate/util.py index 1d572161d..05e5fec29 100755 --- a/frigate/util.py +++ b/frigate/util.py @@ -716,6 +716,8 @@ def ffprobe_stream(path: str) -> sp.CompletedProcess: """Run ffprobe on stream.""" ffprobe_cmd = [ "ffprobe", + "-print_format", + "json", "-show_entries", "stream=codec_long_name,width,height,bit_rate,duration,display_aspect_ratio,avg_frame_rate", "-loglevel", diff --git a/web/src/routes/Debug.jsx b/web/src/routes/Debug.jsx index c3c73ceb2..29d70d065 100644 --- a/web/src/routes/Debug.jsx +++ b/web/src/routes/Debug.jsx @@ -7,11 +7,13 @@ import { useMqtt } from '../api/mqtt'; import useSWR from 'swr'; import axios from 'axios'; import { Table, Tbody, Thead, Tr, Th, Td } from '../components/Table'; -import { useCallback } from 'preact/hooks'; +import { useCallback, useState } from 'preact/hooks'; +import Dialog from '../components/Dialog'; const emptyObject = Object.freeze({}); export default function Debug() { + const [state, setState] = useState({ showFfprobe: false, ffprobe: '' }); const { data: config } = useSWR('config'); const { @@ -22,7 +24,6 @@ export default function Debug() { const { cpu_usages, detectors, service = {}, detection_fps: _, ...cameras } = stats || initialStats || emptyObject; const detectorNames = Object.keys(detectors || emptyObject); - const detectorDataKeys = Object.keys(detectors ? detectors[detectorNames[0]] : emptyObject); const cameraNames = Object.keys(cameras || emptyObject); const handleCopyConfig = useCallback(() => { @@ -32,23 +33,51 @@ export default function Debug() { copy(); }, [config]); - const onCopyFfprobe = async (camera, e) => { + const onHandleFfprobe = async (camera, e) => { if (e) { e.stopPropagation(); } + setState({ ...state, showFfprobe: true }); const response = await axios.get(`${camera}/ffprobe`); if (response.status === 200) { - await window.navigator.clipboard.writeText(JSON.stringify(response.data, null, 2)); + setState({ showFfprobe: true, ffprobe: JSON.stringify(response.data, null, 2) }); + } else { + setState({ ...state, ffprobe: 'There was an error getting the ffprobe output.' }); } }; + const onCopyFfprobe = async () => { + await window.navigator.clipboard.writeText(JSON.stringify(state.ffprobe, null, 2)); + setState({ ...state, ffprobe: '', showFfprobe: false }); + }; + return (
Debug {service.version} + {state.showFfprobe && ( + +
+ Ffprobe Output + {state.ffprobe != '' ?

{state.ffprobe}

: } +
+
+ + +
+
+ )} {!detectors ? (
@@ -56,7 +85,7 @@ export default function Debug() {
) : ( - Detectors + Detectors
{detectorNames.map((detector) => (
@@ -65,16 +94,16 @@ export default function Debug() { - {detectorDataKeys.map((name) => ( - - ))} + + + - {detectorDataKeys.map((name) => ( - - ))} + + +
{name.replace('_', ' ')}P-IDDetection StartInference Speed
{detectors[detector][name]}{detectors[detector]['pid']}{detectors[detector]['detection_start']}{detectors[detector]['inference_speed']}
@@ -83,20 +112,20 @@ export default function Debug() { ))}
- Cameras + Cameras
{cameraNames.map((camera) => (
{camera.replaceAll('_', ' ')} - +
- +
ProcessProcess IDP-ID fps Cpu % Memory %