Skip to content

Instantly share code, notes, and snippets.

@owulveryck
Created December 20, 2020 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save owulveryck/883faf341b1fe122208cae2d7139c1b0 to your computer and use it in GitHub Desktop.
Save owulveryck/883faf341b1fe122208cae2d7139c1b0 to your computer and use it in GitHub Desktop.
Live picture mjpeg remarkable
package main
import (
"bytes"
"compress/zlib"
"context"
"encoding/gob"
"image"
"image/jpeg"
"log"
"net"
"net/http"
"time"
"github.com/mattn/go-mjpeg"
)
func main() {
var d net.Dialer
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
stream := mjpeg.NewStream()
go func(stream *mjpeg.Stream) {
conn, err := d.DialContext(ctx, "tcp", "192.168.88.192:2000")
if err != nil {
log.Fatalf("Failed to dial: %v", err)
}
defer conn.Close()
r, err := zlib.NewReader(conn)
if err != nil {
log.Fatalf("Failed to dial: %v", err)
}
dec := gob.NewDecoder(r)
var img image.Gray
for ; err == nil; err = dec.Decode(&img) {
var b bytes.Buffer
err := jpeg.Encode(&b, &img, nil)
if err != nil {
log.Fatal(err)
}
err = stream.Update(b.Bytes())
if err != nil {
log.Fatal(err)
}
}
}(stream)
mux := http.NewServeMux()
mux.Handle("/video", stream)
http.ListenAndServe(":8080", mux)
}
package main
import (
"compress/zlib"
"encoding/binary"
"encoding/gob"
"image"
"io"
"log"
"net"
"os"
"time"
)
const (
screenWidth = 1872
screenHeight = 1404
fbAddress = 4387048
)
func main() {
file, err := os.OpenFile(os.Args[1], os.O_RDONLY, os.ModeDevice)
if err != nil {
log.Fatal("cannot open file: ", err)
}
defer file.Close()
addr, err := getPointer(file, fbAddress)
if err != nil {
log.Fatal(err)
}
log.Println("Address is: ", addr)
// Listen on TCP port 2000 on all available unicast and
// anycast IP addresses of the local system.
log.Println("listening on tcp 2000")
l, err := net.Listen("tcp", ":2000")
if err != nil {
log.Fatal(err)
}
defer l.Close()
pixels := make([]byte, screenHeight*screenWidth)
tick := time.NewTicker(10 * time.Millisecond)
img := &image.Gray{
Pix: pixels,
Stride: screenWidth,
Rect: image.Rect(0, 0, screenWidth, screenHeight),
}
for {
// Wait for a connection.
conn, err := l.Accept()
if err != nil {
log.Fatal(err)
}
w := zlib.NewWriter(conn)
enc := gob.NewEncoder(w)
for ; ; <-tick.C {
_, err := file.ReadAt(pixels, addr)
if err != nil {
log.Fatal(err)
}
err = enc.Encode(img)
if err != nil {
log.Fatal(err)
}
}
}
}
func getPointer(r io.ReaderAt, offset int64) (int64, error) {
pointer := make([]byte, 4)
_, err := r.ReadAt(pointer, offset)
if err != nil {
return 0, err
}
return int64(binary.LittleEndian.Uint32(pointer)), nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment