Stream Viewers minimal statistics.

This commit is contained in:
Zorglube 2021-03-14 03:13:20 +01:00
parent 19438a1409
commit 3a4dd41f75
4 changed files with 88 additions and 14 deletions

View File

@ -91,17 +91,20 @@ func (cl *Client) NewMsg(data common.ClientData) {
// because the /me command outputs to the messages // because the /me command outputs to the messages
msg = addSpoilerTags(msg) msg = addSpoilerTags(msg)
msgLen := len(msg)
// Don't send zero-length messages // Don't send zero-length messages
if len(msg) == 0 { if msgLen == 0 {
return return
} }
if strings.HasPrefix(msg, "/") { if strings.HasPrefix(msg, "/") {
// is a command // is a command
msg = msg[1:len(msg)] msg = msg[1:msgLen]
fullcmd := strings.Split(msg, " ") fullcmd := strings.Split(msg, " ")
cmd := strings.ToLower(fullcmd[0]) cmd := strings.ToLower(fullcmd[0])
args := fullcmd[1:len(fullcmd)] fullcmdLen := len(fullcmd)
args := fullcmd[1:fullcmdLen]
response, err := commands.RunCommand(cmd, args, cl) response, err := commands.RunCommand(cmd, args, cl)
if response != "" || err != nil { if response != "" || err != nil {
@ -136,7 +139,7 @@ func (cl *Client) NewMsg(data common.ClientData) {
} }
// Trim long messages // Trim long messages
if len(msg) > 400 { if msgLen > 400 {
msg = msg[0:400] msg = msg[0:400]
} }

View File

@ -277,11 +277,13 @@ var commands = &CommandControl{
cl.belongsTo.clientsMtx.Unlock() cl.belongsTo.clientsMtx.Unlock()
// Just print max users and time alive here // Just print max users and time alive here
return fmt.Sprintf("Current users in chat: <b>%d</b><br />Max users in chat: <b>%d</b><br />Server uptime: <b>%s</b><br />Stream uptime: <b>%s</b>", return fmt.Sprintf("Current users in chat: <b>%d</b><br />Max users in chat: <b>%d</b><br />Server uptime: <b>%s</b><br />Stream uptime: <b>%s</b><br />Viewers: <b>%d</b><br />Max Viewers: <b>%d</b>",
users, users,
stats.getMaxUsers(), stats.getMaxUsers(),
time.Since(stats.start), time.Since(stats.start),
stats.getStreamLength(), stats.getStreamLength(),
stats.getViewerCount(),
stats.getMaxViewerCount(),
), nil ), nil
}, },
}, },

View File

@ -409,8 +409,10 @@ func handlePlay(conn *rtmp.Conn) {
} }
func handleLive(w http.ResponseWriter, r *http.Request) { func handleLive(w http.ResponseWriter, r *http.Request) {
uri := strings.Trim(r.URL.Path, "/")
l.RLock() l.RLock()
ch := channels[strings.Trim(r.URL.Path, "/")] ch := channels[uri]
l.RUnlock() l.RUnlock()
if ch != nil { if ch != nil {
@ -424,9 +426,14 @@ func handleLive(w http.ResponseWriter, r *http.Request) {
muxer := flv.NewMuxerWriteFlusher(writeFlusher{httpflusher: flusher, Writer: w}) muxer := flv.NewMuxerWriteFlusher(writeFlusher{httpflusher: flusher, Writer: w})
cursor := ch.que.Latest() cursor := ch.que.Latest()
ip := extractIp(r)
stats.addViewer(ip)
avutil.CopyFile(muxer, cursor) avutil.CopyFile(muxer, cursor)
stats.removeViewer(ip)
} else { } else {
// Maybe HTTP_204 is better than HTTP_404
w.WriteHeader(http.StatusNoContent)
stats.resetViewers()
} }
} }
@ -439,3 +446,16 @@ func handleDefault(w http.ResponseWriter, r *http.Request) {
handleIndexTemplate(w, r) handleIndexTemplate(w, r)
} }
} }
func extractIp(r *http.Request) string {
ip := r.Host
f := r.Header.Get("Forwarded")
xff := r.Header.Get("X-Forwarded-For")
if !(xff == "") {
ip = xff
}
if !(f == "") {
ip = f
}
return ip
}

View File

@ -13,13 +13,40 @@ type streamStats struct {
maxUsers int maxUsers int
start time.Time start time.Time
mutex sync.Mutex mutex sync.Mutex
streamStart time.Time streamStart time.Time
streamLive bool // True if live streamLive bool // True if live
viewers map[string]string
maxViewers int
}
func (s *streamStats) addViewer(ip string) {
s.mutex.Lock()
s.viewers[ip] = ip
s.updateMaxViewers(len(s.viewers))
s.mutex.Unlock()
common.LogDebugf("Viewer connect from: %s\n", ip)
}
func (s *streamStats) removeViewer(ip string) {
s.mutex.Lock()
delete(s.viewers, ip)
s.mutex.Unlock()
common.LogDebugf("Viewer left from: %s\n", ip)
}
func (s *streamStats) updateMaxViewers(size int) {
if s.maxViewers < size {
s.maxViewers = size
}
}
func (s *streamStats) resetViewers() {
s.viewers = make(map[string]string)
} }
func newStreamStats() streamStats { func newStreamStats() streamStats {
return streamStats{start: time.Now(), streamLive: false} return streamStats{start: time.Now(), streamLive: false, viewers: make(map[string]string)}
} }
func (s *streamStats) msgInInc() { func (s *streamStats) msgInInc() {
@ -57,6 +84,7 @@ func (s *streamStats) Print() {
common.LogInfof("Messages Out: %d\n", s.messageOut) common.LogInfof("Messages Out: %d\n", s.messageOut)
common.LogInfof("Max users in chat: %d\n", s.maxUsers) common.LogInfof("Max users in chat: %d\n", s.maxUsers)
common.LogInfof("Total Time: %s\n", time.Since(s.start)) common.LogInfof("Total Time: %s\n", time.Since(s.start))
common.LogInfof("Max Stream Viewer: %d\n", s.maxViewers)
} }
func (s *streamStats) startStream() { func (s *streamStats) startStream() {
@ -83,3 +111,24 @@ func (s *streamStats) getStreamLength() time.Duration {
} }
return time.Since(s.streamStart) return time.Since(s.streamStart)
} }
func (s *streamStats) getViewerCount() int {
s.mutex.Lock()
defer s.mutex.Unlock()
return len(s.viewers)
}
func (s *streamStats) getMaxViewerCount() int {
s.mutex.Lock()
defer s.mutex.Unlock()
return s.maxViewers
}
func (s *streamStats) getViewers() map[string]string {
s.mutex.Lock()
defer s.mutex.Unlock()
return s.viewers
}