Add support streaming as ascii to terminal
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
## Stream as ASCII to Terminal
|
||||
|
||||
**Tips**
|
||||
|
||||
- this feature works only with MJPEG codec (use transcoding)
|
||||
- choose a low frame rate (FPS)
|
||||
- choose the width and height to fit in your terminal
|
||||
- different terminals support different numbers of colours (8, 256, rgb)
|
||||
- escape text param with urlencode
|
||||
- you can stream any camera or file from a disc
|
||||
|
||||
**go2rtc.yaml** - transcoding to MJPEG, terminal size - 210x60, fps - 4
|
||||
|
||||
```yaml
|
||||
streams:
|
||||
macarena: ffmpeg:macarena.mp4#video=mjpeg#hardware#width=210#height=60#raw=-r 4
|
||||
```
|
||||
|
||||
**API params**
|
||||
|
||||
- `color` - foreground color, values: empty, `8`, `256`, `rgb`
|
||||
- `back` - background color, values: empty, `8`, `256`, `rgb`
|
||||
- `text` - character set, values: empty, one space, two spaces, anything you like (in order of brightness)
|
||||
|
||||
**Examples**
|
||||
|
||||
```bash
|
||||
% curl "http://192.168.1.123:1984/api/stream.ascii?src=macarena"
|
||||
% curl "http://192.168.1.123:1984/api/stream.ascii?src=macarena&color=256"
|
||||
% curl "http://192.168.1.123:1984/api/stream.ascii?src=macarena&back=256&text=%20"
|
||||
% curl "http://192.168.1.123:1984/api/stream.ascii?src=macarena&back=8&text=%20%20"
|
||||
% curl "http://192.168.1.123:1984/api/stream.ascii?src=macarena&text=helloworld"
|
||||
```
|
||||
+12
-25
@@ -5,12 +5,14 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/AlexxIT/go2rtc/internal/api"
|
||||
"github.com/AlexxIT/go2rtc/internal/api/ws"
|
||||
"github.com/AlexxIT/go2rtc/internal/ffmpeg"
|
||||
"github.com/AlexxIT/go2rtc/internal/streams"
|
||||
"github.com/AlexxIT/go2rtc/pkg/ascii"
|
||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||
"github.com/AlexxIT/go2rtc/pkg/magic"
|
||||
"github.com/AlexxIT/go2rtc/pkg/mjpeg"
|
||||
@@ -21,6 +23,7 @@ import (
|
||||
func Init() {
|
||||
api.HandleFunc("api/frame.jpeg", handlerKeyframe)
|
||||
api.HandleFunc("api/stream.mjpeg", handlerStream)
|
||||
api.HandleFunc("api/stream.ascii", handlerStream)
|
||||
|
||||
ws.HandleFunc("mjpeg", handlerWS)
|
||||
}
|
||||
@@ -99,38 +102,22 @@ func outputMjpeg(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
h := w.Header()
|
||||
h.Set("Content-Type", "multipart/x-mixed-replace; boundary=frame")
|
||||
h.Set("Cache-Control", "no-cache")
|
||||
h.Set("Connection", "close")
|
||||
h.Set("Pragma", "no-cache")
|
||||
|
||||
wr := &writer{wr: w, buf: []byte(header)}
|
||||
_, _ = cons.WriteTo(wr)
|
||||
if strings.HasSuffix(r.URL.Path, "mjpeg") {
|
||||
wr := mjpeg.NewWriter(w)
|
||||
_, _ = cons.WriteTo(wr)
|
||||
} else {
|
||||
cons.Type = "ASCII passive consumer "
|
||||
|
||||
stream.RemoveConsumer(cons)
|
||||
}
|
||||
|
||||
const header = "--frame\r\nContent-Type: image/jpeg\r\nContent-Length: "
|
||||
|
||||
type writer struct {
|
||||
wr io.Writer
|
||||
buf []byte
|
||||
}
|
||||
|
||||
func (w *writer) Write(p []byte) (n int, err error) {
|
||||
w.buf = w.buf[:len(header)]
|
||||
w.buf = append(w.buf, strconv.Itoa(len(p))...)
|
||||
w.buf = append(w.buf, "\r\n\r\n"...)
|
||||
w.buf = append(w.buf, p...)
|
||||
w.buf = append(w.buf, "\r\n"...)
|
||||
|
||||
// Chrome bug: mjpeg image always shows the second to last image
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=527446
|
||||
if n, err = w.wr.Write(w.buf); err == nil {
|
||||
w.wr.(http.Flusher).Flush()
|
||||
query := r.URL.Query()
|
||||
wr := ascii.NewWriter(w, query.Get("color"), query.Get("back"), query.Get("text"))
|
||||
_, _ = cons.WriteTo(wr)
|
||||
}
|
||||
|
||||
return
|
||||
stream.RemoveConsumer(cons)
|
||||
}
|
||||
|
||||
func inputMjpeg(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Reference in New Issue
Block a user