Gemini Argon is expensive (it can eat your 5-hour quota in 3-5 questions if you throw lots of code at it), but it can also teach you about workarounds you never knew existed! And when you don’t know what you don’t know, well, you’re clueless and ignorant.

The story goes this way. My recently revamped set of radio players includes, alongside the main one that currently features 512 streams, a smaller one labeled “ROMÂNIA” and a 1-stream one that plays CGTN Radio (formerly China Radio International). The “Romanian” one was meant to include a small set of Romanian stations, with streams corresponding to what’s broadcast on FM.

Now, this isn’t entirely consistent. For instance, streams 14-16 and 28-30 don’t have an FM equivalent (note that Romania is medieval and abandoned the plan to introduce DAB+). And it’s not entirely sensible either. The radio stations at numbers 11, 18, 23, and 31 (Magic FM, EBS Radio Cluj, Rock FM, and Radio Clasic FM Romania) have specialized streams that are much more valuable and have fewer ads than the main ones. You can find them in the main player at 417-426, 369-381, 428-431, and 494-512, respectively.

But I can use this player for experiments. I can add Romanian radio stations that seem to broadcast mostly good music without polluting the main player, which already has several Romanian stations. And this is the latest experiment.

Someone (an intellectual) recommended on FB a local radio station, Metronom 89 FM from Râmnicu Vâlcea, so I added it at the end of the list.

There is an issue with this station, though. Its web page plays an HTTPS stream: https://metronom-fm.ro/stream. This stream sometimes fails, unfortunately. There is a secondary stream that is much more resilient, but someone was retarded enough to keep it on HTTP and HTTP only: http://metronom-fm.ro:8000/stream.ogg. And non-SSL streams don’t play in my player (mixed content, you know), although they would play if pasted directly into a browser’s address bar.

A couple of hours ago, the HTTPS stream failed. As I’m writing this, it’s back again, but the HTTP stream has never failed in my experience! You can check the Icecast status and see that the average number of listeners to this stream is less than 20, with a peak of 40. So I wanted to use the HTTP stream instead of the “modern” one.

Ten minutes later, I had a fix from Gemini Argon. I needed to use my free Cloudflare account and create a worker: Workers & Pages → Create application → Start with Hello World! → name and deploy the worker → Edit code → paste the script → Deploy. Here’s the script:

export default {
  async fetch(request) {
    const url = new URL(request.url);
    const streams = {
      "metronom": "http://metronom-fm.ro:8000/stream.ogg"
    };

    const station = url.searchParams.get("s");
    if (!streams[station]) {
      return new Response("Not Found", { status: 404 });
    }

    const response = await fetch(streams[station], {
      headers: { "User-Agent": "Mozilla/5.0" }
    });

    return new Response(response.body, {
      status: response.status,
      headers: {
        "Content-Type": response.headers.get("Content-Type") || "audio/ogg",
        "Cache-Control": "no-cache, no-store",
        "Access-Control-Allow-Origin": "*"
      }
    });
  }
};

Using it requires appending the name of the stream like this: https://<name-of-worker>.<name-of-account>.workers.dev/?s=metronom.

That was the initial version of the worker, but it needed improvements because the “Now playing” info stopped working. This is a version that works as required:

