Backend:
- Install ffmpeg + numpy in Docker image
- New waveform.py: FFT-based SVG generator with 64 frequency bands
- GET /api/clips/{id}/waveform — generates on demand, caches to /data/waveforms/
- DELETE /api/clips/{id} now cascade-removes waveform SVG
- Warm amber-to-orange HSL gradient (25° to 35° hue)
- Mirrored bars: top full opacity, bottom 60% opacity
Frontend:
- DetailPanel shows waveform image beneath album art (80px height)
- Only shown for clips with status='ready'
Storage: /data/waveforms/ persisted via existing ./data volume mount
137 lines
14 KiB
XML
137 lines
14 KiB
XML
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="200" viewBox="0 0 800 200" preserveAspectRatio="none">
|
|
<defs>
|
|
<linearGradient id="barGrad" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
<stop offset="0%" stop-color="#f59e0b" />
|
|
<stop offset="100%" stop-color="#ea580c" />
|
|
</linearGradient>
|
|
</defs>
|
|
<rect width="800" height="200" fill="transparent" />
|
|
<rect x="0.00" y="10.00" width="10.53" height="90.00" fill="hsl(25.0, 85%, 45.0%)" rx="2.63" />
|
|
<rect x="0.00" y="100.00" width="10.53" height="90.00" fill="hsl(25.0, 85%, 45.0%)" rx="2.63" opacity="0.6" />
|
|
<rect x="12.53" y="10.00" width="10.53" height="90.00" fill="hsl(25.2, 85%, 45.3%)" rx="2.63" />
|
|
<rect x="12.53" y="100.00" width="10.53" height="90.00" fill="hsl(25.2, 85%, 45.3%)" rx="2.63" opacity="0.6" />
|
|
<rect x="25.06" y="10.00" width="10.53" height="90.00" fill="hsl(25.3, 85%, 45.6%)" rx="2.63" />
|
|
<rect x="25.06" y="100.00" width="10.53" height="90.00" fill="hsl(25.3, 85%, 45.6%)" rx="2.63" opacity="0.6" />
|
|
<rect x="37.59" y="10.00" width="10.53" height="90.00" fill="hsl(25.5, 85%, 46.0%)" rx="2.63" />
|
|
<rect x="37.59" y="100.00" width="10.53" height="90.00" fill="hsl(25.5, 85%, 46.0%)" rx="2.63" opacity="0.6" />
|
|
<rect x="50.12" y="10.00" width="10.53" height="90.00" fill="hsl(25.6, 85%, 46.3%)" rx="2.63" />
|
|
<rect x="50.12" y="100.00" width="10.53" height="90.00" fill="hsl(25.6, 85%, 46.3%)" rx="2.63" opacity="0.6" />
|
|
<rect x="62.66" y="10.00" width="10.53" height="90.00" fill="hsl(25.8, 85%, 46.6%)" rx="2.63" />
|
|
<rect x="62.66" y="100.00" width="10.53" height="90.00" fill="hsl(25.8, 85%, 46.6%)" rx="2.63" opacity="0.6" />
|
|
<rect x="75.19" y="10.00" width="10.53" height="90.00" fill="hsl(26.0, 85%, 46.9%)" rx="2.63" />
|
|
<rect x="75.19" y="100.00" width="10.53" height="90.00" fill="hsl(26.0, 85%, 46.9%)" rx="2.63" opacity="0.6" />
|
|
<rect x="87.72" y="10.00" width="10.53" height="90.00" fill="hsl(26.1, 85%, 47.2%)" rx="2.63" />
|
|
<rect x="87.72" y="100.00" width="10.53" height="90.00" fill="hsl(26.1, 85%, 47.2%)" rx="2.63" opacity="0.6" />
|
|
<rect x="100.25" y="10.00" width="10.53" height="90.00" fill="hsl(26.3, 85%, 47.5%)" rx="2.63" />
|
|
<rect x="100.25" y="100.00" width="10.53" height="90.00" fill="hsl(26.3, 85%, 47.5%)" rx="2.63" opacity="0.6" />
|
|
<rect x="112.78" y="10.00" width="10.53" height="90.00" fill="hsl(26.4, 85%, 47.9%)" rx="2.63" />
|
|
<rect x="112.78" y="100.00" width="10.53" height="90.00" fill="hsl(26.4, 85%, 47.9%)" rx="2.63" opacity="0.6" />
|
|
<rect x="125.31" y="10.00" width="10.53" height="90.00" fill="hsl(26.6, 85%, 48.2%)" rx="2.63" />
|
|
<rect x="125.31" y="100.00" width="10.53" height="90.00" fill="hsl(26.6, 85%, 48.2%)" rx="2.63" opacity="0.6" />
|
|
<rect x="137.84" y="10.00" width="10.53" height="90.00" fill="hsl(26.7, 85%, 48.5%)" rx="2.63" />
|
|
<rect x="137.84" y="100.00" width="10.53" height="90.00" fill="hsl(26.7, 85%, 48.5%)" rx="2.63" opacity="0.6" />
|
|
<rect x="150.38" y="10.00" width="10.53" height="90.00" fill="hsl(26.9, 85%, 48.8%)" rx="2.63" />
|
|
<rect x="150.38" y="100.00" width="10.53" height="90.00" fill="hsl(26.9, 85%, 48.8%)" rx="2.63" opacity="0.6" />
|
|
<rect x="162.91" y="10.00" width="10.53" height="90.00" fill="hsl(27.1, 85%, 49.1%)" rx="2.63" />
|
|
<rect x="162.91" y="100.00" width="10.53" height="90.00" fill="hsl(27.1, 85%, 49.1%)" rx="2.63" opacity="0.6" />
|
|
<rect x="175.44" y="10.00" width="10.53" height="90.00" fill="hsl(27.2, 85%, 49.4%)" rx="2.63" />
|
|
<rect x="175.44" y="100.00" width="10.53" height="90.00" fill="hsl(27.2, 85%, 49.4%)" rx="2.63" opacity="0.6" />
|
|
<rect x="187.97" y="10.00" width="10.53" height="90.00" fill="hsl(27.4, 85%, 49.8%)" rx="2.63" />
|
|
<rect x="187.97" y="100.00" width="10.53" height="90.00" fill="hsl(27.4, 85%, 49.8%)" rx="2.63" opacity="0.6" />
|
|
<rect x="200.50" y="10.00" width="10.53" height="90.00" fill="hsl(27.5, 85%, 50.1%)" rx="2.63" />
|
|
<rect x="200.50" y="100.00" width="10.53" height="90.00" fill="hsl(27.5, 85%, 50.1%)" rx="2.63" opacity="0.6" />
|
|
<rect x="213.03" y="10.00" width="10.53" height="90.00" fill="hsl(27.7, 85%, 50.4%)" rx="2.63" />
|
|
<rect x="213.03" y="100.00" width="10.53" height="90.00" fill="hsl(27.7, 85%, 50.4%)" rx="2.63" opacity="0.6" />
|
|
<rect x="225.56" y="10.00" width="10.53" height="90.00" fill="hsl(27.9, 85%, 50.7%)" rx="2.63" />
|
|
<rect x="225.56" y="100.00" width="10.53" height="90.00" fill="hsl(27.9, 85%, 50.7%)" rx="2.63" opacity="0.6" />
|
|
<rect x="238.09" y="10.00" width="10.53" height="90.00" fill="hsl(28.0, 85%, 51.0%)" rx="2.63" />
|
|
<rect x="238.09" y="100.00" width="10.53" height="90.00" fill="hsl(28.0, 85%, 51.0%)" rx="2.63" opacity="0.6" />
|
|
<rect x="250.62" y="10.00" width="10.53" height="90.00" fill="hsl(28.2, 85%, 51.3%)" rx="2.63" />
|
|
<rect x="250.62" y="100.00" width="10.53" height="90.00" fill="hsl(28.2, 85%, 51.3%)" rx="2.63" opacity="0.6" />
|
|
<rect x="263.16" y="10.00" width="10.53" height="90.00" fill="hsl(28.3, 85%, 51.7%)" rx="2.63" />
|
|
<rect x="263.16" y="100.00" width="10.53" height="90.00" fill="hsl(28.3, 85%, 51.7%)" rx="2.63" opacity="0.6" />
|
|
<rect x="275.69" y="10.00" width="10.53" height="90.00" fill="hsl(28.5, 85%, 52.0%)" rx="2.63" />
|
|
<rect x="275.69" y="100.00" width="10.53" height="90.00" fill="hsl(28.5, 85%, 52.0%)" rx="2.63" opacity="0.6" />
|
|
<rect x="288.22" y="10.00" width="10.53" height="90.00" fill="hsl(28.7, 85%, 52.3%)" rx="2.63" />
|
|
<rect x="288.22" y="100.00" width="10.53" height="90.00" fill="hsl(28.7, 85%, 52.3%)" rx="2.63" opacity="0.6" />
|
|
<rect x="300.75" y="10.00" width="10.53" height="90.00" fill="hsl(28.8, 85%, 52.6%)" rx="2.63" />
|
|
<rect x="300.75" y="100.00" width="10.53" height="90.00" fill="hsl(28.8, 85%, 52.6%)" rx="2.63" opacity="0.6" />
|
|
<rect x="313.28" y="10.00" width="10.53" height="90.00" fill="hsl(29.0, 85%, 52.9%)" rx="2.63" />
|
|
<rect x="313.28" y="100.00" width="10.53" height="90.00" fill="hsl(29.0, 85%, 52.9%)" rx="2.63" opacity="0.6" />
|
|
<rect x="325.81" y="10.00" width="10.53" height="90.00" fill="hsl(29.1, 85%, 53.3%)" rx="2.63" />
|
|
<rect x="325.81" y="100.00" width="10.53" height="90.00" fill="hsl(29.1, 85%, 53.3%)" rx="2.63" opacity="0.6" />
|
|
<rect x="338.34" y="10.00" width="10.53" height="90.00" fill="hsl(29.3, 85%, 53.6%)" rx="2.63" />
|
|
<rect x="338.34" y="100.00" width="10.53" height="90.00" fill="hsl(29.3, 85%, 53.6%)" rx="2.63" opacity="0.6" />
|
|
<rect x="350.88" y="10.00" width="10.53" height="90.00" fill="hsl(29.4, 85%, 53.9%)" rx="2.63" />
|
|
<rect x="350.88" y="100.00" width="10.53" height="90.00" fill="hsl(29.4, 85%, 53.9%)" rx="2.63" opacity="0.6" />
|
|
<rect x="363.41" y="10.00" width="10.53" height="90.00" fill="hsl(29.6, 85%, 54.2%)" rx="2.63" />
|
|
<rect x="363.41" y="100.00" width="10.53" height="90.00" fill="hsl(29.6, 85%, 54.2%)" rx="2.63" opacity="0.6" />
|
|
<rect x="375.94" y="10.00" width="10.53" height="90.00" fill="hsl(29.8, 85%, 54.5%)" rx="2.63" />
|
|
<rect x="375.94" y="100.00" width="10.53" height="90.00" fill="hsl(29.8, 85%, 54.5%)" rx="2.63" opacity="0.6" />
|
|
<rect x="388.47" y="10.00" width="10.53" height="90.00" fill="hsl(29.9, 85%, 54.8%)" rx="2.63" />
|
|
<rect x="388.47" y="100.00" width="10.53" height="90.00" fill="hsl(29.9, 85%, 54.8%)" rx="2.63" opacity="0.6" />
|
|
<rect x="401.00" y="10.00" width="10.53" height="90.00" fill="hsl(30.1, 85%, 55.2%)" rx="2.63" />
|
|
<rect x="401.00" y="100.00" width="10.53" height="90.00" fill="hsl(30.1, 85%, 55.2%)" rx="2.63" opacity="0.6" />
|
|
<rect x="413.53" y="10.00" width="10.53" height="90.00" fill="hsl(30.2, 85%, 55.5%)" rx="2.63" />
|
|
<rect x="413.53" y="100.00" width="10.53" height="90.00" fill="hsl(30.2, 85%, 55.5%)" rx="2.63" opacity="0.6" />
|
|
<rect x="426.06" y="10.00" width="10.53" height="90.00" fill="hsl(30.4, 85%, 55.8%)" rx="2.63" />
|
|
<rect x="426.06" y="100.00" width="10.53" height="90.00" fill="hsl(30.4, 85%, 55.8%)" rx="2.63" opacity="0.6" />
|
|
<rect x="438.59" y="10.00" width="10.53" height="90.00" fill="hsl(30.6, 85%, 56.1%)" rx="2.63" />
|
|
<rect x="438.59" y="100.00" width="10.53" height="90.00" fill="hsl(30.6, 85%, 56.1%)" rx="2.63" opacity="0.6" />
|
|
<rect x="451.12" y="10.00" width="10.53" height="90.00" fill="hsl(30.7, 85%, 56.4%)" rx="2.63" />
|
|
<rect x="451.12" y="100.00" width="10.53" height="90.00" fill="hsl(30.7, 85%, 56.4%)" rx="2.63" opacity="0.6" />
|
|
<rect x="463.66" y="10.00" width="10.53" height="90.00" fill="hsl(30.9, 85%, 56.7%)" rx="2.63" />
|
|
<rect x="463.66" y="100.00" width="10.53" height="90.00" fill="hsl(30.9, 85%, 56.7%)" rx="2.63" opacity="0.6" />
|
|
<rect x="476.19" y="10.00" width="10.53" height="90.00" fill="hsl(31.0, 85%, 57.1%)" rx="2.63" />
|
|
<rect x="476.19" y="100.00" width="10.53" height="90.00" fill="hsl(31.0, 85%, 57.1%)" rx="2.63" opacity="0.6" />
|
|
<rect x="488.72" y="10.00" width="10.53" height="90.00" fill="hsl(31.2, 85%, 57.4%)" rx="2.63" />
|
|
<rect x="488.72" y="100.00" width="10.53" height="90.00" fill="hsl(31.2, 85%, 57.4%)" rx="2.63" opacity="0.6" />
|
|
<rect x="501.25" y="10.00" width="10.53" height="90.00" fill="hsl(31.3, 85%, 57.7%)" rx="2.63" />
|
|
<rect x="501.25" y="100.00" width="10.53" height="90.00" fill="hsl(31.3, 85%, 57.7%)" rx="2.63" opacity="0.6" />
|
|
<rect x="513.78" y="10.00" width="10.53" height="90.00" fill="hsl(31.5, 85%, 58.0%)" rx="2.63" />
|
|
<rect x="513.78" y="100.00" width="10.53" height="90.00" fill="hsl(31.5, 85%, 58.0%)" rx="2.63" opacity="0.6" />
|
|
<rect x="526.31" y="10.00" width="10.53" height="90.00" fill="hsl(31.7, 85%, 58.3%)" rx="2.63" />
|
|
<rect x="526.31" y="100.00" width="10.53" height="90.00" fill="hsl(31.7, 85%, 58.3%)" rx="2.63" opacity="0.6" />
|
|
<rect x="538.84" y="10.00" width="10.53" height="90.00" fill="hsl(31.8, 85%, 58.7%)" rx="2.63" />
|
|
<rect x="538.84" y="100.00" width="10.53" height="90.00" fill="hsl(31.8, 85%, 58.7%)" rx="2.63" opacity="0.6" />
|
|
<rect x="551.38" y="10.00" width="10.53" height="90.00" fill="hsl(32.0, 85%, 59.0%)" rx="2.63" />
|
|
<rect x="551.38" y="100.00" width="10.53" height="90.00" fill="hsl(32.0, 85%, 59.0%)" rx="2.63" opacity="0.6" />
|
|
<rect x="563.91" y="10.00" width="10.53" height="90.00" fill="hsl(32.1, 85%, 59.3%)" rx="2.63" />
|
|
<rect x="563.91" y="100.00" width="10.53" height="90.00" fill="hsl(32.1, 85%, 59.3%)" rx="2.63" opacity="0.6" />
|
|
<rect x="576.44" y="10.00" width="10.53" height="90.00" fill="hsl(32.3, 85%, 59.6%)" rx="2.63" />
|
|
<rect x="576.44" y="100.00" width="10.53" height="90.00" fill="hsl(32.3, 85%, 59.6%)" rx="2.63" opacity="0.6" />
|
|
<rect x="588.97" y="10.00" width="10.53" height="90.00" fill="hsl(32.5, 85%, 59.9%)" rx="2.63" />
|
|
<rect x="588.97" y="100.00" width="10.53" height="90.00" fill="hsl(32.5, 85%, 59.9%)" rx="2.63" opacity="0.6" />
|
|
<rect x="601.50" y="10.00" width="10.53" height="90.00" fill="hsl(32.6, 85%, 60.2%)" rx="2.63" />
|
|
<rect x="601.50" y="100.00" width="10.53" height="90.00" fill="hsl(32.6, 85%, 60.2%)" rx="2.63" opacity="0.6" />
|
|
<rect x="614.03" y="10.00" width="10.53" height="90.00" fill="hsl(32.8, 85%, 60.6%)" rx="2.63" />
|
|
<rect x="614.03" y="100.00" width="10.53" height="90.00" fill="hsl(32.8, 85%, 60.6%)" rx="2.63" opacity="0.6" />
|
|
<rect x="626.56" y="10.00" width="10.53" height="90.00" fill="hsl(32.9, 85%, 60.9%)" rx="2.63" />
|
|
<rect x="626.56" y="100.00" width="10.53" height="90.00" fill="hsl(32.9, 85%, 60.9%)" rx="2.63" opacity="0.6" />
|
|
<rect x="639.09" y="10.00" width="10.53" height="90.00" fill="hsl(33.1, 85%, 61.2%)" rx="2.63" />
|
|
<rect x="639.09" y="100.00" width="10.53" height="90.00" fill="hsl(33.1, 85%, 61.2%)" rx="2.63" opacity="0.6" />
|
|
<rect x="651.62" y="10.00" width="10.53" height="90.00" fill="hsl(33.3, 85%, 61.5%)" rx="2.63" />
|
|
<rect x="651.62" y="100.00" width="10.53" height="90.00" fill="hsl(33.3, 85%, 61.5%)" rx="2.63" opacity="0.6" />
|
|
<rect x="664.16" y="10.00" width="10.53" height="90.00" fill="hsl(33.4, 85%, 61.8%)" rx="2.63" />
|
|
<rect x="664.16" y="100.00" width="10.53" height="90.00" fill="hsl(33.4, 85%, 61.8%)" rx="2.63" opacity="0.6" />
|
|
<rect x="676.69" y="10.00" width="10.53" height="90.00" fill="hsl(33.6, 85%, 62.1%)" rx="2.63" />
|
|
<rect x="676.69" y="100.00" width="10.53" height="90.00" fill="hsl(33.6, 85%, 62.1%)" rx="2.63" opacity="0.6" />
|
|
<rect x="689.22" y="10.00" width="10.53" height="90.00" fill="hsl(33.7, 85%, 62.5%)" rx="2.63" />
|
|
<rect x="689.22" y="100.00" width="10.53" height="90.00" fill="hsl(33.7, 85%, 62.5%)" rx="2.63" opacity="0.6" />
|
|
<rect x="701.75" y="10.00" width="10.53" height="90.00" fill="hsl(33.9, 85%, 62.8%)" rx="2.63" />
|
|
<rect x="701.75" y="100.00" width="10.53" height="90.00" fill="hsl(33.9, 85%, 62.8%)" rx="2.63" opacity="0.6" />
|
|
<rect x="714.28" y="10.00" width="10.53" height="90.00" fill="hsl(34.0, 85%, 63.1%)" rx="2.63" />
|
|
<rect x="714.28" y="100.00" width="10.53" height="90.00" fill="hsl(34.0, 85%, 63.1%)" rx="2.63" opacity="0.6" />
|
|
<rect x="726.81" y="10.00" width="10.53" height="90.00" fill="hsl(34.2, 85%, 63.4%)" rx="2.63" />
|
|
<rect x="726.81" y="100.00" width="10.53" height="90.00" fill="hsl(34.2, 85%, 63.4%)" rx="2.63" opacity="0.6" />
|
|
<rect x="739.34" y="10.00" width="10.53" height="90.00" fill="hsl(34.4, 85%, 63.7%)" rx="2.63" />
|
|
<rect x="739.34" y="100.00" width="10.53" height="90.00" fill="hsl(34.4, 85%, 63.7%)" rx="2.63" opacity="0.6" />
|
|
<rect x="751.88" y="13.74" width="10.53" height="86.26" fill="hsl(34.5, 85%, 64.0%)" rx="2.63" />
|
|
<rect x="751.88" y="100.00" width="10.53" height="86.26" fill="hsl(34.5, 85%, 64.0%)" rx="2.63" opacity="0.6" />
|
|
<rect x="764.41" y="23.38" width="10.53" height="76.62" fill="hsl(34.7, 85%, 64.4%)" rx="2.63" />
|
|
<rect x="764.41" y="100.00" width="10.53" height="76.62" fill="hsl(34.7, 85%, 64.4%)" rx="2.63" opacity="0.6" />
|
|
<rect x="776.94" y="35.46" width="10.53" height="64.54" fill="hsl(34.8, 85%, 64.7%)" rx="2.63" />
|
|
<rect x="776.94" y="100.00" width="10.53" height="64.54" fill="hsl(34.8, 85%, 64.7%)" rx="2.63" opacity="0.6" />
|
|
<rect x="789.47" y="42.58" width="10.53" height="57.42" fill="hsl(35.0, 85%, 65.0%)" rx="2.63" />
|
|
<rect x="789.47" y="100.00" width="10.53" height="57.42" fill="hsl(35.0, 85%, 65.0%)" rx="2.63" opacity="0.6" />
|
|
</svg> |