feat: no viewer streaminfo implementation

This commit is contained in:
2025-03-15 16:57:24 +01:00
parent eda2acb1be
commit cfc0f78a6c
5 changed files with 115 additions and 70 deletions

View File

@@ -17,7 +17,7 @@ services:
environment:
UID: 1000
GID: 1000
API_AUTH: asdf
API_AUTH: skibiditoilet
volumes:
- ./nginx.conf:/etc/nginx/templates/nginx.conf.template
- ./html:/var/www/html

View File

@@ -97,7 +97,7 @@ function StreamerItem({ streamer }: { streamer: StreamInfoResponse[0] }) {
<div className="flex-1">
<p className="font-medium truncate">{streamer.username}</p>
<p className="text-sm truncate">{streamer.category}</p>
{streamer.isLive && (
{false && streamer.isLive && (
<p className="text-sm">
{streamer.viewers} viewer{streamer.viewers === 1 ? '' : 's'}
</p>

View File

@@ -1,5 +1,5 @@
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
//await (await import('@/lib/instrumentation/streamInfo')).default();
await (await import('@/lib/instrumentation/streamInfo')).default();
}
}

View File

@@ -1,5 +1,5 @@
import prisma from '@/lib/db';
import { roomService } from '@/lib/services/livekit';
import { HttpFlv } from '../types/liveBackendJson';
export default async function runner() {
// if there are no users it explodes so yeah
@@ -45,13 +45,21 @@ export async function initializeStreamInfo(channelId?: string) {
}
export async function syncStream() {
// get all active rooms
const rooms = await roomService.listRooms();
const request = (
await (
await fetch(`${process.env.LIVE_SERVER_URL}/stat`, {
headers: {
Authorization: process.env.STAT_AUTH!,
},
})
).json()
)['http-flv'] as HttpFlv;
const rooms = request.servers[0].applications.filter(app => app.name === 'channel-live')[0].live.streams;
// process each room
for (const room of rooms) {
const isLive = room.numPublishers >= 1;
const isLive = room.active;
const originalStreamInfo = await prisma.streamInfo.findUnique({
where: { username: room.name },
});
@@ -78,7 +86,7 @@ export async function syncStream() {
},
update: {
isLive,
viewers: room.numParticipants - 1,
viewers: room.clients.filter(c => !c.publishing).length,
startedAt: !isLive
? new Date(0)
: originalStreamInfo?.isLive

View File

@@ -1,24 +1,48 @@
export interface RtmpStat {
nginxt_version: string;
compiler: string;
built: string;
pid: number;
uptime: number;
naccepted: number;
bw_in: number;
bw_out: number;
clients: number;
applications: Application[];
/**
* Types for nginx-http-flv module statistics
*/
// Client information
interface Client {
id: number;
address: string;
time: number;
flashver: string;
swfurl?: string;
dropped: number;
avsync: number;
timestamp: number;
publishing: boolean;
active: boolean;
}
interface Application {
name: string;
live: LiveStream[];
hls: HlsStream[];
dash: DashStream[];
// Video metadata
interface VideoMeta {
width: number;
height: number;
frame_rate: number;
codec: string;
profile: string;
compat: number;
level: number;
}
interface LiveStream {
// Audio metadata
interface AudioMeta {
codec: string;
profile: string;
channels: number;
sample_rate: number;
}
// Stream metadata
interface StreamMeta {
video: VideoMeta;
audio: AudioMeta;
}
// Stream information
interface Stream {
name: string;
time: number;
bw_in: number;
@@ -28,53 +52,66 @@ interface LiveStream {
bw_audio: number;
bw_video: number;
clients: Client[];
}
interface HlsStream {
name: string;
bw_in: number;
bytes_in: number;
bw_out: number;
bytes_out: number;
}
interface DashStream {
name: string;
bw_in: number;
bytes_in: number;
bw_out: number;
bytes_out: number;
}
interface Client {
id: string;
address: string;
time: number;
flashver: string;
dropped: number;
avsync: number;
timestamp: number;
records: any[]; // Empty array in the provided example
meta: StreamMeta;
nclients: number;
publishing: boolean;
active: boolean;
audio: AudioStream;
video: VideoStream;
}
interface AudioStream {
codec: string;
profile: string;
level: string;
bw: number;
channels: number;
sample_rate: number;
// Live application section
interface Live {
streams: Stream[];
nclients: number;
}
interface VideoStream {
codec: string;
profile: string;
level: string;
bw: number;
width: number;
height: number;
frame_rate: number;
}
// Recorder configuration
interface Recorder {
id: string;
flags: string[];
unique: boolean;
append: boolean;
lock_file: boolean;
notify: boolean;
path: string;
max_size: number;
max_frames: number;
interval: number;
suffix: string;
}
// Recorders section
interface Recorders {
count: number;
lists: Recorder[];
}
// Application information
interface Application {
name: string;
live: Live;
recorders: Recorders;
}
// Server information
interface Server {
port: number;
server_index: number;
applications: Application[];
}
// Root HTTP-FLV structure
export interface HttpFlv {
nginx_version: string;
nginx_http_flv_version: string;
compiler: string;
built: string;
pid: number;
uptime: number;
naccepted: number;
bw_in: number;
bytes_in: number;
bw_out: number;
bytes_out: number;
servers: Server[];
}