Skip to main content

Swap the audio enclosure URL per subscriber tier at feed compile time

Premium Intermediate

Benecaster picks the audio URL for a given subscriber tier in three steps: it looks for a variant matching that tier exactly, then cascades down to broader tiers, and finally falls back to the episode’s base URL.

The benecaster_episode_audio_url filter runs after that choice is made, so an add-on can override the result per request — geo-routing, per-listener CDN tokens, dynamic ad insertion, and similar.

Give the parameter a ?string $tier_slug = null default — the website always passes an explicit null there, and null is how you tell a player call apart from a feed or tracked-download call.

The filter fires once per episode/tier pair while a feed compiles, and again on a tracked download’s redirect target (Analytics\DownloadProxy) — there $tier_slug is always a string (the token’s snapshot tier, or public for a follower), so this same callback also reaches downloads without any extra wiring. Whatever your callback returns in that context becomes the redirect target, not the enclosure URL verbatim — it still passes through the show’s Enclosure URL prefix afterward, and download tracking logs the request only once the filter returns a non-empty string. A signed CDN URL used here should carry a short TTL: a tracked download is a one-time redirect, not a cached feed entry, so there’s no benefit to a long-lived signature.

Code

<?php
add_filter(
    'benecaster_episode_audio_url',
    function ( string $url, int $episode_id, ?string $tier_slug = null ): string {
        // Web player call — no tier in scope, leave it alone.
        if ( null === $tier_slug ) {
            return $url;
        }
        // Feed and tracked-download calls: route paid tiers through a signed-URL CDN;
        // leave the public/free audio alone.
        if ( in_array( $tier_slug, [ 'public', 'free' ], true ) ) {
            return $url;
        }
        return my_addon_sign_cdn_url( $url, [ 'ttl' => 900 ] );
    },
    10,
    3
);

View on GitHub →

Hooks Used

Need this built rather than just documented? See our services →