mirror of
https://github.com/gen2brain/cam2ip.git
synced 2025-12-15 20:08:30 +00:00
Remove video
This commit is contained in:
@@ -1,6 +1,3 @@
|
|||||||
//go:build !cv2 && !cv4
|
|
||||||
// +build !cv2,!cv4
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
//go:build cv2 || cv4
|
|
||||||
// +build cv2 cv4
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/jamiealquiza/envy"
|
|
||||||
|
|
||||||
"github.com/gen2brain/cam2ip/camera"
|
|
||||||
"github.com/gen2brain/cam2ip/server"
|
|
||||||
"github.com/gen2brain/cam2ip/video"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
name = "cam2ip"
|
|
||||||
version = "1.6"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
srv := server.NewServer()
|
|
||||||
|
|
||||||
flag.IntVar(&srv.Index, "index", 0, "Camera index")
|
|
||||||
flag.IntVar(&srv.Delay, "delay", 10, "Delay between frames, in milliseconds")
|
|
||||||
flag.Float64Var(&srv.FrameWidth, "width", 640, "Frame width")
|
|
||||||
flag.Float64Var(&srv.FrameHeight, "height", 480, "Frame height")
|
|
||||||
flag.IntVar(&srv.Rotate, "rotate", 0, "Rotate image, valid values are 90, 180, 270")
|
|
||||||
flag.BoolVar(&srv.NoWebGL, "nowebgl", false, "Disable WebGL drawing of images (html handler)")
|
|
||||||
flag.BoolVar(&srv.Timestamp, "timestamp", false, "Draws timestamp on images")
|
|
||||||
flag.StringVar(&srv.Bind, "bind-addr", ":56000", "Bind address")
|
|
||||||
flag.StringVar(&srv.Htpasswd, "htpasswd-file", "", "Path to htpasswd file, if empty auth is disabled")
|
|
||||||
flag.StringVar(&srv.FileName, "video-file", "", "Use video file instead of camera")
|
|
||||||
|
|
||||||
envy.Parse("CAM2IP")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
srv.Name = name
|
|
||||||
srv.Version = version
|
|
||||||
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if srv.Htpasswd != "" {
|
|
||||||
if _, err = os.Stat(srv.Htpasswd); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if srv.FileName != "" {
|
|
||||||
if _, err = os.Stat(srv.FileName); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if srv.FileName != "" {
|
|
||||||
vid, err := video.New(video.Options{srv.FileName, srv.Rotate})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
srv.Reader = vid
|
|
||||||
} else {
|
|
||||||
cam, err := camera.New(camera.Options{srv.Index, srv.Rotate, srv.FrameWidth, srv.FrameHeight, srv.Timestamp})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
srv.Reader = cam
|
|
||||||
}
|
|
||||||
|
|
||||||
defer srv.Reader.Close()
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Listening on %s\n", srv.Bind)
|
|
||||||
|
|
||||||
err = srv.ListenAndServe()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
//go:build cv2 && !cv4
|
|
||||||
// +build cv2,!cv4
|
|
||||||
|
|
||||||
// Package video.
|
|
||||||
package video
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"image"
|
|
||||||
|
|
||||||
"github.com/disintegration/imaging"
|
|
||||||
"github.com/go-opencv/go-opencv/opencv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Options.
|
|
||||||
type Options struct {
|
|
||||||
Filename string
|
|
||||||
Rotate int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Video represents video.
|
|
||||||
type Video struct {
|
|
||||||
opts Options
|
|
||||||
video *opencv.Capture
|
|
||||||
frame *opencv.IplImage
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns new Video for given path.
|
|
||||||
func New(opts Options) (video *Video, err error) {
|
|
||||||
video = &Video{}
|
|
||||||
video.opts = opts
|
|
||||||
|
|
||||||
video.video = opencv.NewFileCapture(opts.Filename)
|
|
||||||
if video.video == nil {
|
|
||||||
err = fmt.Errorf("video: can not open video %s", opts.Filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads next frame from video and returns image.
|
|
||||||
func (v *Video) Read() (img image.Image, err error) {
|
|
||||||
if v.video.GrabFrame() {
|
|
||||||
v.frame = v.video.RetrieveFrame(1)
|
|
||||||
if v.frame == nil {
|
|
||||||
err = fmt.Errorf("video: can not retrieve frame")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
img = v.frame.ToImage()
|
|
||||||
if v.opts.Rotate == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch v.opts.Rotate {
|
|
||||||
case 90:
|
|
||||||
img = imaging.Rotate90(img)
|
|
||||||
case 180:
|
|
||||||
img = imaging.Rotate180(img)
|
|
||||||
case 270:
|
|
||||||
img = imaging.Rotate270(img)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("video: can not grab frame")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes video.
|
|
||||||
func (v *Video) Close() (err error) {
|
|
||||||
if v.video == nil {
|
|
||||||
err = fmt.Errorf("video: video is not opened")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
v.frame.Release()
|
|
||||||
v.video.Release()
|
|
||||||
v.video = nil
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
//go:build cv4 && !cv2
|
|
||||||
// +build cv4,!cv2
|
|
||||||
|
|
||||||
// Package video.
|
|
||||||
package video
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"image"
|
|
||||||
|
|
||||||
"github.com/disintegration/imaging"
|
|
||||||
"gocv.io/x/gocv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Options.
|
|
||||||
type Options struct {
|
|
||||||
Filename string
|
|
||||||
Rotate int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Video represents video.
|
|
||||||
type Video struct {
|
|
||||||
opts Options
|
|
||||||
video *gocv.VideoCapture
|
|
||||||
frame *gocv.Mat
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns new Video for given path.
|
|
||||||
func New(opts Options) (video *Video, err error) {
|
|
||||||
video = &Video{}
|
|
||||||
video.opts = opts
|
|
||||||
|
|
||||||
mat := gocv.NewMat()
|
|
||||||
video.frame = &mat
|
|
||||||
|
|
||||||
video.video, err = gocv.VideoCaptureFile(opts.Filename)
|
|
||||||
if err != nil {
|
|
||||||
err = fmt.Errorf("video: can not open video %s: %s", opts.Filename, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads next frame from video and returns image.
|
|
||||||
func (v *Video) Read() (img image.Image, err error) {
|
|
||||||
ok := v.video.Read(v.frame)
|
|
||||||
if !ok {
|
|
||||||
err = fmt.Errorf("video: can not grab frame")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.frame == nil {
|
|
||||||
err = fmt.Errorf("video: can not retrieve frame")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
img, e := v.frame.ToImage()
|
|
||||||
if e != nil {
|
|
||||||
err = fmt.Errorf("video: %v", e)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.opts.Rotate == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch v.opts.Rotate {
|
|
||||||
case 90:
|
|
||||||
img = imaging.Rotate90(img)
|
|
||||||
case 180:
|
|
||||||
img = imaging.Rotate180(img)
|
|
||||||
case 270:
|
|
||||||
img = imaging.Rotate270(img)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes video.
|
|
||||||
func (v *Video) Close() (err error) {
|
|
||||||
if v.video == nil {
|
|
||||||
err = fmt.Errorf("video: video is not opened")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
v.frame.Close()
|
|
||||||
err = v.video.Close()
|
|
||||||
v.video = nil
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package video
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"image/jpeg"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestVideo(t *testing.T) {
|
|
||||||
video, err := New(video.Options{"test.mp4", 0})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer video.Close()
|
|
||||||
|
|
||||||
tmpdir, err := ioutil.TempDir(os.TempDir(), "cam2ip")
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
|
|
||||||
var i int
|
|
||||||
var n int = 10
|
|
||||||
|
|
||||||
timeout := time.After(time.Duration(n) * time.Second)
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-timeout:
|
|
||||||
//fmt.Printf("Fps: %d\n", i/n)
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
img, err := video.Read()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := os.Create(filepath.Join(tmpdir, fmt.Sprintf("%03d.jpg", i)))
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = jpeg.Encode(file, img, &jpeg.Options{Quality: 75})
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = file.Close()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user