From 61ae490a5df7613f0da4e5bac16d28bdf68dc962 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Tue, 13 Oct 2020 00:15:23 +0200 Subject: [PATCH] Make telnet output configurable --- docs/ghostream.example.yml | 17 +++++++++++ internal/config/config.go | 9 ++++++ main.go | 2 ++ stream/telnet/telnet.go | 61 ++++++++++++++++++++++++++++---------- stream/webrtc/ingest.go | 3 +- 5 files changed, 75 insertions(+), 17 deletions(-) diff --git a/docs/ghostream.example.yml b/docs/ghostream.example.yml index d28a95d..3b7d628 100644 --- a/docs/ghostream.example.yml +++ b/docs/ghostream.example.yml @@ -68,6 +68,23 @@ srt: # Max number of active SRT connections #maxClients: 64 +## Telnet server ## +# The telnet server receive the stream and emit the stream as ASCII-art. +telnet: + # By default, this easter egg is disabled. + # You must enable it to use it. + #enable: false + + #listenAddress: :4242 + + # Size is in characters. It is recommended to keep a 16x9 format. + #width: 80 + #height: 45 + + # Time in milliseconds that we should sleep between two images. By default, 20 FPS. Displaying text takes time... + #delay: 50 + + ## Web server ## # The web server serves a WebRTC player. web: diff --git a/internal/config/config.go b/internal/config/config.go index 96e8606..eab8b79 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -3,6 +3,7 @@ package config import ( "bytes" + "gitlab.crans.org/nounous/ghostream/stream/telnet" "log" "net" "strings" @@ -25,6 +26,7 @@ type Config struct { Forwarding forwarding.Options Monitoring monitoring.Options Srt srt.Options + Telnet telnet.Options Web web.Options WebRTC webrtc.Options } @@ -56,6 +58,13 @@ func New() *Config { ListenAddress: ":9710", MaxClients: 64, }, + Telnet: telnet.Options{ + Enabled: false, + ListenAddress: ":4242", + Width: 80, + Height: 45, + Delay: 50, + }, Web: web.Options{ Enabled: true, Favicon: "/static/img/favicon.svg", diff --git a/main.go b/main.go index deb5a12..36815b2 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ package main import ( + "gitlab.crans.org/nounous/ghostream/stream/telnet" "log" "gitlab.crans.org/nounous/ghostream/auth" @@ -50,6 +51,7 @@ func main() { go forwarding.Serve(forwardingChannel, cfg.Forwarding) go monitoring.Serve(&cfg.Monitoring) go srt.Serve(&cfg.Srt, authBackend, forwardingChannel, webrtcChannel) + go telnet.Serve(&cfg.Telnet) go web.Serve(remoteSdpChan, localSdpChan, &cfg.Web) go webrtc.Serve(remoteSdpChan, localSdpChan, webrtcChannel, &cfg.WebRTC) diff --git a/stream/telnet/telnet.go b/stream/telnet/telnet.go index ac58aac..8ad53df 100644 --- a/stream/telnet/telnet.go +++ b/stream/telnet/telnet.go @@ -8,20 +8,34 @@ import ( "time" ) -func asciiChar(pixel byte) string { - asciiChars := []string{"@", "#", "$", "%", "?", "*", "+", ";", ":", ",", "."} - return asciiChars[pixel/25] +var ( + Cfg *Options + currentMessage *string +) + +// Options holds telnet package configuration +type Options struct { + Enabled bool + ListenAddress string + Width int + Height int + Delay int } -// ServeAsciiArt starts a telnet server that send all packets as ASCII Art -func ServeAsciiArt(reader io.Reader) { - listener, err := net.Listen("tcp", ":4242") - if err != nil { - log.Printf("Error while listening to the port 4242: %s", err) +func Serve(config *Options) { + Cfg = config + + if !Cfg.Enabled { return } - currentMessage := "" + listener, err := net.Listen("tcp", Cfg.ListenAddress) + if err != nil { + log.Printf("Error while listening to the address %s: %s", Cfg.ListenAddress, err) + return + } + + currentMessage = new(string) go func() { for { @@ -32,7 +46,7 @@ func ServeAsciiArt(reader io.Reader) { } go func(s net.Conn) { for { - n, err := s.Write([]byte(currentMessage)) + n, err := s.Write([]byte(*currentMessage)) if err != nil { log.Printf("Error while sending TCP data: %s", err) _ = s.Close() @@ -42,13 +56,28 @@ func ServeAsciiArt(reader io.Reader) { _ = s.Close() break } - time.Sleep(50 * time.Millisecond) + time.Sleep(time.Duration(Cfg.Delay) * time.Millisecond) } }(s) } }() - buff := make([]byte, 2048) + log.Println("Telnet server initialized") +} + +func asciiChar(pixel byte) string { + asciiChars := []string{"@", "#", "$", "%", "?", "*", "+", ";", ":", ",", ".", " "} + return asciiChars[(255-pixel)/23] +} + +// ServeAsciiArt starts a telnet server that send all packets as ASCII Art +func ServeAsciiArt(reader io.ReadCloser) { + if !Cfg.Enabled { + _ = reader.Close() + return + } + + buff := make([]byte, Cfg.Width*Cfg.Height) header := "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" for { n, _ := reader.Read(buff) @@ -56,13 +85,13 @@ func ServeAsciiArt(reader io.Reader) { break } imageStr := "" - for j := 0; j < 18; j++ { - for i := 0; i < 32; i++ { - pixel := buff[32*j+i] + for j := 0; j < Cfg.Height; j++ { + for i := 0; i < Cfg.Width; i++ { + pixel := buff[Cfg.Width*j+i] imageStr += asciiChar(pixel) + asciiChar(pixel) } imageStr += "\n" } - currentMessage = header + imageStr + *currentMessage = header + imageStr } } diff --git a/stream/webrtc/ingest.go b/stream/webrtc/ingest.go index 3ba4cb5..5bc9cc5 100644 --- a/stream/webrtc/ingest.go +++ b/stream/webrtc/ingest.go @@ -3,6 +3,7 @@ package webrtc import ( "bufio" + "fmt" "gitlab.crans.org/nounous/ghostream/stream/telnet" "io" "log" @@ -53,7 +54,7 @@ func ingestFrom(inputChannel chan srt.Packet) { "-f", "rtp", "rtp://127.0.0.1:5004", "-vn", "-acodec", "libopus", "-cpu-used", "5", "-deadline", "1", "-qmin", "10", "-qmax", "42", "-error-resilient", "1", "-auto-alt-ref", "1", "-f", "rtp", "rtp://127.0.0.1:5005", - "-an", "-f", "rawvideo", "-vf", "scale=32x18", "-pix_fmt", "gray", "pipe:1") + "-an", "-f", "rawvideo", "-vf", fmt.Sprintf("scale=%dx%d", telnet.Cfg.Width, telnet.Cfg.Height), "-pix_fmt", "gray", "pipe:1") input, err := ffmpeg.StdinPipe() if err != nil {