Files
mitus/docs/graphs/python_pipeline.svg
2026-05-06 11:51:43 -03:00

309 lines
24 KiB
XML

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 14.1.2 (0)
-->
<!-- Title: python_pipeline Pages: 1 -->
<svg width="1067pt" height="1624pt"
viewBox="0.00 0.00 1067.00 1624.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(43.2 1580.56)">
<title>python_pipeline</title>
<polygon fill="#1e1e2e" stroke="none" points="-43.2,43.2 -43.2,-1580.56 1024.25,-1580.56 1024.25,43.2 -43.2,43.2"/>
<g id="clust1" class="cluster">
<title>cluster_sender</title>
<polygon fill="#1e1e2e" stroke="#45475a" points="159.75,-1176.05 159.75,-1529.36 533.75,-1529.36 533.75,-1176.05 159.75,-1176.05"/>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1512.06" font-family="monospace" font-size="14.00" fill="#a6adc8">Sender — sender/stream_av.sh</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_recorder</title>
<polygon fill="#1e1e2e" stroke="#45475a" points="174.75,-664.16 174.75,-1000.24 512.75,-1000.24 512.75,-664.16 174.75,-664.16"/>
<text xml:space="preserve" text-anchor="middle" x="343.75" y="-982.94" font-family="monospace" font-size="14.00" fill="#a6adc8">StreamRecorder — cht/stream/recorder.py</text>
</g>
<g id="clust3" class="cluster">
<title>cluster_processor</title>
<polygon fill="#1e1e2e" stroke="#45475a" points="135.75,-484.12 135.75,-628.9 873.75,-628.9 873.75,-484.12 135.75,-484.12"/>
<text xml:space="preserve" text-anchor="middle" x="504.75" y="-611.6" font-family="monospace" font-size="14.00" fill="#a6adc8">SessionProcessor — cht/stream/processor.py</text>
</g>
<!-- drm -->
<g id="node1" class="node">
<title>drm</title>
<path fill="#1e3a2f" stroke="#a6e3a1" d="M151.5,-1464.85C151.5,-1468.42 117.55,-1471.32 75.75,-1471.32 33.95,-1471.32 0,-1468.42 0,-1464.85 0,-1464.85 0,-1406.59 0,-1406.59 0,-1403.02 33.95,-1400.12 75.75,-1400.12 117.55,-1400.12 151.5,-1403.02 151.5,-1406.59 151.5,-1406.59 151.5,-1464.85 151.5,-1464.85"/>
<path fill="none" stroke="#a6e3a1" d="M151.5,-1464.85C151.5,-1461.27 117.55,-1458.37 75.75,-1458.37 33.95,-1458.37 0,-1461.27 0,-1464.85"/>
<text xml:space="preserve" text-anchor="middle" x="75.75" y="-1439.67" font-family="monospace" font-size="14.00" fill="#cdd6f4">/dev/dri/card0</text>
<text xml:space="preserve" text-anchor="middle" x="75.75" y="-1422.42" font-family="monospace" font-size="14.00" fill="#cdd6f4">(KMS scanout)</text>
</g>
<!-- ffmpeg_send -->
<g id="node5" class="node">
<title>ffmpeg_send</title>
<polygon fill="#1e2d3e" stroke="#89b4fa" points="525.62,-1322.08 167.88,-1322.08 167.88,-1184.05 525.62,-1184.05 525.62,-1322.08"/>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1300.14" font-family="monospace" font-size="14.00" fill="#cdd6f4">ffmpeg CLI</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1282.89" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1265.64" font-family="monospace" font-size="14.00" fill="#cdd6f4">kmsgrab → hwmap=vaapi</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1248.39" font-family="monospace" font-size="14.00" fill="#cdd6f4">scale_vaapi 1920x1080 nv12</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1231.14" font-family="monospace" font-size="14.00" fill="#cdd6f4">h264_vaapi (qp=20, gop=30, no B&#45;frames)</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1213.89" font-family="monospace" font-size="14.00" fill="#cdd6f4">amix(monitor, mic) → aac 128k</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1196.64" font-family="monospace" font-size="14.00" fill="#cdd6f4">mpegts → TCP</text>
</g>
<!-- drm&#45;&gt;ffmpeg_send -->
<g id="edge1" class="edge">
<title>drm&#45;&gt;ffmpeg_send</title>
<path fill="none" stroke="#585b70" d="M122.29,-1400.17C139.89,-1387.11 155.75,-1375.33 155.75,-1375.33 155.75,-1375.33 189.94,-1353.62 229.39,-1328.57"/>
<polygon fill="#585b70" stroke="#585b70" points="231.13,-1331.62 237.69,-1323.31 227.37,-1325.71 231.13,-1331.62"/>
<text xml:space="preserve" text-anchor="middle" x="235.85" y="-1344.03" font-family="monospace" font-size="14.00" fill="#a6adc8">kmsgrab</text>
</g>
<!-- pulse -->
<g id="node2" class="node">
<title>pulse</title>
<path fill="#1e3a2f" stroke="#a6e3a1" d="M751.38,-1484.25C751.38,-1490.2 704.48,-1495.04 646.75,-1495.04 589.02,-1495.04 542.12,-1490.2 542.12,-1484.25 542.12,-1484.25 542.12,-1387.19 542.12,-1387.19 542.12,-1381.24 589.02,-1376.4 646.75,-1376.4 704.48,-1376.4 751.38,-1381.24 751.38,-1387.19 751.38,-1387.19 751.38,-1484.25 751.38,-1484.25"/>
<path fill="none" stroke="#a6e3a1" d="M751.38,-1484.25C751.38,-1478.3 704.48,-1473.47 646.75,-1473.47 589.02,-1473.47 542.12,-1478.3 542.12,-1484.25"/>
<text xml:space="preserve" text-anchor="middle" x="646.75" y="-1456.92" font-family="monospace" font-size="14.00" fill="#cdd6f4">PulseAudio</text>
<text xml:space="preserve" text-anchor="middle" x="646.75" y="-1439.67" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
<text xml:space="preserve" text-anchor="middle" x="646.75" y="-1422.42" font-family="monospace" font-size="14.00" fill="#cdd6f4">monitor: default sink</text>
<text xml:space="preserve" text-anchor="middle" x="646.75" y="-1405.17" font-family="monospace" font-size="14.00" fill="#cdd6f4">mic: webcam (C922)</text>
</g>
<!-- pulse&#45;&gt;ffmpeg_send -->
<g id="edge2" class="edge">
<title>pulse&#45;&gt;ffmpeg_send</title>
<path fill="none" stroke="#585b70" d="M555.11,-1379.54C528.25,-1363.36 498.43,-1345.41 469.95,-1328.25"/>
<polygon fill="#585b70" stroke="#585b70" points="472.01,-1325.41 461.64,-1323.25 468.4,-1331.41 472.01,-1325.41"/>
<text xml:space="preserve" text-anchor="middle" x="547.71" y="-1344.03" font-family="monospace" font-size="14.00" fill="#a6adc8">&#45;f pulse</text>
</g>
<!-- net -->
<g id="node3" class="node">
<title>net</title>
<polygon fill="#1e2a3e" stroke="#89b4fa" points="461.05,-1147.05 279.22,-1147.05 232.45,-1043.49 414.28,-1043.49 461.05,-1147.05"/>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1099.22" font-family="monospace" font-size="14.00" fill="#cdd6f4">TCP :4444</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1081.97" font-family="monospace" font-size="14.00" fill="#cdd6f4">mpegts</text>
</g>
<!-- ffmpeg_recv -->
<g id="node6" class="node">
<title>ffmpeg_recv</title>
<polygon fill="#1e2d3e" stroke="#89b4fa" points="505,-966.99 188.5,-966.99 188.5,-828.96 505,-828.96 505,-966.99"/>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-945.05" font-family="monospace" font-size="14.00" fill="#cdd6f4">ffmpeg listener</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-927.8" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-910.55" font-family="monospace" font-size="14.00" fill="#cdd6f4">listen=1 on TCP :4444</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-893.3" font-family="monospace" font-size="14.00" fill="#cdd6f4">→ 2 outputs:</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-876.05" font-family="monospace" font-size="14.00" fill="#cdd6f4"> &#160;fragmented MP4 (recording_*.mp4)</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-858.8" font-family="monospace" font-size="14.00" fill="#cdd6f4"> &#160;UDP :4445 (mpegts → mpv)</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-841.55" font-family="monospace" font-size="14.00" fill="#cdd6f4"> &#160;stdout pipe (showinfo)</text>
</g>
<!-- net&#45;&gt;ffmpeg_recv -->
<g id="edge5" class="edge">
<title>net&#45;&gt;ffmpeg_recv</title>
<path fill="none" stroke="#585b70" d="M346.75,-1043.21C346.75,-1023.48 346.75,-1000.44 346.75,-978.64"/>
<polygon fill="#585b70" stroke="#585b70" points="350.25,-978.88 346.75,-968.88 343.25,-978.88 350.25,-978.88"/>
<text xml:space="preserve" text-anchor="middle" x="371.5" y="-1012.19" font-family="monospace" font-size="14.00" fill="#a6adc8">mpegts</text>
</g>
<!-- watchdog -->
<g id="node4" class="node">
<title>watchdog</title>
<polygon fill="#2d2038" stroke="#cba6f7" points="500.88,-1496.11 192.62,-1496.11 192.62,-1375.33 500.88,-1375.33 500.88,-1496.11"/>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1474.17" font-family="monospace" font-size="14.00" fill="#cdd6f4">watchdog loop</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1456.92" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1439.67" font-family="monospace" font-size="14.00" fill="#cdd6f4">ffmpeg restart on stall</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1422.42" font-family="monospace" font-size="14.00" fill="#cdd6f4">(total_size or frame stuck &gt; 10s)</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1405.17" font-family="monospace" font-size="14.00" fill="#cdd6f4">immediate restart on</text>
<text xml:space="preserve" text-anchor="middle" x="346.75" y="-1387.92" font-family="monospace" font-size="14.00" fill="#cdd6f4">DRM plane format change</text>
</g>
<!-- watchdog&#45;&gt;ffmpeg_send -->
<g id="edge3" class="edge">
<title>watchdog&#45;&gt;ffmpeg_send</title>
<path fill="none" stroke="#585b70" stroke-dasharray="5,2" d="M346.75,-1375.07C346.75,-1361.9 346.75,-1347.74 346.75,-1333.92"/>
<polygon fill="#585b70" stroke="#585b70" points="350.25,-1333.93 346.75,-1323.93 343.25,-1333.93 350.25,-1333.93"/>
<text xml:space="preserve" text-anchor="middle" x="375.62" y="-1344.03" font-family="monospace" font-size="14.00" fill="#a6adc8">restart</text>
</g>
<!-- ffmpeg_send&#45;&gt;net -->
<g id="edge4" class="edge">
<title>ffmpeg_send&#45;&gt;net</title>
<path fill="none" stroke="#585b70" d="M346.75,-1183.73C346.75,-1175.4 346.75,-1166.91 346.75,-1158.67"/>
<polygon fill="#585b70" stroke="#585b70" points="350.25,-1158.73 346.75,-1148.73 343.25,-1158.73 350.25,-1158.73"/>
</g>
<!-- scene_pipe -->
<g id="node7" class="node">
<title>scene_pipe</title>
<polygon fill="#2d2038" stroke="#cba6f7" points="458.12,-775.69 199.38,-775.69 199.38,-672.16 458.12,-672.16 458.12,-775.69"/>
<text xml:space="preserve" text-anchor="middle" x="328.75" y="-753.75" font-family="monospace" font-size="14.00" fill="#cdd6f4">scene&#45;detect parser</text>
<text xml:space="preserve" text-anchor="middle" x="328.75" y="-736.5" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
<text xml:space="preserve" text-anchor="middle" x="328.75" y="-719.25" font-family="monospace" font-size="14.00" fill="#cdd6f4">reads stdout pipe</text>
<text xml:space="preserve" text-anchor="middle" x="328.75" y="-702" font-family="monospace" font-size="14.00" fill="#cdd6f4">showinfo → scene timestamps</text>
<text xml:space="preserve" text-anchor="middle" x="328.75" y="-684.75" font-family="monospace" font-size="14.00" fill="#cdd6f4">emits raw_frame(jpeg, ts)</text>
</g>
<!-- ffmpeg_recv&#45;&gt;scene_pipe -->
<g id="edge8" class="edge">
<title>ffmpeg_recv&#45;&gt;scene_pipe</title>
<path fill="none" stroke="#585b70" d="M339.58,-828.48C338.15,-814.79 336.65,-800.49 335.25,-787.03"/>
<polygon fill="#585b70" stroke="#585b70" points="338.77,-787.04 334.25,-777.46 331.81,-787.77 338.77,-787.04"/>
<text xml:space="preserve" text-anchor="middle" x="362.5" y="-797.66" font-family="monospace" font-size="14.00" fill="#a6adc8">stdout</text>
</g>
<!-- fmp4 -->
<g id="node13" class="node">
<title>fmp4</title>
<polygon fill="#2a2a3e" stroke="#585b70" points="680.62,-749.82 677.62,-753.82 656.62,-753.82 653.62,-749.82 520.88,-749.82 520.88,-698.04 680.62,-698.04 680.62,-749.82"/>
<text xml:space="preserve" text-anchor="middle" x="600.75" y="-727.88" font-family="monospace" font-size="14.00" fill="#cdd6f4">stream/</text>
<text xml:space="preserve" text-anchor="middle" x="600.75" y="-710.63" font-family="monospace" font-size="14.00" fill="#cdd6f4">recording_*.mp4</text>
</g>
<!-- ffmpeg_recv&#45;&gt;fmp4 -->
<g id="edge6" class="edge">
<title>ffmpeg_recv&#45;&gt;fmp4</title>
<path fill="none" stroke="#585b70" d="M447.87,-828.48C484.57,-803.62 524.28,-776.73 554.03,-756.57"/>
<polygon fill="#585b70" stroke="#585b70" points="555.75,-759.63 562.07,-751.13 551.83,-753.84 555.75,-759.63"/>
</g>
<!-- udp -->
<g id="node14" class="node">
<title>udp</title>
<polygon fill="#2a2a3e" stroke="#585b70" points="981.05,-775.71 799.22,-775.71 752.45,-672.15 934.28,-672.15 981.05,-775.71"/>
<text xml:space="preserve" text-anchor="middle" x="866.75" y="-727.88" font-family="monospace" font-size="14.00" fill="#cdd6f4">UDP :4445</text>
<text xml:space="preserve" text-anchor="middle" x="866.75" y="-710.63" font-family="monospace" font-size="14.00" fill="#cdd6f4">→ mpv</text>
</g>
<!-- ffmpeg_recv&#45;&gt;udp -->
<g id="edge7" class="edge">
<title>ffmpeg_recv&#45;&gt;udp</title>
<path fill="none" stroke="#585b70" d="M505.24,-844.54C594.36,-815.05 702.36,-779.32 776.98,-754.63"/>
<polygon fill="#585b70" stroke="#585b70" points="777.91,-758.01 786.31,-751.55 775.71,-751.36 777.91,-758.01"/>
</g>
<!-- frame_writer -->
<g id="node8" class="node">
<title>frame_writer</title>
<polygon fill="#2d2038" stroke="#cba6f7" points="419.38,-595.65 144.12,-595.65 144.12,-492.12 419.38,-492.12 419.38,-595.65"/>
<text xml:space="preserve" text-anchor="middle" x="281.75" y="-573.71" font-family="monospace" font-size="14.00" fill="#cdd6f4">frame writer</text>
<text xml:space="preserve" text-anchor="middle" x="281.75" y="-556.46" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
<text xml:space="preserve" text-anchor="middle" x="281.75" y="-539.21" font-family="monospace" font-size="14.00" fill="#cdd6f4">writes JPEG to frames/</text>
<text xml:space="preserve" text-anchor="middle" x="281.75" y="-521.96" font-family="monospace" font-size="14.00" fill="#cdd6f4">appends to index.json</text>
<text xml:space="preserve" text-anchor="middle" x="281.75" y="-504.71" font-family="monospace" font-size="14.00" fill="#cdd6f4">fires on_new_frames(ts, path)</text>
</g>
<!-- scene_pipe&#45;&gt;frame_writer -->
<g id="edge10" class="edge">
<title>scene_pipe&#45;&gt;frame_writer</title>
<path fill="none" stroke="#585b70" d="M315.28,-671.91C309.92,-651.61 303.71,-628.06 298.09,-606.8"/>
<polygon fill="#585b70" stroke="#585b70" points="301.54,-606.15 295.61,-597.38 294.77,-607.94 301.54,-606.15"/>
<text xml:space="preserve" text-anchor="middle" x="346.58" y="-640.85" font-family="monospace" font-size="14.00" fill="#a6adc8">raw_frame</text>
</g>
<!-- frames -->
<g id="node15" class="node">
<title>frames</title>
<polygon fill="#2a2a3e" stroke="#585b70" points="464,-192.31 461,-196.31 440,-196.31 437,-192.31 279.5,-192.31 279.5,-140.53 464,-140.53 464,-192.31"/>
<text xml:space="preserve" text-anchor="middle" x="371.75" y="-170.37" font-family="monospace" font-size="14.00" fill="#cdd6f4">frames/</text>
<text xml:space="preserve" text-anchor="middle" x="371.75" y="-153.12" font-family="monospace" font-size="14.00" fill="#cdd6f4">index.json + *.jpg</text>
</g>
<!-- frame_writer&#45;&gt;frames -->
<g id="edge11" class="edge">
<title>frame_writer&#45;&gt;frames</title>
<path fill="none" stroke="#585b70" d="M293.98,-491.86C312.47,-414.71 347.09,-270.31 363.15,-203.29"/>
<polygon fill="#585b70" stroke="#585b70" points="366.47,-204.47 365.39,-193.93 359.66,-202.84 366.47,-204.47"/>
</g>
<!-- audio_extract -->
<g id="node9" class="node">
<title>audio_extract</title>
<polygon fill="#2d2038" stroke="#cba6f7" points="671.75,-595.65 437.75,-595.65 437.75,-492.12 671.75,-492.12 671.75,-595.65"/>
<text xml:space="preserve" text-anchor="middle" x="554.75" y="-573.71" font-family="monospace" font-size="14.00" fill="#cdd6f4">audio extractor</text>
<text xml:space="preserve" text-anchor="middle" x="554.75" y="-556.46" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
<text xml:space="preserve" text-anchor="middle" x="554.75" y="-539.21" font-family="monospace" font-size="14.00" fill="#cdd6f4">polls fMP4 for new audio</text>
<text xml:space="preserve" text-anchor="middle" x="554.75" y="-521.96" font-family="monospace" font-size="14.00" fill="#cdd6f4">ffmpeg → 16 kHz mono WAV</text>
<text xml:space="preserve" text-anchor="middle" x="554.75" y="-504.71" font-family="monospace" font-size="14.00" fill="#cdd6f4">chunks for transcription</text>
</g>
<!-- audio -->
<g id="node16" class="node">
<title>audio</title>
<polygon fill="#2a2a3e" stroke="#585b70" points="620.12,-455.12 617.12,-459.12 596.12,-459.12 593.12,-455.12 493.38,-455.12 493.38,-403.34 620.12,-403.34 620.12,-455.12"/>
<text xml:space="preserve" text-anchor="middle" x="556.75" y="-433.18" font-family="monospace" font-size="14.00" fill="#cdd6f4">audio/</text>
<text xml:space="preserve" text-anchor="middle" x="556.75" y="-415.93" font-family="monospace" font-size="14.00" fill="#cdd6f4">chunk_*.wav</text>
</g>
<!-- audio_extract&#45;&gt;audio -->
<g id="edge13" class="edge">
<title>audio_extract&#45;&gt;audio</title>
<path fill="none" stroke="#585b70" d="M555.66,-491.83C555.8,-483.48 555.96,-474.97 556.1,-467.05"/>
<polygon fill="#585b70" stroke="#585b70" points="559.59,-467.16 556.27,-457.1 552.6,-467.03 559.59,-467.16"/>
</g>
<!-- tracker -->
<g id="node10" class="node">
<title>tracker</title>
<polygon fill="#2d2038" stroke="#cba6f7" points="865.88,-595.65 689.62,-595.65 689.62,-492.12 865.88,-492.12 865.88,-595.65"/>
<text xml:space="preserve" text-anchor="middle" x="777.75" y="-573.71" font-family="monospace" font-size="14.00" fill="#cdd6f4">RecordingTracker</text>
<text xml:space="preserve" text-anchor="middle" x="777.75" y="-556.46" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
<text xml:space="preserve" text-anchor="middle" x="777.75" y="-539.21" font-family="monospace" font-size="14.00" fill="#cdd6f4">ffprobe duration</text>
<text xml:space="preserve" text-anchor="middle" x="777.75" y="-521.96" font-family="monospace" font-size="14.00" fill="#cdd6f4">sums segments</text>
<text xml:space="preserve" text-anchor="middle" x="777.75" y="-504.71" font-family="monospace" font-size="14.00" fill="#cdd6f4">feeds timeline UI</text>
</g>
<!-- gui -->
<g id="node12" class="node">
<title>gui</title>
<polygon fill="#2d2038" stroke="#cba6f7" points="860.62,-103.53 568.88,-103.53 568.88,0 860.62,0 860.62,-103.53"/>
<text xml:space="preserve" text-anchor="middle" x="714.75" y="-81.59" font-family="monospace" font-size="14.00" fill="#cdd6f4">Mitus GUI (GTK4)</text>
<text xml:space="preserve" text-anchor="middle" x="714.75" y="-64.34" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
<text xml:space="preserve" text-anchor="middle" x="714.75" y="-47.09" font-family="monospace" font-size="14.00" fill="#cdd6f4">Monitor (mpv UDP)</text>
<text xml:space="preserve" text-anchor="middle" x="714.75" y="-29.84" font-family="monospace" font-size="14.00" fill="#cdd6f4">Scrub bar · Frames · Transcript</text>
<text xml:space="preserve" text-anchor="middle" x="714.75" y="-12.59" font-family="monospace" font-size="14.00" fill="#cdd6f4">Agent input/output</text>
</g>
<!-- tracker&#45;&gt;gui -->
<g id="edge17" class="edge">
<title>tracker&#45;&gt;gui</title>
<path fill="none" stroke="#585b70" d="M771.41,-491.83C767.7,-462.02 763.75,-430.23 763.75,-430.23 763.75,-430.23 763.75,-430.23 763.75,-165.42 763.75,-165.42 752.97,-140.64 741.53,-114.33"/>
<polygon fill="#585b70" stroke="#585b70" points="744.76,-112.98 737.56,-105.21 738.34,-115.77 744.76,-112.98"/>
<text xml:space="preserve" text-anchor="middle" x="796.75" y="-276.4" font-family="monospace" font-size="14.00" fill="#a6adc8">duration</text>
</g>
<!-- transcriber -->
<g id="node11" class="node">
<title>transcriber</title>
<polygon fill="#2d2038" stroke="#cba6f7" points="726,-332.84 409.5,-332.84 409.5,-229.31 726,-229.31 726,-332.84"/>
<text xml:space="preserve" text-anchor="middle" x="567.75" y="-310.9" font-family="monospace" font-size="14.00" fill="#cdd6f4">TranscriberEngine</text>
<text xml:space="preserve" text-anchor="middle" x="567.75" y="-293.65" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
<text xml:space="preserve" text-anchor="middle" x="567.75" y="-276.4" font-family="monospace" font-size="14.00" fill="#cdd6f4">cht/transcriber/engine.py</text>
<text xml:space="preserve" text-anchor="middle" x="567.75" y="-259.15" font-family="monospace" font-size="14.00" fill="#cdd6f4">faster&#45;whisper (CUDA)</text>
<text xml:space="preserve" text-anchor="middle" x="567.75" y="-241.9" font-family="monospace" font-size="14.00" fill="#cdd6f4">grouped segments → transcript.json</text>
</g>
<!-- txt -->
<g id="node17" class="node">
<title>txt</title>
<polygon fill="#2a2a3e" stroke="#585b70" points="691.62,-184.42 688.62,-188.42 667.62,-188.42 664.62,-184.42 531.88,-184.42 531.88,-148.42 691.62,-148.42 691.62,-184.42"/>
<text xml:space="preserve" text-anchor="middle" x="611.75" y="-161.75" font-family="monospace" font-size="14.00" fill="#cdd6f4">transcript.json</text>
</g>
<!-- transcriber&#45;&gt;txt -->
<g id="edge15" class="edge">
<title>transcriber&#45;&gt;txt</title>
<path fill="none" stroke="#585b70" d="M587.69,-229.02C592.18,-217.52 596.79,-205.72 600.76,-195.56"/>
<polygon fill="#585b70" stroke="#585b70" points="603.99,-196.9 604.37,-186.31 597.47,-194.35 603.99,-196.9"/>
</g>
<!-- fmp4&#45;&gt;audio_extract -->
<g id="edge12" class="edge">
<title>fmp4&#45;&gt;audio_extract</title>
<path fill="none" stroke="#585b70" stroke-dasharray="5,2" d="M594.26,-697.8C588.16,-674.22 578.81,-638 570.73,-606.73"/>
<polygon fill="#585b70" stroke="#585b70" points="574.2,-606.17 568.31,-597.37 567.42,-607.92 574.2,-606.17"/>
<text xml:space="preserve" text-anchor="middle" x="598.37" y="-640.85" font-family="monospace" font-size="14.00" fill="#a6adc8">poll</text>
</g>
<!-- fmp4&#45;&gt;tracker -->
<g id="edge16" class="edge">
<title>fmp4&#45;&gt;tracker</title>
<path fill="none" stroke="#585b70" stroke-dasharray="5,2" d="M625.73,-697.8C649.89,-673.5 687.4,-635.77 719.11,-603.87"/>
<polygon fill="#585b70" stroke="#585b70" points="721.4,-606.53 725.97,-596.97 716.43,-601.6 721.4,-606.53"/>
<text xml:space="preserve" text-anchor="middle" x="712.82" y="-640.85" font-family="monospace" font-size="14.00" fill="#a6adc8">ffprobe</text>
</g>
<!-- udp&#45;&gt;gui -->
<g id="edge9" class="edge">
<title>udp&#45;&gt;gui</title>
<path fill="none" stroke="#585b70" d="M874.49,-671.91C882.47,-619.3 893.75,-544.88 893.75,-544.88 893.75,-544.88 893.75,-544.88 893.75,-165.42 893.75,-165.42 850.06,-137.93 805.85,-110.1"/>
<polygon fill="#585b70" stroke="#585b70" points="807.74,-107.15 797.41,-104.79 804.01,-113.08 807.74,-107.15"/>
<text xml:space="preserve" text-anchor="middle" x="922.62" y="-372.04" font-family="monospace" font-size="14.00" fill="#a6adc8">live</text>
<text xml:space="preserve" text-anchor="middle" x="922.62" y="-354.79" font-family="monospace" font-size="14.00" fill="#a6adc8">monitor</text>
</g>
<!-- frames&#45;&gt;gui -->
<g id="edge18" class="edge">
<title>frames&#45;&gt;gui</title>
<path fill="none" stroke="#585b70" d="M448.73,-140.14C481.04,-129.52 519.87,-116.77 557.75,-104.33"/>
<polygon fill="#585b70" stroke="#585b70" points="558.56,-107.75 566.97,-101.3 556.37,-101.1 558.56,-107.75"/>
</g>
<!-- audio&#45;&gt;transcriber -->
<g id="edge14" class="edge">
<title>audio&#45;&gt;transcriber</title>
<path fill="none" stroke="#585b70" d="M558.64,-403.11C559.86,-386.92 561.5,-365.12 563.05,-344.48"/>
<polygon fill="#585b70" stroke="#585b70" points="566.53,-344.92 563.79,-334.69 559.55,-344.4 566.53,-344.92"/>
<text xml:space="preserve" text-anchor="middle" x="574.62" y="-363.41" font-family="monospace" font-size="14.00" fill="#a6adc8">WAV</text>
</g>
<!-- txt&#45;&gt;gui -->
<g id="edge19" class="edge">
<title>txt&#45;&gt;gui</title>
<path fill="none" stroke="#585b70" d="M627.39,-148.31C636.43,-138.42 648.4,-125.33 660.57,-112.02"/>
<polygon fill="#585b70" stroke="#585b70" points="662.96,-114.59 667.13,-104.85 657.8,-109.87 662.96,-114.59"/>
</g>
</g>
</svg>