chore: Run `deno fmt`
Signed-off-by: Tim Hårek Andreassen <tim@harek.no>
This commit is contained in:
parent
f9a97b627b
commit
047ceec147
|
|
@ -3,16 +3,19 @@
|
|||
https://nrss.deno.dev/
|
||||
|
||||
## Local devlopment
|
||||
|
||||
install Deno
|
||||
https://deno.land/manual/getting_started/installation
|
||||
|
||||
### Run the application
|
||||
``` shell
|
||||
|
||||
```shell
|
||||
deno task start
|
||||
```
|
||||
|
||||
Open http://localhost:8000/ to view it in the browser
|
||||
|
||||
|
||||
## Known Problems
|
||||
|
||||
- Some clients may not accept a feed hosted over HTTPS only. See @steinarb's workaround [here](https://github.com/olaven/NRSS/issues/5#issuecomment-1488840679) for a possible solution.
|
||||
- The feeds only provide the latest episodes for a podcast, not the entire archive. I've not yet found any acceptable method of fetching all episodes without getting rate limited by NRK or introducing a storage layer. This is tracked in https://github.com/olaven/NRSS/issues/8.
|
||||
|
|
|
|||
|
|
@ -2,8 +2,16 @@ export default function Search(props: { defaultValue: string }) {
|
|||
return (
|
||||
<form className="flex flex-col w-full lg:w-2/3 mx-auto my-4">
|
||||
<label className="sr-only" htmlFor="query">Program</label>
|
||||
<input placeholder="NRK-podcast" className="border-2 rounded-md px-2" name="query" id="query" defaultValue={props.defaultValue} />
|
||||
<button type="submit" className="my-2 bg-gray-100 rounded-md">Søk</button>
|
||||
<input
|
||||
placeholder="NRK-podcast"
|
||||
className="border-2 rounded-md px-2"
|
||||
name="query"
|
||||
id="query"
|
||||
defaultValue={props.defaultValue}
|
||||
/>
|
||||
<button type="submit" className="my-2 bg-gray-100 rounded-md">
|
||||
Søk
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { SearchResult } from "../lib/nrk.ts"
|
||||
import { SearchResult } from "../lib/nrk.ts";
|
||||
import CopyButton from "../islands/CopyButton.tsx";
|
||||
|
||||
export function SerieCard(props: { serie: SearchResult, origin: string }) {
|
||||
export function SerieCard(props: { serie: SearchResult; origin: string }) {
|
||||
const feedUrl = new URL(`/api/feeds/${props.serie.seriesId}`, props.origin);
|
||||
const image = props.serie.images[0];
|
||||
return (
|
||||
|
|
@ -14,6 +14,6 @@ export function SerieCard(props: { serie: SearchResult, origin: string }) {
|
|||
Kopier URL
|
||||
</CopyButton>
|
||||
</div>
|
||||
</div >
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"lock": false,
|
||||
"tasks": {
|
||||
"start": "deno run -A --watch=static/,routes/ dev.ts"
|
||||
"start": "deno run -A --watch=static/,routes/ dev.ts",
|
||||
"check": "deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx"
|
||||
},
|
||||
"imports": {
|
||||
"$fresh/": "https://deno.land/x/fresh@1.6.5/",
|
||||
|
|
@ -22,8 +23,8 @@
|
|||
"output"
|
||||
],
|
||||
"useTabs": false,
|
||||
"lineWidth": 80,
|
||||
"indentWidth": 4,
|
||||
"lineWidth": 120,
|
||||
"indentWidth": 2,
|
||||
"proseWrap": "preserve"
|
||||
}
|
||||
}
|
||||
23
fresh.gen.ts
23
fresh.gen.ts
|
|
@ -1,24 +1,23 @@
|
|||
// DO NOT EDIT. This file is generated by fresh.
|
||||
// DO NOT EDIT. This file is generated by Fresh.
|
||||
// This file SHOULD be checked into source version control.
|
||||
// This file is automatically updated during development when running `dev.ts`.
|
||||
|
||||
import config from "./deno.json" assert { type: "json" };
|
||||
import * as $0 from "./routes/api/feeds/[seriesId].ts";
|
||||
import * as $1 from "./routes/api/feeds/[seriesId]/[episodeId]/chapters.ts";
|
||||
import * as $2 from "./routes/index.tsx";
|
||||
import * as $$0 from "./islands/CopyButton.tsx";
|
||||
import * as $api_feeds_seriesId_ from "./routes/api/feeds/[seriesId].ts";
|
||||
import * as $api_feeds_seriesId_episodeId_chapters from "./routes/api/feeds/[seriesId]/[episodeId]/chapters.ts";
|
||||
import * as $index from "./routes/index.tsx";
|
||||
import * as $CopyButton from "./islands/CopyButton.tsx";
|
||||
import { type Manifest } from "$fresh/server.ts";
|
||||
|
||||
const manifest = {
|
||||
routes: {
|
||||
"./routes/api/feeds/[seriesId].ts": $0,
|
||||
"./routes/api/feeds/[seriesId]/[episodeId]/chapters.ts": $1,
|
||||
"./routes/index.tsx": $2,
|
||||
"./routes/api/feeds/[seriesId].ts": $api_feeds_seriesId_,
|
||||
"./routes/api/feeds/[seriesId]/[episodeId]/chapters.ts": $api_feeds_seriesId_episodeId_chapters,
|
||||
"./routes/index.tsx": $index,
|
||||
},
|
||||
islands: {
|
||||
"./islands/CopyButton.tsx": $$0,
|
||||
"./islands/CopyButton.tsx": $CopyButton,
|
||||
},
|
||||
baseUrl: import.meta.url,
|
||||
config,
|
||||
};
|
||||
} satisfies Manifest;
|
||||
|
||||
export default manifest;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
import Preact from "preact";
|
||||
import { useState } from "preact/hooks"
|
||||
import { useState } from "preact/hooks";
|
||||
import { IS_BROWSER } from "$fresh/runtime.ts";
|
||||
|
||||
export default function CopyButton(props: { textBefore: string, textAfter: string } & Preact.PropsWithChildren) {
|
||||
|
||||
export default function CopyButton(
|
||||
props: { textBefore: string; textAfter: string } & Preact.PropsWithChildren,
|
||||
) {
|
||||
const [clicked, setClicked] = useState(false);
|
||||
|
||||
const startReset = () => {
|
||||
setTimeout(() => {
|
||||
setClicked(false);
|
||||
}, 2_000);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -508,7 +508,9 @@ export interface components {
|
|||
/** @description Aggregated info for clips */
|
||||
ExtraMaterialClipsHalEmbedded: {
|
||||
metadata?: {
|
||||
displayAspectRatio: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DisplayAspectRatio"];
|
||||
displayAspectRatio: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["DisplayAspectRatio"];
|
||||
/**
|
||||
* @description Clip length. The string is formatted as https://en.wikipedia.org/wiki/ISO_8601#Durations
|
||||
* @example PT2M0S
|
||||
|
|
@ -517,7 +519,9 @@ export interface components {
|
|||
id: string;
|
||||
/** @enum {undefined} */
|
||||
playability: "nonPlayable" | "playable";
|
||||
preplay: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PreplayVm"];
|
||||
preplay: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PreplayVm"];
|
||||
/** @description Link to full metadata */
|
||||
_links: {
|
||||
self: components["schemas"]["HalLink"];
|
||||
|
|
@ -886,36 +890,56 @@ export interface external {
|
|||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json": {
|
||||
paths: {
|
||||
"/playback/debug": {
|
||||
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackDebug"];
|
||||
get: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["operations"]["getPlaybackDebug"];
|
||||
};
|
||||
"/playback/dnslist": {
|
||||
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackDnsList"];
|
||||
get: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["operations"]["getPlaybackDnsList"];
|
||||
};
|
||||
"/playback/manifest/{id}": {
|
||||
/** This endpoint is just for clients that doesn't know its context */
|
||||
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackManifestRedirect"];
|
||||
get: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["operations"]["getPlaybackManifestRedirect"];
|
||||
};
|
||||
"/playback/manifest/program/{programId}": {
|
||||
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackProgramManifest"];
|
||||
get: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["operations"]["getPlaybackProgramManifest"];
|
||||
};
|
||||
"/playback/manifest/channel/{channelId}": {
|
||||
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackChannelManifest"];
|
||||
get: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["operations"]["getPlaybackChannelManifest"];
|
||||
};
|
||||
"/playback/manifest/clip/{clipId}": {
|
||||
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackClipManifest"];
|
||||
get: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["operations"]["getPlaybackClipManifest"];
|
||||
};
|
||||
"/playback/metadata/{id}": {
|
||||
/** This endpoint is just for clients that doesn't know its context */
|
||||
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackMetadataRedirect"];
|
||||
get: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["operations"]["getPlaybackMetadataRedirect"];
|
||||
};
|
||||
"/playback/metadata/program/{programId}": {
|
||||
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackProgramMetadata"];
|
||||
get: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["operations"]["getPlaybackProgramMetadata"];
|
||||
};
|
||||
"/playback/metadata/channel/{channelId}": {
|
||||
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackChannelMetadata"];
|
||||
get: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["operations"]["getPlaybackChannelMetadata"];
|
||||
};
|
||||
"/playback/metadata/clip/{clipId}": {
|
||||
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackClipMetadata"];
|
||||
get: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["operations"]["getPlaybackClipMetadata"];
|
||||
};
|
||||
};
|
||||
components: {
|
||||
|
|
@ -935,8 +959,12 @@ export interface external {
|
|||
href: string;
|
||||
};
|
||||
};
|
||||
playbackData: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlaybackDataVm"];
|
||||
locationData: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LocationDataVm"];
|
||||
playbackData: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlaybackDataVm"];
|
||||
locationData: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["LocationDataVm"];
|
||||
};
|
||||
PlaybackDataVm: {
|
||||
maxBitrate: number;
|
||||
|
|
@ -951,9 +979,15 @@ export interface external {
|
|||
isBeta: boolean;
|
||||
originalUa: string;
|
||||
wurflId: string | null;
|
||||
distributionFormat: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DistributionFormat"];
|
||||
deviceGroupName: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DeviceGroupName"];
|
||||
playerPlatform: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayerPlatform"];
|
||||
distributionFormat: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["DistributionFormat"];
|
||||
deviceGroupName: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["DeviceGroupName"];
|
||||
playerPlatform: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayerPlatform"];
|
||||
customManifestParameters: (
|
||||
| "AudioOnly"
|
||||
| "DolbyOnly"
|
||||
|
|
@ -965,7 +999,9 @@ export interface external {
|
|||
| "NoSignalDiscontinuities"
|
||||
| "SignalDiscontinuities"
|
||||
)[];
|
||||
subtitlesDistribution: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SubtitlesDistribution"];
|
||||
subtitlesDistribution: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["SubtitlesDistribution"];
|
||||
};
|
||||
/** @enum {string} */
|
||||
DistributionFormat:
|
||||
|
|
@ -975,7 +1011,12 @@ export interface external {
|
|||
| "ProgressiveDownload"
|
||||
| "ProgressiveMp3";
|
||||
/** @enum {string} */
|
||||
DeviceGroupName: "Desktop" | "Mobile" | "SetTopUnit" | "Tablet" | "Tv";
|
||||
DeviceGroupName:
|
||||
| "Desktop"
|
||||
| "Mobile"
|
||||
| "SetTopUnit"
|
||||
| "Tablet"
|
||||
| "Tv";
|
||||
/** @enum {string} */
|
||||
PlayerPlatform:
|
||||
| "Altibox"
|
||||
|
|
@ -1021,28 +1062,51 @@ export interface external {
|
|||
forwardedFor: string;
|
||||
realIp: string;
|
||||
};
|
||||
ManifestResponse: Partial<
|
||||
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableManifest"]
|
||||
> &
|
||||
Partial<
|
||||
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NonPlayableManifest"]
|
||||
ManifestResponse:
|
||||
& Partial<
|
||||
external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableManifest"]
|
||||
>
|
||||
& Partial<
|
||||
external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["NonPlayableManifest"]
|
||||
>;
|
||||
PlayableManifest: {
|
||||
/** @enum {string} */
|
||||
playability: "playable";
|
||||
playable: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableElementVm"];
|
||||
playable: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableElementVm"];
|
||||
statistics: {
|
||||
scores: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ScoresStatisticsVm"];
|
||||
ga: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["GoogleAnalyticsVm"];
|
||||
conviva: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ConvivaStatisticsVm"];
|
||||
luna: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LunaStatisticsVm"];
|
||||
scores: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["ScoresStatisticsVm"];
|
||||
ga: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["GoogleAnalyticsVm"];
|
||||
conviva: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["ConvivaStatisticsVm"];
|
||||
luna: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["LunaStatisticsVm"];
|
||||
};
|
||||
nonPlayable: unknown | null;
|
||||
id: string;
|
||||
streamingMode: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableStreamingMode"];
|
||||
availability: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["AvailabilityVm"];
|
||||
displayAspectRatio: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DisplayAspectRatio"];
|
||||
sourceMedium: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableSourceMedium"];
|
||||
streamingMode: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableStreamingMode"];
|
||||
availability: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["AvailabilityVm"];
|
||||
displayAspectRatio: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["DisplayAspectRatio"];
|
||||
sourceMedium: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableSourceMedium"];
|
||||
_links: {
|
||||
self: {
|
||||
href: string;
|
||||
|
|
@ -1063,12 +1127,22 @@ export interface external {
|
|||
ga: unknown | null;
|
||||
luna: unknown | null;
|
||||
};
|
||||
nonPlayable: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NonPlayableElementVm"];
|
||||
nonPlayable: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["NonPlayableElementVm"];
|
||||
id: string;
|
||||
streamingMode: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableStreamingMode"];
|
||||
availability: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["AvailabilityVm"];
|
||||
displayAspectRatio: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DisplayAspectRatio"];
|
||||
sourceMedium: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableSourceMedium"];
|
||||
streamingMode: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableStreamingMode"];
|
||||
availability: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["AvailabilityVm"];
|
||||
displayAspectRatio: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["DisplayAspectRatio"];
|
||||
sourceMedium: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableSourceMedium"];
|
||||
_links: {
|
||||
self: {
|
||||
href: string;
|
||||
|
|
@ -1084,19 +1158,31 @@ export interface external {
|
|||
endSequenceStartTime: string | null;
|
||||
duration: string | null;
|
||||
/** @description List of mediaAssets */
|
||||
assets: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["MediaUrlVm"][];
|
||||
assets: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["MediaUrlVm"][];
|
||||
/** @description Livebuffer if element is live */
|
||||
liveBuffer: Partial<
|
||||
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LiveBufferVm"]
|
||||
> | null;
|
||||
liveBuffer:
|
||||
| Partial<
|
||||
external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["LiveBufferVm"]
|
||||
>
|
||||
| null;
|
||||
/** @description List of subtitles */
|
||||
subtitles: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SubtitlesVm"][];
|
||||
subtitles: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["SubtitlesVm"][];
|
||||
};
|
||||
MediaUrlVm: {
|
||||
/** @description The media URL itself. */
|
||||
url: string;
|
||||
format: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableFormat"];
|
||||
mimeType: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableMimeType"];
|
||||
format: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableFormat"];
|
||||
mimeType: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableMimeType"];
|
||||
/** @description True if program is marked as HDSecure, false otherwise */
|
||||
encrypted: boolean;
|
||||
};
|
||||
|
|
@ -1120,7 +1206,9 @@ export interface external {
|
|||
bufferStartTime: string | null;
|
||||
/** @description Live buffer length */
|
||||
bufferDuration: string;
|
||||
bufferType: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LiveBufferType"];
|
||||
bufferType: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["LiveBufferType"];
|
||||
};
|
||||
/**
|
||||
* @description Type of liveBuffer
|
||||
|
|
@ -1128,9 +1216,15 @@ export interface external {
|
|||
*/
|
||||
LiveBufferType: "fixed" | "growing" | "none" | "sliding";
|
||||
SubtitlesVm: {
|
||||
type: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SubtitleType"];
|
||||
language: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SubtitleLanguage"];
|
||||
label: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SubtitleLabel"];
|
||||
type: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["SubtitleType"];
|
||||
language: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["SubtitleLanguage"];
|
||||
label: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["SubtitleLabel"];
|
||||
defaultOn: boolean;
|
||||
webVtt: string;
|
||||
};
|
||||
|
|
@ -1139,7 +1233,10 @@ export interface external {
|
|||
/** @enum {string} */
|
||||
SubtitleLanguage: "en" | "nb";
|
||||
/** @enum {string} */
|
||||
SubtitleLabel: "English" | "Norsk tekst" | "Tekstet for hørselshemmede";
|
||||
SubtitleLabel:
|
||||
| "English"
|
||||
| "Norsk tekst"
|
||||
| "Tekstet for hørselshemmede";
|
||||
ScoresStatisticsVm: {
|
||||
springStreamSite: string;
|
||||
springStreamStream: string;
|
||||
|
|
@ -1178,14 +1275,18 @@ export interface external {
|
|||
* When duration is unknown, eg channels: -1
|
||||
*/
|
||||
duration: number;
|
||||
streamType: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ConvivaStreamType"];
|
||||
streamType: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["ConvivaStreamType"];
|
||||
/**
|
||||
* @description The URL from where this video content will be downloaded. For
|
||||
* manifest-based streaming protocols, it should be the URL of the top-level
|
||||
* manifest.
|
||||
*/
|
||||
streamUrl: string;
|
||||
custom: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ConvivaCustomProperties"];
|
||||
custom: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["ConvivaCustomProperties"];
|
||||
};
|
||||
/** @enum {string} */
|
||||
ConvivaStreamType: "LIVE" | "VOD";
|
||||
|
|
@ -1221,7 +1322,9 @@ export interface external {
|
|||
* Example: underholdning
|
||||
*/
|
||||
category: string;
|
||||
mediaType: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ConvivaMediaType"];
|
||||
mediaType: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["ConvivaMediaType"];
|
||||
/**
|
||||
* @description Name of selected CDN
|
||||
* Example: Telenor-Cdn
|
||||
|
|
@ -1239,7 +1342,9 @@ export interface external {
|
|||
* Example: tv.nrk.no, nrk.no, nrksuper.no
|
||||
*/
|
||||
serviceName: string;
|
||||
contentType: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ConvivaContentType"];
|
||||
contentType: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["ConvivaContentType"];
|
||||
};
|
||||
/**
|
||||
* @description MediaType for current content
|
||||
|
|
@ -1257,8 +1362,12 @@ export interface external {
|
|||
| "Podcast"
|
||||
| "Program";
|
||||
LunaStatisticsVm: {
|
||||
config: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LunaConfig"];
|
||||
data: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LunaPayload"];
|
||||
config: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["LunaConfig"];
|
||||
data: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["LunaPayload"];
|
||||
};
|
||||
LunaConfig: {
|
||||
beacon: string;
|
||||
|
|
@ -1288,27 +1397,37 @@ export interface external {
|
|||
* @description Only applicable for on-demand media elements. Will be null for live media
|
||||
* elements.
|
||||
*/
|
||||
onDemand: Partial<
|
||||
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["OnDemandUsageRights"]
|
||||
> | null;
|
||||
onDemand:
|
||||
| Partial<
|
||||
external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["OnDemandUsageRights"]
|
||||
>
|
||||
| null;
|
||||
/**
|
||||
* @description Only applicable for live media elements. Will be null for on-demand media
|
||||
* elements.
|
||||
*/
|
||||
live:
|
||||
| (Partial<{
|
||||
| (
|
||||
& Partial<{
|
||||
/** @enum {string} */
|
||||
type: "channel";
|
||||
/** @enum {boolean} */
|
||||
isOngoing: true;
|
||||
transmissionInterval: unknown | null;
|
||||
}> &
|
||||
Partial<{
|
||||
}>
|
||||
& Partial<{
|
||||
/** @enum {string} */
|
||||
type: "transmission";
|
||||
isOngoing: boolean;
|
||||
transmissionInterval: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LiveTransmissionIntervalVm"];
|
||||
}>)
|
||||
transmissionInterval: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"][
|
||||
"LiveTransmissionIntervalVm"
|
||||
];
|
||||
}>
|
||||
)
|
||||
| null;
|
||||
externalEmbeddingAllowed: boolean;
|
||||
};
|
||||
|
|
@ -1326,8 +1445,12 @@ export interface external {
|
|||
/** @enum {string} */
|
||||
PlayableSourceMedium: "audio" | "video";
|
||||
NonPlayableElementVm: {
|
||||
reason: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NonPlayableReason"];
|
||||
messageType: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NonPlayableMessageType"];
|
||||
reason: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["NonPlayableReason"];
|
||||
messageType: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["NonPlayableMessageType"];
|
||||
/**
|
||||
* @description Standard message for end user describing why the media element is not
|
||||
* playable.
|
||||
|
|
@ -1389,7 +1512,9 @@ export interface external {
|
|||
/** @description Image to show before play */
|
||||
PosterVm: {
|
||||
/** @description List of images in different sizes */
|
||||
images: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PosterImageVm"][];
|
||||
images: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PosterImageVm"][];
|
||||
};
|
||||
/** @description Title to show before play */
|
||||
TitlesVm: {
|
||||
|
|
@ -1397,12 +1522,18 @@ export interface external {
|
|||
subtitle: string;
|
||||
};
|
||||
PreplayVm: {
|
||||
titles: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["TitlesVm"];
|
||||
titles: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["TitlesVm"];
|
||||
/** @description Description to show before play */
|
||||
description: string;
|
||||
poster: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PosterVm"];
|
||||
poster: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PosterVm"];
|
||||
/** @description List of index points */
|
||||
indexPoints: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["IndexPointVm"][];
|
||||
indexPoints: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["IndexPointVm"][];
|
||||
};
|
||||
LegalAgeRating: {
|
||||
code: string;
|
||||
|
|
@ -1412,7 +1543,9 @@ export interface external {
|
|||
LegalAgeBodyRated: {
|
||||
/** @enum {string} */
|
||||
status: "rated";
|
||||
rating: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LegalAgeRating"];
|
||||
rating: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["LegalAgeRating"];
|
||||
};
|
||||
LegalAgeBodyExempt: {
|
||||
/** @enum {string} */
|
||||
|
|
@ -1420,11 +1553,16 @@ export interface external {
|
|||
};
|
||||
LegalAgeVm: {
|
||||
legalReference: string;
|
||||
body: Partial<
|
||||
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LegalAgeBodyExempt"]
|
||||
> &
|
||||
Partial<
|
||||
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LegalAgeBodyRated"]
|
||||
body:
|
||||
& Partial<
|
||||
external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["LegalAgeBodyExempt"]
|
||||
>
|
||||
& Partial<
|
||||
external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["LegalAgeBodyRated"]
|
||||
>;
|
||||
};
|
||||
PlayableMetadataVm: {
|
||||
|
|
@ -1434,33 +1572,63 @@ export interface external {
|
|||
PlayableMetadata: {
|
||||
/** @enum {string} */
|
||||
playability: "playable";
|
||||
playable: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableMetadataVm"];
|
||||
playable: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableMetadataVm"];
|
||||
nonPlayable: unknown | null;
|
||||
id: string;
|
||||
streamingMode: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableStreamingMode"];
|
||||
streamingMode: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableStreamingMode"];
|
||||
duration: string | null;
|
||||
availability: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["AvailabilityVm"];
|
||||
legalAge: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LegalAgeVm"];
|
||||
preplay: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PreplayVm"];
|
||||
displayAspectRatio: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DisplayAspectRatio"];
|
||||
skipDialogInfo: Partial<
|
||||
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SkipDialogInfoVm"]
|
||||
> | null;
|
||||
sourceMedium: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableSourceMedium"];
|
||||
availability: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["AvailabilityVm"];
|
||||
legalAge: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["LegalAgeVm"];
|
||||
preplay: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PreplayVm"];
|
||||
displayAspectRatio: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["DisplayAspectRatio"];
|
||||
skipDialogInfo:
|
||||
| Partial<
|
||||
external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["SkipDialogInfoVm"]
|
||||
>
|
||||
| null;
|
||||
sourceMedium: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableSourceMedium"];
|
||||
_links: {
|
||||
self: {
|
||||
href: string;
|
||||
};
|
||||
manifests: Partial<
|
||||
manifests:
|
||||
| Partial<
|
||||
{
|
||||
href: string;
|
||||
name: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestLinkName"];
|
||||
name: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"][
|
||||
"ManifestLinkName"
|
||||
];
|
||||
}[]
|
||||
> | null;
|
||||
next: Partial<
|
||||
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NextLink"]
|
||||
> | null;
|
||||
series?: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SeriesLink"];
|
||||
>
|
||||
| null;
|
||||
next:
|
||||
| Partial<
|
||||
external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["NextLink"]
|
||||
>
|
||||
| null;
|
||||
series?: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["SeriesLink"];
|
||||
progress?: {
|
||||
href: string;
|
||||
/** @enum {boolean} */
|
||||
|
|
@ -1468,50 +1636,90 @@ export interface external {
|
|||
};
|
||||
};
|
||||
_embedded: {
|
||||
manifests: Partial<
|
||||
manifests:
|
||||
| Partial<
|
||||
{
|
||||
id: string;
|
||||
availabilityLabel: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["AvailabilityLabel"];
|
||||
availabilityLabel: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"][
|
||||
"AvailabilityLabel"
|
||||
];
|
||||
_links: {
|
||||
self: {
|
||||
href: string;
|
||||
name: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestLinkName"];
|
||||
name: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"][
|
||||
"ManifestLinkName"
|
||||
];
|
||||
};
|
||||
};
|
||||
}[]
|
||||
> | null;
|
||||
>
|
||||
| null;
|
||||
};
|
||||
};
|
||||
NonPlayableMetadata: {
|
||||
/** @enum {string} */
|
||||
playability: "nonPlayable";
|
||||
playable: unknown | null;
|
||||
nonPlayable: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NonPlayableElementVm"];
|
||||
nonPlayable: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["NonPlayableElementVm"];
|
||||
id: string;
|
||||
streamingMode: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableStreamingMode"];
|
||||
streamingMode: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableStreamingMode"];
|
||||
duration: string | null;
|
||||
availability: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["AvailabilityVm"];
|
||||
legalAge: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LegalAgeVm"];
|
||||
preplay: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PreplayVm"];
|
||||
displayAspectRatio: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DisplayAspectRatio"];
|
||||
skipDialogInfo: Partial<
|
||||
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SkipDialogInfoVm"]
|
||||
> | null;
|
||||
sourceMedium: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableSourceMedium"];
|
||||
availability: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["AvailabilityVm"];
|
||||
legalAge: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["LegalAgeVm"];
|
||||
preplay: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PreplayVm"];
|
||||
displayAspectRatio: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["DisplayAspectRatio"];
|
||||
skipDialogInfo:
|
||||
| Partial<
|
||||
external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["SkipDialogInfoVm"]
|
||||
>
|
||||
| null;
|
||||
sourceMedium: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableSourceMedium"];
|
||||
_links: {
|
||||
self: {
|
||||
href: string;
|
||||
};
|
||||
manifests: Partial<
|
||||
manifests:
|
||||
| Partial<
|
||||
{
|
||||
href: string;
|
||||
name: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestLinkName"];
|
||||
name: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"][
|
||||
"ManifestLinkName"
|
||||
];
|
||||
}[]
|
||||
> | null;
|
||||
next: Partial<
|
||||
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NextLink"]
|
||||
> | null;
|
||||
series?: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SeriesLink"];
|
||||
>
|
||||
| null;
|
||||
next:
|
||||
| Partial<
|
||||
external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["NextLink"]
|
||||
>
|
||||
| null;
|
||||
series?: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["SeriesLink"];
|
||||
progress?: {
|
||||
href: string;
|
||||
/** @enum {boolean} */
|
||||
|
|
@ -1519,25 +1727,40 @@ export interface external {
|
|||
};
|
||||
};
|
||||
_embedded: {
|
||||
manifests: Partial<
|
||||
manifests:
|
||||
| Partial<
|
||||
{
|
||||
id: string;
|
||||
availabilityLabel: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["AvailabilityLabel"];
|
||||
availabilityLabel: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"][
|
||||
"AvailabilityLabel"
|
||||
];
|
||||
_links: {
|
||||
self: {
|
||||
href: string;
|
||||
name: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestLinkName"];
|
||||
name: external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"][
|
||||
"ManifestLinkName"
|
||||
];
|
||||
};
|
||||
};
|
||||
}[]
|
||||
> | null;
|
||||
>
|
||||
| null;
|
||||
};
|
||||
};
|
||||
MetadataResponse: Partial<
|
||||
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableMetadata"]
|
||||
> &
|
||||
Partial<
|
||||
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NonPlayableMetadata"]
|
||||
MetadataResponse:
|
||||
& Partial<
|
||||
external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["PlayableMetadata"]
|
||||
>
|
||||
& Partial<
|
||||
external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["NonPlayableMetadata"]
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
|
@ -1547,7 +1770,9 @@ export interface external {
|
|||
/** OK */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DebugData"];
|
||||
"application/json": external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["DebugData"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1557,7 +1782,9 @@ export interface external {
|
|||
/** OK */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DnsList"];
|
||||
"application/json": external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["DnsList"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1593,7 +1820,9 @@ export interface external {
|
|||
/** OK */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestResponse"];
|
||||
"application/json": external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["ManifestResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1623,7 +1852,9 @@ export interface external {
|
|||
/** OK */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestResponse"];
|
||||
"application/json": external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["ManifestResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1651,7 +1882,9 @@ export interface external {
|
|||
/** OK */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestResponse"];
|
||||
"application/json": external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["ManifestResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1679,7 +1912,9 @@ export interface external {
|
|||
/** OK */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestResponse"];
|
||||
"application/json": external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["ManifestResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1709,7 +1944,9 @@ export interface external {
|
|||
/** OK */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["MetadataResponse"];
|
||||
"application/json": external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["MetadataResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1729,7 +1966,9 @@ export interface external {
|
|||
/** OK */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["MetadataResponse"];
|
||||
"application/json": external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["MetadataResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1749,7 +1988,9 @@ export interface external {
|
|||
/** OK */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["MetadataResponse"];
|
||||
"application/json": external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["MetadataResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1771,7 +2012,9 @@ export interface external {
|
|||
/** OK */
|
||||
200: {
|
||||
content: {
|
||||
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["MetadataResponse"];
|
||||
"application/json": external[
|
||||
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json"
|
||||
]["components"]["schemas"]["MetadataResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
71
lib/nrk.ts
71
lib/nrk.ts
|
|
@ -1,20 +1,21 @@
|
|||
import { get, OK } from "https://deno.land/x/kall@v0.1.0/mod.ts";
|
||||
import { components as searchComponents } from './nrk-search.ts';
|
||||
import { components as catalogComponents } from './nrk-catalog.ts';
|
||||
import { components as searchComponents } from "./nrk-search.ts";
|
||||
import { components as catalogComponents } from "./nrk-catalog.ts";
|
||||
|
||||
|
||||
type ArrayElement<A> = A extends readonly (infer T)[] ? T : never
|
||||
export type Serie = catalogComponents["schemas"]["SeriesViewModel"]
|
||||
type ArrayElement<A> = A extends readonly (infer T)[] ? T : never;
|
||||
export type Serie = catalogComponents["schemas"]["SeriesViewModel"];
|
||||
type OriginalEpisode = catalogComponents["schemas"]["EpisodeHalResource"];
|
||||
export type OriginalEpisode = OriginalEpisode & { url: string; }
|
||||
export type OriginalEpisode = OriginalEpisode & { url: string };
|
||||
export type SearchResultList = searchComponents["schemas"]["seriesResult"]["results"];
|
||||
export type SearchResult = ArrayElement<SearchResultList> & { description?: string }
|
||||
export type SearchResult = ArrayElement<SearchResultList> & {
|
||||
description?: string;
|
||||
};
|
||||
|
||||
/* Incomplete manifest types */
|
||||
interface Manifest {
|
||||
id: string;
|
||||
playable: {
|
||||
endSequenceStartTime: null,
|
||||
endSequenceStartTime: null;
|
||||
duration: string;
|
||||
assets: {
|
||||
url: string;
|
||||
|
|
@ -25,58 +26,70 @@ interface Manifest {
|
|||
};
|
||||
}
|
||||
|
||||
async function withDownloadLink(episode: OriginalEpisode): Promise<OriginalEpisode> {
|
||||
async function withDownloadLink(
|
||||
episode: OriginalEpisode,
|
||||
): Promise<OriginalEpisode> {
|
||||
// getting stream link
|
||||
const [playbackStatus, playbackResponse] = await get<Manifest>(`https://psapi.nrk.no/playback/manifest/podcast/${episode.episodeId}`)
|
||||
const [playbackStatus, playbackResponse] = await get<Manifest>(
|
||||
`https://psapi.nrk.no/playback/manifest/podcast/${episode.episodeId}`,
|
||||
);
|
||||
|
||||
if (playbackStatus === OK && playbackResponse) {
|
||||
return { ...episode, url: playbackResponse.playable.assets[0].url };
|
||||
} else {
|
||||
throw `Error getting downloadLink for ${episode.episodeId}, serie: ${episode.originalTitle}. Status: ${playbackStatus}`
|
||||
throw `Error getting downloadLink for ${episode.episodeId}, serie: ${episode.originalTitle}. Status: ${playbackStatus}`;
|
||||
}
|
||||
}
|
||||
|
||||
export const nrkRadio = {
|
||||
search: async (query: string): Promise<SearchResultList> => {
|
||||
|
||||
const [status, response] = await get<searchComponents["schemas"]["searchresult"]>(`https://psapi.nrk.no/radio/search/search?q=${query}`);
|
||||
const [status, response] = await get<
|
||||
searchComponents["schemas"]["searchresult"]
|
||||
>(`https://psapi.nrk.no/radio/search/search?q=${query}`);
|
||||
if (status === OK && response) {
|
||||
return response.results.series?.results;
|
||||
} else {
|
||||
throw `Something went wrong with ${query} - got status ${status}`
|
||||
throw `Something went wrong with ${query} - got status ${status}`;
|
||||
}
|
||||
},
|
||||
getSerieData: async (seriesId: string) => {
|
||||
|
||||
const [
|
||||
[episodeStatus, episodeResponse],
|
||||
[seriesStatus, serieResponse],
|
||||
] = await Promise.all([
|
||||
get<catalogComponents["schemas"]["EpisodesHalResource"]>(`https://psapi.nrk.no/radio/catalog/podcast/${seriesId}/episodes`),
|
||||
get<catalogComponents["schemas"]["SeriesHalResource"]>(`https://psapi.nrk.no/radio/catalog/podcast/${seriesId}`)
|
||||
get<catalogComponents["schemas"]["EpisodesHalResource"]>(
|
||||
`https://psapi.nrk.no/radio/catalog/podcast/${seriesId}/episodes`,
|
||||
),
|
||||
get<catalogComponents["schemas"]["SeriesHalResource"]>(
|
||||
`https://psapi.nrk.no/radio/catalog/podcast/${seriesId}`,
|
||||
),
|
||||
]);
|
||||
|
||||
|
||||
if (episodeStatus === OK && seriesStatus === OK && serieResponse?.series && episodeResponse?._embedded.episodes?.length) {
|
||||
const episodes = await Promise.all(episodeResponse._embedded.episodes.map(episode => withDownloadLink(episode)));
|
||||
if (
|
||||
episodeStatus === OK && seriesStatus === OK &&
|
||||
serieResponse?.series && episodeResponse?._embedded.episodes?.length
|
||||
) {
|
||||
const episodes = await Promise.all(
|
||||
episodeResponse._embedded.episodes.map((episode) => withDownloadLink(episode)),
|
||||
);
|
||||
return {
|
||||
...serieResponse.series,
|
||||
episodes,
|
||||
}
|
||||
};
|
||||
} else {
|
||||
throw `Error getting episodes for ${seriesId}: EpisodeStatus: ${episodeStatus}. SerieStatus: ${seriesStatus}`
|
||||
throw `Error getting episodes for ${seriesId}: EpisodeStatus: ${episodeStatus}. SerieStatus: ${seriesStatus}`;
|
||||
}
|
||||
|
||||
},
|
||||
getEpisode: async (seriesId: string, episodeId: string): Promise<OriginalEpisode> => {
|
||||
|
||||
|
||||
const url = `https://psapi.nrk.no/radio/catalog/podcast/${seriesId}/episodes/${episodeId}`
|
||||
getEpisode: async (
|
||||
seriesId: string,
|
||||
episodeId: string,
|
||||
): Promise<OriginalEpisode> => {
|
||||
const url = `https://psapi.nrk.no/radio/catalog/podcast/${seriesId}/episodes/${episodeId}`;
|
||||
const [status, episode] = await get<OriginalEpisode>(url);
|
||||
if (status !== OK) {
|
||||
throw `Error getting episode ${episodeId}. Status: ${status}. Series: ${seriesId}`;
|
||||
}
|
||||
|
||||
return episode;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import { nrkRadio, Episode } from "../../../lib/nrk.ts"
|
||||
import { Episode, nrkRadio } from "../../../lib/nrk.ts";
|
||||
import { HandlerContext } from "$fresh/server.ts";
|
||||
|
||||
import { serialize, tag, declaration } from "https://raw.githubusercontent.com/olaven/serialize-xml/v0.4.0/mod.ts";
|
||||
import { declaration, serialize, tag } from "https://raw.githubusercontent.com/olaven/serialize-xml/v0.4.0/mod.ts";
|
||||
import { getHostName } from "../../../utils.ts";
|
||||
|
||||
function toItemTag(seriesId: string, episode: Episode) {
|
||||
|
||||
const description = episode.titles.subtitle || "";
|
||||
return tag("item", [
|
||||
tag("title", episode.titles.title),
|
||||
|
|
@ -16,7 +15,10 @@ function toItemTag(seriesId: string, episode: Episode) {
|
|||
tag("pubDate", new Date(episode.date).toUTCString()),
|
||||
tag("itunes:duration", episode.durationInSeconds.toString()),
|
||||
tag("podcast:chapters", "", [
|
||||
["url", `${getHostName()}/api/feeds/${seriesId}/${episode.episodeId}/chapters`],
|
||||
[
|
||||
"url",
|
||||
`${getHostName()}/api/feeds/${seriesId}/${episode.episodeId}/chapters`,
|
||||
],
|
||||
["type", "application/json+chapters"],
|
||||
]),
|
||||
tag("enclosure", "", [
|
||||
|
|
@ -24,11 +26,11 @@ function toItemTag(seriesId: string, episode: Episode) {
|
|||
["length", episode.durationInSeconds.toString()],
|
||||
["type", "audio/mpeg3"],
|
||||
]),
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
async function buildFeed(seriesId: string) {
|
||||
const serie = await nrkRadio.getSerieData(seriesId)
|
||||
const serie = await nrkRadio.getSerieData(seriesId);
|
||||
const imageUrl = serie.squareImage.at(-1)?.url;
|
||||
const linkValue = `https://radio.nrk.no/podkast/${serie.id}`;
|
||||
|
||||
|
|
@ -51,18 +53,17 @@ async function buildFeed(seriesId: string) {
|
|||
podcast feed validation.
|
||||
*/
|
||||
tag("itunes:category", "", [["text", "Government"]]),
|
||||
tag("itunes:owner",
|
||||
[
|
||||
tag("itunes:owner", [
|
||||
tag("itunes:name", "NRK"),
|
||||
tag("itunes:email", "nrkpodcast@nrk.no")
|
||||
]
|
||||
),
|
||||
tag("itunes:email", "nrkpodcast@nrk.no"),
|
||||
]),
|
||||
tag(
|
||||
"description",
|
||||
serie.titles.subtitle || ""
|
||||
serie.titles.subtitle || "",
|
||||
),
|
||||
tag("ttl", "60"), //60 minutes
|
||||
...(imageUrl ? [
|
||||
...(imageUrl
|
||||
? [
|
||||
tag("itunes:image", "", [
|
||||
["href", imageUrl],
|
||||
]),
|
||||
|
|
@ -70,9 +71,10 @@ async function buildFeed(seriesId: string) {
|
|||
tag("url", imageUrl),
|
||||
tag("title", serie.titles.title),
|
||||
tag("link", linkValue),
|
||||
])
|
||||
] : []),
|
||||
...serie.episodes.map(episode => toItemTag(seriesId, episode)),
|
||||
]),
|
||||
]
|
||||
: []),
|
||||
...serie.episodes.map((episode) => toItemTag(seriesId, episode)),
|
||||
]),
|
||||
],
|
||||
[
|
||||
|
|
@ -80,18 +82,21 @@ async function buildFeed(seriesId: string) {
|
|||
["xmlns:itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd"],
|
||||
["xmlns:content", "http://purl.org/rss/1.0/modules/content/"],
|
||||
["xmlns:podcast", "https://podcastindex.org/namespace/1.0"],
|
||||
]
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export const handler = async (req: Request, _ctx: HandlerContext): Promise<Response> => {
|
||||
export const handler = async (
|
||||
req: Request,
|
||||
_ctx: HandlerContext,
|
||||
): Promise<Response> => {
|
||||
const seriesId = _ctx.params.seriesId;
|
||||
const feedContent = await buildFeed(seriesId);
|
||||
|
||||
return new Response(feedContent, {
|
||||
headers: {
|
||||
"Content-Type": "application/xml"
|
||||
}
|
||||
"Content-Type": "application/xml",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,12 +2,15 @@ import { parse, toSeconds } from "https://esm.sh/iso8601-duration@2.1.1";
|
|||
import { nrkRadio, OriginalEpisode } from "../../../../../lib/nrk.ts";
|
||||
|
||||
function toChapters(episode: OriginalEpisode) {
|
||||
return episode.indexPoints.map(indexPoint => ({
|
||||
return episode.indexPoints.map((indexPoint) => ({
|
||||
title: indexPoint.title,
|
||||
startTime: toSeconds(parse(indexPoint.startPoint))
|
||||
}))
|
||||
startTime: toSeconds(parse(indexPoint.startPoint)),
|
||||
}));
|
||||
}
|
||||
export const handler = async (req: Request, _ctx: HandlerContext): Promise<Response> => {
|
||||
export const handler = async (
|
||||
req: Request,
|
||||
_ctx: HandlerContext,
|
||||
): Promise<Response> => {
|
||||
const seriesId = _ctx.params.seriesId;
|
||||
const episodeId = _ctx.params.episodeId;
|
||||
|
||||
|
|
@ -17,11 +20,11 @@ export const handler = async (req: Request, _ctx: HandlerContext): Promise<Respo
|
|||
const body = {
|
||||
version: "1.2.0",
|
||||
chapters,
|
||||
}
|
||||
};
|
||||
|
||||
return new Response(JSON.stringify(body), {
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Head } from "$fresh/runtime.ts";
|
||||
import { Handlers, PageProps } from "$fresh/server.ts";
|
||||
import Search from "../components/Search.tsx"
|
||||
import Search from "../components/Search.tsx";
|
||||
import { SerieCard } from "../components/SeriesCard.tsx";
|
||||
import { nrkRadio, SearchResult, SearchResultList, Serie } from "../lib/nrk.ts";
|
||||
|
||||
|
|
@ -34,15 +34,42 @@ export default function Home({ data }: PageProps<HandlerData>) {
|
|||
<h2 className="lg:text-xl">NRK-podcast som RSS</h2>
|
||||
</div>
|
||||
<Search defaultValue={data.query} />
|
||||
{data.result ? (
|
||||
{data.result
|
||||
? (
|
||||
<div className="w-full mx-auto my-4">
|
||||
{data.result.map(result => <SerieCard serie={result} origin={data.origin} />)}
|
||||
{data.result.map((result) => (
|
||||
<SerieCard
|
||||
serie={result}
|
||||
origin={data.origin}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
)
|
||||
: null}
|
||||
<h2 className="text-3xl">Hva er dette?</h2>
|
||||
<p>Hei! Denne løsningen er laget som en reaksjon på at statsfinansierte NRK lukker ned innholdet sitt til sin egen app fremfor å bygge oppunder åpne standarder som RSS. Denne siden er laget fort og gæli - den er ustabil og kommer til å krasje :) Sjekk gjerne ut <a href="https://github.com/olaven/NRSS/" className="underline">kildekoden</a>. </p>
|
||||
<p>
|
||||
Hei! Denne løsningen er laget som en reaksjon på at statsfinansierte NRK lukker ned innholdet sitt til sin
|
||||
egen app fremfor å bygge oppunder åpne standarder som RSS. Denne siden er laget fort og gæli - den er ustabil
|
||||
og kommer til å krasje :) Sjekk gjerne ut{" "}
|
||||
<a
|
||||
href="https://github.com/olaven/NRSS/"
|
||||
className="underline"
|
||||
>
|
||||
kildekoden
|
||||
</a>.
|
||||
</p>
|
||||
<h2 className="text-3xl">Hvordan bruker jeg dette?</h2>
|
||||
<p>Søk på NRK-podcasten du vil høre på. Kopier deretter URL-en under bildet. Lim denne inn i akkurat den podcastspilleren du måtte foretrekke! Se <a className="underline" href="https://help.omnystudio.com/en/articles/5222518-podcast-apps-that-support-add-rss-feed">her</a> for en oversikt over hvordan det gjøres i populære podcastspillere.</p>
|
||||
<p>
|
||||
Søk på NRK-podcasten du vil høre på. Kopier deretter URL-en under bildet. Lim denne inn i akkurat den
|
||||
podcastspilleren du måtte foretrekke! Se{" "}
|
||||
<a
|
||||
className="underline"
|
||||
href="https://help.omnystudio.com/en/articles/5222518-podcast-apps-that-support-add-rss-feed"
|
||||
>
|
||||
her
|
||||
</a>{" "}
|
||||
for en oversikt over hvordan det gjøres i populære podcastspillere.
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue