Compare commits

...

4 Commits

Author SHA1 Message Date
Cedric Verstraeten
2feda33808 joy4 v1.0.51 2023-02-11 20:52:36 +01:00
Cedric Verstraeten
ec42b9ea85 update timescale to 90000 2023-02-11 12:27:38 +01:00
Cedric Verstraeten
a2b4ee12ec align timescale to 90000 2023-02-11 12:02:04 +01:00
Cedric Verstraeten
a0f99a5167 add two new variables to disable snapshotting (encoding time) + disable motion 2023-02-07 13:55:38 +01:00
5 changed files with 46 additions and 39 deletions

View File

@@ -2,7 +2,7 @@ module github.com/kerberos-io/agent/machinery
go 1.19
//replace github.com/kerberos-io/joy4 v1.0.50 => ../../../../github.com/kerberos-io/joy4
//replace github.com/kerberos-io/joy4 v1.0.51 => ../../../../github.com/kerberos-io/joy4
//replace github.com/kerberos-io/onvif v0.0.5 => ../../../../github.com/kerberos-io/onvif
require (

View File

@@ -244,6 +244,12 @@ func OverrideWithEnvironmentVariables(configuration *models.Configuration) {
case "AGENT_CAPTURE_CONTINUOUS":
configuration.Config.Capture.Continuous = value
break
case "AGENT_CAPTURE_MOTION":
configuration.Config.Capture.Motion = value
break
case "AGENT_CAPTURE_SNAPSHOTS":
configuration.Config.Capture.Snapshots = value
break
case "AGENT_CAPTURE_PRERECORDING":
duration, err := strconv.ParseInt(value, 10, 64)
if err == nil {

View File

@@ -39,12 +39,7 @@ func ProcessMotion(motionCursor *pubsub.QueueCursor, configuration *models.Confi
pixelThreshold = 150
}
if config.Capture.Recording == "false" {
// We might later add the option to still detect motion, but not record.
log.Log.Info("ProcessMotion: Recording disabled, so we do not need motion detection either.")
} else if config.Capture.Continuous == "true" {
if config.Capture.Continuous == "true" {
log.Log.Info("ProcessMotion: Continuous recording, so no motion detection.")
@@ -134,23 +129,25 @@ func ProcessMotion(motionCursor *pubsub.QueueCursor, configuration *models.Confi
}
// Store snapshots (jpg) for hull.
files, err := ioutil.ReadDir("./data/snapshots")
if err == nil {
rgbImage, err := GetRawImage(frame, pkt, decoder, decoderMutex)
if config.Capture.Snapshots != "false" {
files, err := ioutil.ReadDir("./data/snapshots")
if err == nil {
sort.Slice(files, func(i, j int) bool {
return files[i].ModTime().Before(files[j].ModTime())
})
if len(files) > 3 {
os.Remove("./data/snapshots/" + files[0].Name())
}
// Save image
t := strconv.FormatInt(time.Now().Unix(), 10)
f, err := os.Create("./data/snapshots/" + t + ".jpg")
rgbImage, err := GetRawImage(frame, pkt, decoder, decoderMutex)
if err == nil {
jpeg.Encode(f, &rgbImage.Image, &jpeg.Options{Quality: 15})
f.Close()
sort.Slice(files, func(i, j int) bool {
return files[i].ModTime().Before(files[j].ModTime())
})
if len(files) > 3 {
os.Remove("./data/snapshots/" + files[0].Name())
}
// Save image
t := strconv.FormatInt(time.Now().Unix(), 10)
f, err := os.Create("./data/snapshots/" + t + ".jpg")
if err == nil {
jpeg.Encode(f, &rgbImage.Image, &jpeg.Options{Quality: 15})
f.Close()
}
}
}
}
@@ -178,26 +175,29 @@ func ProcessMotion(motionCursor *pubsub.QueueCursor, configuration *models.Confi
}
}
// Remember additional information about the result of findmotion
isPixelChangeThresholdReached, changesToReturn = FindMotion(imageArray, coordinatesToCheck, pixelThreshold)
if config.Capture.Motion != "false" {
if detectMotion && isPixelChangeThresholdReached {
// Remember additional information about the result of findmotion
isPixelChangeThresholdReached, changesToReturn = FindMotion(imageArray, coordinatesToCheck, pixelThreshold)
if detectMotion && isPixelChangeThresholdReached {
if mqttClient != nil {
mqttClient.Publish("kerberos/"+key+"/device/"+config.Key+"/motion", 2, false, "motion")
if mqttClient != nil {
mqttClient.Publish("kerberos/"+key+"/device/"+config.Key+"/motion", 2, false, "motion")
}
if config.Capture.Recording != "false" {
dataToPass := models.MotionDataPartial{
Timestamp: time.Now().Unix(),
NumberOfChanges: changesToReturn,
}
communication.HandleMotion <- dataToPass //Save data to the channel
}
}
//FIXME: In the future MotionDataPartial should be replaced with MotionDataFull
dataToPass := models.MotionDataPartial{
Timestamp: time.Now().Unix(),
NumberOfChanges: changesToReturn,
}
communication.HandleMotion <- dataToPass //Save data to the channel
imageArray[0] = imageArray[1]
imageArray[1] = imageArray[2]
i++
}
imageArray[0] = imageArray[1]
imageArray[1] = imageArray[2]
i++
}
if img != nil {
@@ -239,7 +239,6 @@ func GetRawImage(frame *ffmpeg.VideoFrame, pkt av.Packet, dec *ffmpeg.VideoDecod
func ImageToBytes(img image.Image) ([]byte, error) {
buffer := new(bytes.Buffer)
w := bufio.NewWriter(buffer)
//err := jpeg.Encode(w, img, &jpeg.EncoderOptions{Quality: 70})
err := jpeg.Encode(w, img, &jpeg.Options{Quality: 15})
return buffer.Bytes(), err
}

View File

@@ -51,6 +51,8 @@ type Capture struct {
RaspiCamera RaspiCamera `json:"raspicamera"`
Recording string `json:"recording,omitempty"`
Continuous string `json:"continuous,omitempty"`
Snapshots string `json:"snapshots,omitempty"`
Motion string `json:"motion,omitempty"`
PostRecording int64 `json:"postrecording"`
PreRecording int64 `json:"prerecording"`
MaxLengthRecording int64 `json:"maxlengthrecording"`

View File

@@ -253,7 +253,7 @@ func CreateFragmentedMP4(fullName string, fragmentedDuration int64) {
path, _ := os.Getwd()
duration := fragmentedDuration * 1000
// This timescale is crucial, as it should be the same as the one defined in JOY4.
cmd := exec.Command("mp4fragment", "--timescale", "10000", "--fragment-duration", strconv.FormatInt(duration, 10), fullName, fullName+"f.mp4")
cmd := exec.Command("mp4fragment", "--timescale", "90000", "--fragment-duration", strconv.FormatInt(duration, 10), fullName, fullName+"f.mp4")
cmd.Dir = path
log.Log.Info(cmd.String())
var out bytes.Buffer