Files
esports/src/lib/broadcast/platforms.ts

107 lines
3.3 KiB
TypeScript

/** Where a channel can stream to, and what each platform needs. */
export interface Platform {
id: string;
label: string;
/** Default ingest server; empty means the platform gives you one per stream. */
ingest: string;
/** Where to find the stream key. */
keyHelp: string;
/** Shown 9:16 on phones: use a portrait channel. */
vertical: boolean;
/** How the platform keeps the recording. */
vods: string;
/** Brand color, for its badge. */
color: string;
}
export const PLATFORMS: Platform[] = [
{
id: 'twitch',
label: 'Twitch',
color: '#9146FF',
ingest: 'rtmp://ingest.global-contribute.live-video.net/app',
keyHelp: 'Twitch Creator Dashboard → Settings → Stream → Primary stream key.',
vertical: false,
vods: 'Turn on “Store past broadcasts” in Twitch → Settings → Stream. Twitch keeps them 7 days, or 60 for Partners, Turbo and Prime.'
},
{
id: 'youtube',
label: 'YouTube',
color: '#FF0033',
ingest: 'rtmps://a.rtmps.youtube.com/live2',
keyHelp:
'YouTube Studio → Create → Go live → Stream → Stream key. A persistent key works for every stream.',
vertical: false,
vods: 'YouTube keeps every stream as a video on the channel by itself.'
},
{
id: 'facebook',
label: 'Facebook',
color: '#1877F2',
ingest: 'rtmps://live-api-s.facebook.com:443/rtmp',
keyHelp: 'Facebook Live Producer → Streaming software → “Use a persistent stream key”.',
vertical: false,
vods: 'Facebook posts the stream as a video when it ends.'
},
{
id: 'x',
label: 'X (Twitter)',
color: '#e7e9ea',
ingest: '',
keyHelp: 'X Media Studio → Producer → Sources: copy the RTMP URL and the stream key.',
vertical: false,
vods: 'X keeps the broadcast as a post.'
},
{
id: 'instagram',
label: 'Instagram',
color: '#E1306C',
ingest: '',
keyHelp:
'instagram.com → Create → Live video: copy the stream URL and key. Instagram makes a new key for every broadcast.',
vertical: true,
vods: 'Share the live video to your profile when it ends.'
},
{
id: 'tiktok',
label: 'TikTok',
color: '#25F4EE',
ingest: '',
keyHelp:
'TikTok LIVE Center (or LIVE Studio) → Stream key: copy the server URL and key. Needs an account that can go LIVE.',
vertical: true,
vods: 'TikTok offers a replay for a while after the stream.'
},
{
id: 'custom',
label: 'Other RTMP server',
color: '#a1a1aa',
ingest: '',
keyHelp: 'Any RTMP or RTMPS server: its URL, and the stream key if it has one.',
vertical: false,
vods: 'Up to the server.'
}
];
export const platform = (id: string) =>
PLATFORMS.find((each) => each.id === id) ?? PLATFORMS[PLATFORMS.length - 1];
export const QUALITIES: Record<
string,
{ label: string; height: number; fps: number; bitrate: number }
> = {
'720p30': { label: '720p, 30 fps (3 Mbps)', height: 720, fps: 30, bitrate: 3000 },
'1080p30': { label: '1080p, 30 fps (4.5 Mbps)', height: 1080, fps: 30, bitrate: 4500 },
'1080p60': { label: '1080p, 60 fps (6 Mbps)', height: 1080, fps: 60, bitrate: 6000 }
};
/** Output size for a channel: 16:9, or 9:16 for portrait. */
export function outputSize(format: string, quality: string) {
const q = QUALITIES[quality] ?? QUALITIES['1080p30'];
const long = Math.round((q.height * 16) / 9);
const { height: short, ...rest } = q;
return format === 'portrait'
? { ...rest, width: short, height: long }
: { ...rest, width: long, height: short };
}