benecaster_episode_audio_url
Filters the audio file URL wherever Benecaster resolves one. It fires in four places.
The front-end player and episode page. $tier_slug is null — there is no tier in scope here. Every call passes all three arguments, the website passing an explicit null, so a callback declaring three parameters never throws ArgumentCountError. null means the website; a string means a feed or a tracked download. [benecaster_player] makes the same call, and so does [benecaster_episodes] for each list item the visitor can play. Benecaster registers its own callback at priority 10 (Episode\PreviewClipPlayer): on a locked web render it swaps in the episode’s preview clip, and it passes every call carrying a tier slug through untouched. A callback registered at priority > 10 runs after it and wins.
Each feed item, immediately before benecaster_feed_enclosure_url, carrying the tier slug of the feed being compiled.
Each channel-level <podcast:trailer>, carrying that trailer episode’s ID — so a channel tag advertising an episode’s media cannot bypass a rewrite the item respects.
A tracked download’s redirect target (Analytics\DownloadProxy). When download tracking is on and the app follows a token feed’s /benecaster-download/{id}/?token=… enclosure, the proxy runs this filter on the 302 target with three arguments. $tier_slug is the tier the media was resolved at: the token’s snapshot tier, or public for a follower — always a string, so a download is feed context and PreviewClipPlayer’s clip swap never fires here. The URL is the file the feed lists for that tier: its audio variant when it has one, on a video episode too, otherwise the episode’s base file, which on a video episode is the video. The call lands after the per-tier variant cascade and before two things: the show’s Enclosure URL prefix, which wraps whatever your callback returns, and the download-log write — return '' to refuse the download, which gives the app a 404 and writes no benecaster_download_log row, the same as a missing file. benecaster_feed_enclosure_url does not run on this redirect: Benecaster’s ProxyUrlRewriter is on that filter and would hand back the proxy’s own URL, looping the download.
On the website $url is already the viewer’s tier variant. Benecaster picks it the way the viewer’s feed does: their tier if the episode’s date for it has passed, then their buy-ups and standalone grants, else the public file, through the same cascade the feed uses. Only a viewer who can play the episode gets a variant; a locked viewer whose player a callback opened gets the base file, which the preview-clip swap then replaces. A signed-out visitor holding an episode magic link hears that subscriber’s variant. One difference from the feed: a subscriber over their plan’s limit is not moved to the public file on the website. $tier_slug stays null on the website even so, because null is how a callback tells the website from a feed; the variant reaches you as $url. To get the same URL in your own template, call benecaster_get_episode_audio_url().
Use this when you want the same rewrite everywhere — player, feed, and tracked downloads alike. Use benecaster_feed_enclosure_url instead when you want to change only what goes in the feed, and leave the on-site player untouched.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
$url |
string |
— | The audio URL |
$episode_id |
int |
— | ID of the episode |
$tier_slug |
string|null |
— | The tier being served in a feed or tracked download; null on the website (the player, archive cards, [benecaster_player]) |
Returns:
string
Example
add_filter( 'benecaster_episode_audio_url', function( $url, $episode_id, $tier_slug = '' ) {
// Serve audio through a CDN subdomain, on the player and in the feed.
return str_replace( 'https://files.example.com/', 'https://cdn.example.com/', $url );
}, 10, 3 );
Affects
- Episode page player
Need this built rather than just documented? See our services →