import { StreamState } from "index"; import { NostrEvent } from "@snort/system"; import { ExternalStore } from "@snort/shared"; import { Nip103StreamProvider } from "./zsz"; import { ManualProvider } from "./manual"; import { OwncastProvider } from "./owncast"; export interface StreamProvider { get name(): string; get type(): StreamProviders; /** * Get general info about connected provider to test everything is working */ info(): Promise; /** * Create a config object to save in localStorage */ createConfig(): unknown & { type: StreamProviders }; /** * Update stream info event */ updateStreamInfo(ev: NostrEvent): Promise; /** * Top-up balance with provider */ topup(amount: number): Promise; /** * Accept TOS of the streaming provider */ acceptTos(): Promise; } export enum StreamProviders { Manual = "manual", Owncast = "owncast", Cloudflare = "cloudflare", NostrType = "nostr", } export interface StreamProviderInfo { name: string; summary?: string; version?: string; state: StreamState; viewers?: number; publishedEvent?: NostrEvent; streamInfo?: StreamProviderStreamInfo; balance?: number; endpoints: Array; tosAccepted?: boolean; tosLink?: string } export interface StreamProviderEndpoint { name: string; url: string; key: string; rate?: number; unit?: string; capabilities?: Array; } export interface StreamProviderStreamInfo { title: string summary: string image: string tags: Array content_warning: string } export class ProviderStore extends ExternalStore> { #providers: Array = []; constructor() { super(); const cache = window.localStorage.getItem("providers"); if (cache) { const cached: Array<{ type: StreamProviders } & Record> = JSON.parse(cache); for (const c of cached) { switch (c.type) { case StreamProviders.Manual: { this.#providers.push(new ManualProvider()); break; } case StreamProviders.NostrType: { this.#providers.push(new Nip103StreamProvider(c.url as string)); break; } case StreamProviders.Owncast: { this.#providers.push( new OwncastProvider(c.url as string, c.token as string) ); break; } } } } } add(p: StreamProvider) { this.#providers.push(p); this.#save(); this.notifyChange(); } takeSnapshot() { const defaultProvider = new Nip103StreamProvider( "https://api.zap.stream/api/nostr/" ); return [defaultProvider, new ManualProvider(), ...this.#providers]; } #save() { const cfg = this.#providers.map((a) => a.createConfig()); window.localStorage.setItem("providers", JSON.stringify(cfg)); } } export const StreamProviderStore = new ProviderStore();