@ -7,29 +7,29 @@ Will display an overview with the following datasources:
TODO : Link each overview value to the sub - page that focuses on it .
TODO : Link each overview value to the sub - page that focuses on it .
* /
* /
import React , { useState , useEffect , useContext } from "react" ;
import React , { useState , useEffect , useContext } from 'react' ;
import { Skeleton , Card , Statistic } from "antd" ;
import { Skeleton , Card , Statistic } from 'antd' ;
import { UserOutlined , ClockCircleOutlined } from "@ant-design/icons" ;
import { UserOutlined , ClockCircleOutlined } from '@ant-design/icons' ;
import { formatDistanceToNow , formatRelative } from "date-fns" ;
import { formatDistanceToNow , formatRelative } from 'date-fns' ;
import { ServerStatusContext } from "../utils/server-status-context" ;
import { ServerStatusContext } from '../utils/server-status-context' ;
import StatisticItem from "./components/statistic"
import StatisticItem from '../components/statistic' ;
import LogTable from "./components/log-table" ;
import LogTable from '../components/log-table' ;
import Offline from './offline-notice' ;
import Offline from './offline-notice' ;
import {
import { LOGS_WARN , fetchData , FETCH_INTERVAL } from '../utils/apis' ;
LOGS_WARN ,
import { formatIPAddress , isEmptyObject } from '../utils/format' ;
fetchData ,
import { UpdateArgs } from '../types/config-section' ;
FETCH_INTERVAL ,
} from "../utils/apis" ;
import { formatIPAddress , isEmptyObject } from "../utils/format" ;
import { UpdateArgs } from "../types/config-section" ;
function streamDetailsFormatter ( streamDetails ) {
function streamDetailsFormatter ( streamDetails ) {
return (
return (
< ul className = "statistics-list" >
< ul className = "statistics-list" >
< li > { streamDetails . videoCodec || 'Unknown' } @ { streamDetails . videoBitrate || 'Unknown' } kbps < / li >
< li >
{ streamDetails . videoCodec || 'Unknown' } @ { streamDetails . videoBitrate || 'Unknown' } kbps
< / li >
< li > { streamDetails . framerate || 'Unknown' } fps < / li >
< li > { streamDetails . framerate || 'Unknown' } fps < / li >
< li > { streamDetails . width } x { streamDetails . height } < / li >
< li >
{ streamDetails . width } x { streamDetails . height }
< / li >
< / ul >
< / ul >
) ;
) ;
}
}
@ -39,7 +39,7 @@ export default function Home() {
const { broadcaster , serverConfig : configData } = serverStatusData || { } ;
const { broadcaster , serverConfig : configData } = serverStatusData || { } ;
const { remoteAddr , streamDetails } = broadcaster || { } ;
const { remoteAddr , streamDetails } = broadcaster || { } ;
const encoder = streamDetails ? . encoder || "Unknown encoder" ;
const encoder = streamDetails ? . encoder || 'Unknown encoder' ;
const [ logsData , setLogs ] = useState ( [ ] ) ;
const [ logsData , setLogs ] = useState ( [ ] ) ;
const getLogs = async ( ) = > {
const getLogs = async ( ) = > {
@ -47,12 +47,12 @@ export default function Home() {
const result = await fetchData ( LOGS_WARN ) ;
const result = await fetchData ( LOGS_WARN ) ;
setLogs ( result ) ;
setLogs ( result ) ;
} catch ( error ) {
} catch ( error ) {
console . log ( "==== error" , error ) ;
console . log ( '==== error' , error ) ;
}
}
} ;
} ;
const getMoreStats = ( ) = > {
const getMoreStats = ( ) = > {
getLogs ( ) ;
getLogs ( ) ;
}
} ;
useEffect ( ( ) = > {
useEffect ( ( ) = > {
getMoreStats ( ) ;
getMoreStats ( ) ;
@ -62,7 +62,7 @@ export default function Home() {
return ( ) = > {
return ( ) = > {
clearInterval ( intervalId ) ;
clearInterval ( intervalId ) ;
}
} ;
} , [ ] ) ;
} , [ ] ) ;
if ( isEmptyObject ( configData ) || isEmptyObject ( serverStatusData ) ) {
if ( isEmptyObject ( configData ) || isEmptyObject ( serverStatusData ) ) {
@ -80,7 +80,8 @@ export default function Home() {
}
}
// map out settings
// map out settings
const videoQualitySettings = serverStatusData ? . currentBroadcast ? . outputSettings ? . map ( ( setting , index ) = > {
const videoQualitySettings = serverStatusData ? . currentBroadcast ? . outputSettings ? . map (
( setting , index ) = > {
const { audioPassthrough , videoPassthrough , audioBitrate , videoBitrate , framerate } = setting ;
const { audioPassthrough , videoPassthrough , audioBitrate , videoBitrate , framerate } = setting ;
const audioSetting = audioPassthrough
const audioSetting = audioPassthrough
@ -88,32 +89,29 @@ export default function Home() {
: ` ${ audioBitrate || 'Unknown' } kbps ` ;
: ` ${ audioBitrate || 'Unknown' } kbps ` ;
const videoSetting = videoPassthrough
const videoSetting = videoPassthrough
? ` ${ streamDetails . videoBitrate || 'Unknown' } kbps, ${ streamDetails . framerate } fps ${ streamDetails . width } x ${ streamDetails . height } `
? ` ${ streamDetails . videoBitrate || 'Unknown' } kbps, ${ streamDetails . framerate } fps ${
streamDetails . width
} x $ { streamDetails . height } `
: ` ${ videoBitrate || 'Unknown' } kbps, ${ framerate } fps ` ;
: ` ${ videoBitrate || 'Unknown' } kbps, ${ framerate } fps ` ;
let settingTitle = 'Outbound Stream Details' ;
let settingTitle = 'Outbound Stream Details' ;
settingTitle = ( videoQualitySettings ? . length > 1 ) ?
settingTitle =
` ${ settingTitle } ${ index + 1 } ` : settingTitle ;
videoQualitySettings ? . length > 1 ? ` ${ settingTitle } ${ index + 1 } ` : settingTitle ;
return (
return (
< Card title = { settingTitle } type = "inner" key = { ` ${ settingTitle } ${ index } ` } >
< Card title = { settingTitle } type = "inner" key = { ` ${ settingTitle } ${ index } ` } >
< StatisticItem
< StatisticItem title = "Outbound Video Stream" value = { videoSetting } prefix = { null } / >
title = "Outbound Video Stream"
< StatisticItem title = "Outbound Audio Stream" value = { audioSetting } prefix = { null } / >
value = { videoSetting }
prefix = { null }
/ >
< StatisticItem
title = "Outbound Audio Stream"
value = { audioSetting }
prefix = { null }
/ >
< / Card >
< / Card >
) ;
) ;
} ) ;
} ,
) ;
// inbound
// inbound
const { viewerCount , sessionPeakViewerCount } = serverStatusData ;
const { viewerCount , sessionPeakViewerCount } = serverStatusData ;
const streamAudioDetailString = ` ${ streamDetails . audioCodec } , ${ streamDetails . audioBitrate || 'Unknown' } kbps ` ;
const streamAudioDetailString = ` ${ streamDetails . audioCodec } , ${
streamDetails . audioBitrate || 'Unknown'
} kbps ` ;
const broadcastDate = new Date ( broadcaster . time ) ;
const broadcastDate = new Date ( broadcaster . time ) ;
@ -123,18 +121,11 @@ export default function Home() {
< div className = "section online-status-section" >
< div className = "section online-status-section" >
< Card title = "Stream is online" type = "inner" >
< Card title = "Stream is online" type = "inner" >
< Statistic
< Statistic
title = { ` Stream started ${ formatRelative (
title = { ` Stream started ${ formatRelative ( broadcastDate , Date . now ( ) ) } ` }
broadcastDate ,
Date . now ( )
) } ` }
value = { formatDistanceToNow ( broadcastDate ) }
value = { formatDistanceToNow ( broadcastDate ) }
prefix = { < ClockCircleOutlined / > }
prefix = { < ClockCircleOutlined / > }
/ >
/ >
< Statistic
< Statistic title = "Viewers" value = { viewerCount } prefix = { < UserOutlined / > } / >
title = "Viewers"
value = { viewerCount }
prefix = { < UserOutlined / > }
/ >
< Statistic
< Statistic
title = "Peak viewer count"
title = "Peak viewer count"
value = { sessionPeakViewerCount }
value = { sessionPeakViewerCount }
@ -144,10 +135,7 @@ export default function Home() {
< / div >
< / div >
< div className = "section stream-details-section" >
< div className = "section stream-details-section" >
< div className = "details outbound-details" > { videoQualitySettings } < / div >
< div className = "details outbound-details" >
{ videoQualitySettings }
< / div >
< div className = "details other-details" >
< div className = "details other-details" >
< Card title = "Inbound Stream Details" type = "inner" >
< Card title = "Inbound Stream Details" type = "inner" >