mirror of
https://github.com/Luzifer/cam2mjpeg.git
synced 2024-11-08 13:40:04 +00:00
Replace mjpeg reader to fix broken frames
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
ce8b98b9cb
commit
e0d5f6a195
2 changed files with 33 additions and 13 deletions
44
main.go
44
main.go
|
@ -3,7 +3,6 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
@ -96,27 +95,46 @@ func main() {
|
|||
|
||||
log.Debug("ffmpeg spawned")
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
var (
|
||||
br, bw int
|
||||
buf = make([]byte, 10*1024*1024) // 10MB (jpg should be smaller)
|
||||
)
|
||||
|
||||
for {
|
||||
if _, err := io.CopyN(buf, out, 1024); err != nil {
|
||||
log.WithError(err).Error("Failed to read ffmpeg output")
|
||||
break
|
||||
// If buffer was read, slide the remains to the beginning
|
||||
if br > 0 {
|
||||
copy(buf, buf[br:bw])
|
||||
bw -= br
|
||||
br = 0
|
||||
}
|
||||
|
||||
eoj := bytes.Index(buf.Bytes(), endOfJPEG)
|
||||
if eoj == -1 {
|
||||
// Fill buffer
|
||||
n, err := out.Read(buf[bw:])
|
||||
if err != nil {
|
||||
log.WithError(err).Fatal("Unable to read from output")
|
||||
}
|
||||
bw += n
|
||||
|
||||
if n == 0 {
|
||||
// Nothing read, try again
|
||||
continue
|
||||
}
|
||||
|
||||
img := buf.Next(eoj + len(endOfJPEG))
|
||||
// Extract as many images as possible before next read
|
||||
for eoj := bytes.Index(buf[br:bw], endOfJPEG); eoj >= 0; eoj = bytes.Index(buf[br:bw], endOfJPEG) {
|
||||
eoj += len(endOfJPEG)
|
||||
img := make([]byte, eoj-br)
|
||||
copy(img, buf[br:br+eoj])
|
||||
|
||||
if !bytes.HasPrefix(img, beginOfJPEG) || !bytes.HasSuffix(img, endOfJPEG) {
|
||||
log.Warn("Found invalid JPEG, skipping")
|
||||
continue
|
||||
br += eoj
|
||||
|
||||
if !bytes.HasPrefix(img, beginOfJPEG) || !bytes.HasSuffix(img, endOfJPEG) {
|
||||
log.Warn("Found invalid JPEG, skipping")
|
||||
continue
|
||||
}
|
||||
|
||||
go sendImage(img)
|
||||
}
|
||||
|
||||
go sendImage(img)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
mjpeg.go
2
mjpeg.go
|
@ -5,6 +5,7 @@ import (
|
|||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/textproto"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
@ -38,6 +39,7 @@ func handleMJPEG(res http.ResponseWriter, r *http.Request, imgs chan []byte, uid
|
|||
err := func() error {
|
||||
partHeader := make(textproto.MIMEHeader)
|
||||
partHeader.Add("Content-Type", "image/jpeg")
|
||||
partHeader.Add("Content-Length", strconv.Itoa(len(img)))
|
||||
|
||||
partWriter, err := mimeWriter.CreatePart(partHeader)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue