diff options
| author | jade (winter) | 2026-07-19 17:51:11 +0100 |
|---|---|---|
| committer | jade (winter) | 2026-07-19 17:51:11 +0100 |
| commit | 5f301e85b24f3a219c3020a8e24113c31a2a1058 (patch) | |
| tree | f0b15a1dc34af78270718fabf933d075ccd0d028 /lib | |
| parent | 92d27365cadbd98e6d709673cd0729de8793c494 (diff) | |
fix so much stuff + add hls player
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/bbcnext.php | 183 | ||||
| -rw-r--r-- | lib/mediaselector.php | 27 | ||||
| -rw-r--r-- | lib/rms.php | 2 |
3 files changed, 123 insertions, 89 deletions
diff --git a/lib/bbcnext.php b/lib/bbcnext.php index 988d248..ed58a4f 100644 --- a/lib/bbcnext.php +++ b/lib/bbcnext.php @@ -1,109 +1,116 @@ <?php require_once __DIR__ . '/rms.php'; +require_once __DIR__ . '/mediaselector.php'; function next_renderFromRms(string $path) { - next_renderExperience(rms_fetch($path)->data); + next_renderExperience(rms_fetch($path)->data); } function next_renderExperience(array $modules) { - foreach ($modules as $m) { - next_renderModule($m); - } + foreach ($modules as $m) { + next_renderModule($m); + } } function next_renderModule(stdClass $module) { - $type = strtr($module->type, '_', '-'); - $titleTag = $type == 'inline-header-module' ? 'h1' : 'h2'; - echo "<$type id=\"$module->id\" module-style=\"$module->style\">"; - echo "<$titleTag>" - . htmlspecialchars($module->title ?? '[no title]') - . "</$titleTag>"; - if (isset($module->description)) { - echo '<module-description>' - . htmlspecialchars($module->description) - . '</module-description>'; - } - echo '<module-items>'; - if (!is_array($module->data)) { - next_renderItem($module->data); - } else { - foreach ($module->data as $item) { - next_renderItem($item); - } - } - echo "</module-items></$type>"; + $type = strtr($module->type, '_', '-'); + $titleTag = $type == 'inline-header-module' ? 'h1' : 'h2'; + echo "<$type id=\"$module->id\" module-style=\"$module->style\">"; + echo "<$titleTag>" + . htmlspecialchars($module->title ?? '[no title]') + . "</$titleTag>"; + if (isset($module->description)) { + echo '<module-description>' + . htmlspecialchars($module->description) + . '</module-description>'; + } + echo '<module-items>'; + if (!is_array($module->data)) { + next_renderItem($module->data); + } else { + foreach ($module->data as $item) { + next_renderItem($item); + } + } + echo "</module-items>"; + if ($module->id == 'aod_play_area') { + $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>'; + } + echo "</$type>"; } function next_renderItem(stdClass $item) { - $type = strtr($item->type, '_', '-'); - $primaryTag = $type == 'segment-item' ? 'primary-title' : 'h3'; - echo "<$type id=\"$item->id\">"; - echo '<item-titles><item-first-titles>'; - echo "<$primaryTag>" - . htmlspecialchars($item->titles?->primary ?? '[no primary]') - . "</$primaryTag>"; - if (isset($item->network)) { - echo '<item-network>' - . htmlspecialchars($item->network->short_title) - . '</item-network>'; - } - echo '</item-first-titles>'; - if (isset($item->titles->secondary)) { - echo '<secondary-title>' - . htmlspecialchars($item->titles->secondary) - . '</secondary-title>'; - } - if (isset($item->titles->tertiary)) { - echo '<tertiary-title>' - . htmlspecialchars($item->titles->tertiary) - . '</tertiary-title>'; - } - echo '</item-titles>'; - if (isset($item->synopses?->short, $item->synopses?->medium)) { - echo '<synopsis><details><summary>' - . htmlspecialchars($item->synopses->short) - . '</summary>' - . htmlspecialchars($item->synopses->long ?? $item->synopses->medium) - . '</details></synopsis>'; - } elseif (isset($item->synopses?->short)) { - echo '<synopsis>' . htmlspecialchars($item->synopses->short) - . '</synopsis>'; - } + $type = strtr($item->type, '_', '-'); + $primaryTag = $type == 'segment-item' ? 'primary-title' : 'h3'; + echo "<$type id=\"$item->id\">"; + echo '<item-titles><item-first-titles>'; + echo "<$primaryTag>" + . htmlspecialchars($item->titles?->primary ?? '[no primary]') + . "</$primaryTag>"; + if (isset($item->network)) { + echo '<item-network>' + . htmlspecialchars($item->network->short_title) + . '</item-network>'; + } + echo '</item-first-titles>'; + if (isset($item->titles->secondary)) { + echo '<secondary-title>' + . htmlspecialchars($item->titles->secondary) + . '</secondary-title>'; + } + if (isset($item->titles->tertiary)) { + echo '<tertiary-title>' + . htmlspecialchars($item->titles->tertiary) + . '</tertiary-title>'; + } + echo '</item-titles>'; + if (isset($item->synopses?->short, $item->synopses?->medium)) { + echo '<synopsis><details><summary>' + . htmlspecialchars($item->synopses->short) + . '</summary>' + . htmlspecialchars($item->synopses->long ?? $item->synopses->medium) + . '</details></synopsis>'; + } elseif (isset($item->synopses?->short)) { + echo '<synopsis>' . htmlspecialchars($item->synopses->short) + . '</synopsis>'; + } - if (isset($item->item)) { - next_renderItem($item->item); - } + if (isset($item->item)) { + next_renderItem($item->item); + } - if (isset($item->offset)) { - echo '<offset-start>' - . gmdate('H:i:s', $item->offset->start) - . '</offset-start>'; - echo '<offset-end>' - . gmdate('H:i:s', $item->offset->end) - . '</offset-end>'; - } + if (isset($item->offset)) { + echo '<offset-start>' + . gmdate('H:i:s', $item->offset->start) + . '</offset-start>'; + echo '<offset-end>' + . gmdate('H:i:s', $item->offset->end) + . '</offset-end>'; + } - if ($type == 'container-item') { - $href = '?path=' . RMS_SOUNDS_CONTAINER . '/' . $item->urn; - echo "<a href=\"$href\">View</a>"; - } elseif ($type == 'playable-item') { - $pid = explode(':', $item->urn)[4]; - $href = '?path=' . RMS_SOUNDS_PLAYABLE . '/' . $pid; - echo "<a href=\"$href\">Listen</a>"; - } + if ($type == 'container-item') { + $href = '?path=' . RMS_SOUNDS_CONTAINER . '/' . $item->urn; + echo "<a href=\"$href\">View</a>"; + } elseif ($type == 'playable-item') { + $pid = explode(':', $item->urn)[4]; + $href = '?path=' . RMS_SOUNDS_PLAYABLE . '/' . $pid; + echo "<a href=\"$href\">Listen</a>"; + } - foreach ($item->uris ?? [] as $uri) { - if ($uri->type != 'link') continue; - echo '<a href="' . htmlspecialchars($uri->uri) . '" target="_blank">' - . htmlspecialchars($uri->label) . '</a>'; - } + foreach ($item->uris ?? [] as $uri) { + if ($uri->type != 'link') continue; + echo '<a href="' . htmlspecialchars($uri->uri) . '" target="_blank">' + . htmlspecialchars($uri->label) . '</a>'; + } - if (isset($item->download) && $item->download->type == 'non_drm') { - $variant = $item->download->quality_variants->high; - echo '<a href="' . htmlspecialchars($variant->file_url) . '">' - . "Download ($variant->label)</a>"; - } + if (isset($item->download) && $item->download->type == 'non_drm') { + $variant = $item->download->quality_variants->high; + echo '<a href="' . htmlspecialchars($variant->file_url) . '">' + . "Download ($variant->label)</a>"; + } - echo "</$type>"; + echo "</$type>"; } diff --git a/lib/mediaselector.php b/lib/mediaselector.php new file mode 100644 index 0000000..df19c8d --- /dev/null +++ b/lib/mediaselector.php @@ -0,0 +1,27 @@ +<?php + +const MEDIASELECTOR_BASE = 'https://open.live.bbc.co.uk/mediaselector/6/select'; + +function mediaselector_lookup(array $options): 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)); +} + +function mediaselector_findHls(string $vpid): ?string { + $resp = mediaselector_lookup([ + 'version' => '3.0', + 'proto' => 'https', + 'transferformat' => 'hls', + 'mediaset' => 'pc', + 'cvid' => "urn:bbc:pips:pid:$vpid", + ]); + if (isset($resp->result) && $resp->result == 'selectionunavailable') { + return null; + } + return $resp->media[0]->connection[0]->href; +} diff --git a/lib/rms.php b/lib/rms.php index 1e76d53..8b92e49 100644 --- a/lib/rms.php +++ b/lib/rms.php @@ -6,5 +6,5 @@ const RMS_SOUNDS_CONTAINER = '/experience/inline/container'; const RMS_SOUNDS_PLAYABLE = '/experience/inline/play'; function rms_fetch(string $path): stdClass { - return json_decode(file_get_contents(RMS_API_BASE . $path)); + return json_decode(file_get_contents(RMS_API_BASE . $path)); } |