export default {
  async fetch(request) {
    const url = new URL(request.url);
    
    // 1. If metadata.php asks for Icecast status-json.xsl or stats, proxy it!
    if (url.pathname.endsWith("/status-json.xsl")) {
      const resp = await fetch("http://metronom-fm.ro:8000/status-json.xsl", {
        headers: { "User-Agent": "Mozilla/5.0" }
      });
      return new Response(resp.body, {
        status: resp.status,
        headers: {
          "Content-Type": "application/json",
          "Access-Control-Allow-Origin": "*"
        }
      });
    }

    const streams = {
      "metronom": "http://metronom-fm.ro:8000/stream.ogg"
    };
    
    const station = url.searchParams.get("s");
    if (!streams[station]) {
      return new Response("Not Found", { status: 404 });
    }

    // 2. If metadata.php connects to the stream URL directly with "Icy-MetaData: 1",
    // fetch the current song from Icecast JSON and synthesize a fake ICY response!
    if (request.headers.get("Icy-MetaData") === "1") {
      try {
        const metaResp = await fetch("http://metronom-fm.ro:8000/status-json.xsl");
        const data = await metaResp.json();
        let sources = data.icestats.source;
        if (!Array.isArray(sources)) sources = [sources];
        
        // Find the /stream.ogg mountpoint (or fallback to first active source)
        const mount = sources.find(s => s.listenurl && s.listenurl.includes("stream.ogg")) || sources[0];
        const title = (mount && mount.title) ? mount.title : "";

        // Build a synthetic ICY stream block with metaint = 1 byte
        const metaString = `StreamTitle='${title}';`;
        const metaLength = Math.ceil(metaString.length / 16);
        const paddedMeta = metaString.padEnd(metaLength * 16, "\0");
        
        const payload = new Uint8Array(1 + 1 + paddedMeta.length);
        payload[0] = 0x00; // 1 dummy audio byte
        payload[1] = metaLength; // ICY length byte (in 16-byte chunks)
        for (let i = 0; i < paddedMeta.length; i++) {
          payload[2 + i] = paddedMeta.charCodeAt(i) & 0xff;
        }

        return new Response(payload, {
          status: 200,
          headers: {
            "Content-Type": "audio/ogg",
            "icy-metaint": "1",
            "Access-Control-Allow-Origin": "*"
          }
        });
      } catch (e) {
        // Fall through to normal stream if JSON parse fails
      }
    }

    // 3. Normal browser audio playback: stream the Ogg audio directly
    const response = await fetch(streams[station], {
      headers: { "User-Agent": "Mozilla/5.0" }
    });

    return new Response(response.body, {
      status: response.status,
      headers: {
        "Content-Type": response.headers.get("Content-Type") || "audio/ogg",
        "Cache-Control": "no-cache, no-store",
        "Access-Control-Allow-Origin": "*"
      }
    });
  }
};

Now, the question is: how can this proxy service be free? So, basically, Cloudflare offers a free proxy with no limits?

Gemini answered:

There is no hard bandwidth (data transfer) limit on Cloudflare Workers, and you will never receive a surprise bill because the Free tier doesn’t even ask for a credit card, though there are specific execution limits that govern how it operates:

  • 100,000 Requests per Day: Every time you (or a visitor) click “Play” or the player reconnects to the stream, that counts as 1 request (resetting daily at 00:00 UTC). Once the HTTP connection is established, the continuous audio stream flows inside that single request.
  • 10 ms CPU Time per Request (Not Wall-Clock Time): This is the catch that makes audio streaming possible. Cloudflare measures actual processor cycles spent executing your JavaScript, not how long the HTTP connection stays open. Because new Response(response.body, ...) hands the readable stream directly to Cloudflare’s underlying network runtime without inspecting or modifying the bytes in JS, a 2-hour listening session only consumes about 1–2 milliseconds of actual CPU time.
  • Idle & Isolate Eviction: A single continuous HTTP connection through a Worker won’t stay open forever. Cloudflare periodically recycles Worker isolates or drops very long-lived connections (typically after a few hours, or if the upstream radio server hiccups). When that happens, your browser’s <audio> element simply reconnects, using 1 more request out of your 100,000 daily quota.
  • Terms of Service Nuance: Cloudflare’s ToS prohibits using their free CDN/Workers to run a massive commercial video/audio distribution network (like hosting a pirate IPTV relay for thousands of people). For a personal or low-traffic radio player relaying a lightweight ~128 kbps .ogg stream, your bandwidth usage is a rounding error on their network and stays completely under the radar.

Because we hardcoded the $streams dictionary (const streams = { "metronom": ... }) in your script rather than accepting an arbitrary ?url= parameter, nobody else on the internet can hijack your Worker as an open proxy to eat up your 100,000 daily requests.

So there.