Index: src/routes/audio.js
===================================================================
--- src/routes/audio.js	(revision 749605af631b5b99863f74d5dafdf86b103cbb20)
+++ src/routes/audio.js	(revision a5caa7318c74f3934365116bbc01979a35645972)
@@ -147,4 +147,10 @@
   res.setHeader('Content-Type', mime);
   res.setHeader('Accept-Ranges', 'bytes');
+  // Same lesson /media already learned: Helmet's default CORP is same-origin,
+  // and the browser then refuses to hand a cross-origin <audio> the bytes —
+  // the file arrives, the player stays silent. These URLs are precisely what
+  // we advertise in federated Audio objects (Funkwhale, the hub) to be played
+  // elsewhere; WHO may fetch is decided by the gate above, not by CORP.
+  res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
   // Allow the browser to cache the file for a day so play/pause/replay
   // doesn't re-fetch the whole stream every time. `private` keeps it out of
