diff options
| author | jade (winter) | 2026-07-20 13:35:01 +0100 |
|---|---|---|
| committer | jade (winter) | 2026-07-20 13:35:01 +0100 |
| commit | d5ea0f332bf8e5f0745e2c0e592ee895423a70ad (patch) | |
| tree | 1649ba6a70b64623b5b1692359b4a70cb89970f1 /lib | |
| parent | 5f301e85b24f3a219c3020a8e24113c31a2a1058 (diff) | |
add live playback support
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/bbcnext.php | 20 | ||||
| -rw-r--r-- | lib/mediaselector.php | 20 | ||||
| -rw-r--r-- | lib/sounds-auth.php | 15 |
3 files changed, 50 insertions, 5 deletions
diff --git a/lib/bbcnext.php b/lib/bbcnext.php index ed58a4f..f4ad4ec 100644 --- a/lib/bbcnext.php +++ b/lib/bbcnext.php @@ -3,8 +3,22 @@ require_once __DIR__ . '/rms.php'; require_once __DIR__ . '/mediaselector.php'; +const INCLUDE_RMS_DATA = false; + function next_renderFromRms(string $path) { - next_renderExperience(rms_fetch($path)->data); + $resp = rms_fetch($path); + try { + next_renderExperience($resp->data); + } catch (Exception|TypeError $e) { + echo '<exception>' + . htmlspecialchars($e->getMessage()) + . '</exception>'; + } + if (INCLUDE_RMS_DATA) { + echo '<details><summary>Raw data from RMS</summary><pre>'; + echo json_encode($resp, JSON_PRETTY_PRINT); + echo '</pre></details>'; + } } function next_renderExperience(array $modules) { @@ -38,6 +52,10 @@ function next_renderModule(stdClass $module) { $url = mediaselector_findHls($module->data[0]->id); echo '<audio controls hidden id="hls-player" data-hls="' . $url . '" />'; echo '<script src="static/hls-player.js" defer></script>'; + } elseif ($module->id == 'live_play_area') { + $url = mediaselector_findLiveHls($module->data[0]->service_id); + echo '<audio controls hidden id="hls-player" data-hls="' . $url . '" />'; + echo '<script src="static/hls-player.js" defer></script>'; } echo "</$type>"; } diff --git a/lib/mediaselector.php b/lib/mediaselector.php index df19c8d..2adaf71 100644 --- a/lib/mediaselector.php +++ b/lib/mediaselector.php @@ -1,27 +1,39 @@ <?php +require_once __DIR__ . '/sounds-auth.php'; + const MEDIASELECTOR_BASE = 'https://open.live.bbc.co.uk/mediaselector/6/select'; -function mediaselector_lookup(array $options): stdClass { +function mediaselector_lookup(array $options, ?string $token = null): stdClass { // ['version' => '3.0', 'cvid' => 'urn:bbc:pips:pid:...'] $url = MEDIASELECTOR_BASE; $options['format'] = 'json'; foreach ($options as $k => $v) { $url .= "/$k/$v"; } - return json_decode(file_get_contents($url)); + $ctx = stream_context_get_default(); + if (isset($token)) { + stream_context_set_option($ctx, 'http', + 'header', "Authorization: Bearer $token"); + } + return json_decode(file_get_contents($url, context: $ctx)); } -function mediaselector_findHls(string $vpid): ?string { +function mediaselector_findHls(string $vpid, ?string $token = null): ?string { $resp = mediaselector_lookup([ 'version' => '3.0', 'proto' => 'https', 'transferformat' => 'hls', 'mediaset' => 'pc', 'cvid' => "urn:bbc:pips:pid:$vpid", - ]); + ], $token); if (isset($resp->result) && $resp->result == 'selectionunavailable') { return null; } return $resp->media[0]->connection[0]->href; } + +function mediaselector_findLiveHls(string $service): ?string { + $jwt = sounds_getLiveBearerToken($service); + return mediaselector_findHls($service, $jwt); +} diff --git a/lib/sounds-auth.php b/lib/sounds-auth.php new file mode 100644 index 0000000..91e2599 --- /dev/null +++ b/lib/sounds-auth.php @@ -0,0 +1,15 @@ +<?php + +// where does 1d590d3 come from? i have no clue +const SOUNDS_NEXT_DATA_BASE = 'https://www.bbc.co.uk/sounds/_next/data/1d590d3'; +const SOUNDS_NEXT_DATA_LIVE = '/play/live/{service}.json'; + +function sounds_fetchPageData(string $path) { + return json_decode(file_get_contents(SOUNDS_NEXT_DATA_BASE . $path)); +} + +function sounds_getLiveBearerToken(string $service) { + return sounds_fetchPageData( + str_replace('{service}', $service, SOUNDS_NEXT_DATA_LIVE) + )->pageProps->jwtToken; +} |
