mirror of
https://github.com/kerberos-io/agent.git
synced 2026-08-23 15:08:32 +00:00
get rid of snapshots + was blocking stream and corrupted recordings
This commit is contained in:
@@ -7,14 +7,10 @@ package capture
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/jpeg"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
@@ -351,8 +347,6 @@ func (g *Golibrtsp) ConnectBackChannel(ctx context.Context) (err error) {
|
||||
func (g *Golibrtsp) Start(ctx context.Context, queue *packets.Queue, configuration *models.Configuration, communication *models.Communication) (err error) {
|
||||
log.Log.Debug("RTSPClient(Golibrtsp).Start(): started")
|
||||
|
||||
config := configuration.Config
|
||||
|
||||
// called when a MULAW audio RTP packet arrives
|
||||
if g.AudioG711Media != nil {
|
||||
g.Client.OnPacketRTP(g.AudioG711Media, g.AudioG711Forma, func(rtppkt *rtp.Packet) {
|
||||
@@ -515,22 +509,6 @@ func (g *Golibrtsp) Start(ctx context.Context, queue *packets.Queue, configurati
|
||||
|
||||
queue.WritePacket(pkt)
|
||||
|
||||
// Store snapshots (jpg) for hull.
|
||||
// We'll store the last snapshot, so we can use it for hull on the frontend.
|
||||
// But we'll also store the last 10 snapshots, so we can use it for the timelapse.
|
||||
if config.Capture.Snapshots != "false" {
|
||||
image, err := g.DecodePacket(pkt)
|
||||
if err == nil {
|
||||
buffer := new(bytes.Buffer)
|
||||
w := bufio.NewWriter(buffer)
|
||||
err := jpeg.Encode(w, &image, &jpeg.Options{Quality: 15})
|
||||
if err == nil {
|
||||
snapshot := base64.StdEncoding.EncodeToString(buffer.Bytes())
|
||||
communication.Image = snapshot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This will check if we need to stop the thread,
|
||||
// because of a reconfiguration.
|
||||
select {
|
||||
@@ -641,22 +619,6 @@ func (g *Golibrtsp) Start(ctx context.Context, queue *packets.Queue, configurati
|
||||
|
||||
queue.WritePacket(pkt)
|
||||
|
||||
// Store snapshots (jpg) for hull.
|
||||
// We'll store the last snapshot, so we can use it for hull on the frontend.
|
||||
// This will also be used to retrieve the last snapshot from the API.
|
||||
if config.Capture.Snapshots != "false" {
|
||||
image, err := g.DecodePacket(pkt)
|
||||
if err == nil {
|
||||
buffer := new(bytes.Buffer)
|
||||
w := bufio.NewWriter(buffer)
|
||||
err := jpeg.Encode(w, &image, &jpeg.Options{Quality: 15})
|
||||
if err == nil {
|
||||
snapshot := base64.StdEncoding.EncodeToString(buffer.Bytes())
|
||||
communication.Image = snapshot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This will check if we need to stop the thread,
|
||||
// because of a reconfiguration.
|
||||
select {
|
||||
|
||||
@@ -7,6 +7,9 @@ import './ImageCanvas.css';
|
||||
|
||||
class ImageCanvas extends React.Component {
|
||||
componentDidMount() {
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
|
||||
this.loadImage = this.loadImage.bind(this);
|
||||
this.generateRandomTagsDescriptor =
|
||||
this.generateRandomTagsDescriptor.bind(this);
|
||||
@@ -55,14 +58,27 @@ class ImageCanvas extends React.Component {
|
||||
|
||||
const { image } = this.props;
|
||||
this.loadImage(image, (img) => {
|
||||
this.loadData(img);
|
||||
if (this.width !== img.width || this.height !== img.height) {
|
||||
this.width = img.width;
|
||||
this.height = img.height;
|
||||
this.loadData(img);
|
||||
} else {
|
||||
this.editor.addContentSource(img);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { image } = this.props;
|
||||
this.loadImage(image, (img) => {
|
||||
this.loadData(img);
|
||||
if (this.width !== img.width || this.height !== img.height) {
|
||||
this.width = img.width;
|
||||
this.height = img.height;
|
||||
this.loadData(img);
|
||||
} else {
|
||||
// alert('ok');
|
||||
this.editor.addContentSource(img);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ import {
|
||||
} from '@kerberos-io/ui';
|
||||
import { Link, withRouter } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import { interval } from 'rxjs';
|
||||
import { send } from '@giantmachines/redux-websocket';
|
||||
import ImageCanvas from '../../components/ImageCanvas/ImageCanvas';
|
||||
import './Settings.scss';
|
||||
import timezones from './timezones';
|
||||
@@ -121,6 +123,7 @@ class Settings extends React.Component {
|
||||
this.onUpdateToggle = this.onUpdateToggle.bind(this);
|
||||
this.onUpdateNumberField = this.onUpdateNumberField.bind(this);
|
||||
this.onUpdateTimeline = this.onUpdateTimeline.bind(this);
|
||||
this.initialiseLiveview = this.initialiseLiveview.bind(this);
|
||||
this.verifyPersistenceSettings = this.verifyPersistenceSettings.bind(this);
|
||||
this.verifyHubSettings = this.verifyHubSettings.bind(this);
|
||||
this.verifyCameraSettings = this.verifyCameraSettings.bind(this);
|
||||
@@ -144,11 +147,18 @@ class Settings extends React.Component {
|
||||
}));
|
||||
this.calculateTimetable(config.timetable);
|
||||
});
|
||||
this.initialiseLiveview();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('keydown', this.escFunction, false);
|
||||
clearInterval(this.interval);
|
||||
|
||||
const { dispatchSend } = this.props;
|
||||
const message = {
|
||||
message_type: 'stop-sd',
|
||||
};
|
||||
dispatchSend(message);
|
||||
}
|
||||
|
||||
onAddRegion(device, id, polygon) {
|
||||
@@ -227,6 +237,24 @@ class Settings extends React.Component {
|
||||
]);
|
||||
}
|
||||
|
||||
initialiseLiveview() {
|
||||
const message = {
|
||||
message_type: 'stream-sd',
|
||||
};
|
||||
const { connected, dispatchSend } = this.props;
|
||||
if (connected) {
|
||||
dispatchSend(message);
|
||||
}
|
||||
|
||||
const requestStreamInterval = interval(2000);
|
||||
this.requestStreamSubscription = requestStreamInterval.subscribe(() => {
|
||||
const { connected: isConnected } = this.props;
|
||||
if (isConnected) {
|
||||
dispatchSend(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
calculateTimetable(timetable) {
|
||||
this.timetable = timetable;
|
||||
if (this.timetable) {
|
||||
@@ -521,8 +549,8 @@ class Settings extends React.Component {
|
||||
loadingHub,
|
||||
} = this.state;
|
||||
|
||||
const { config: c, t } = this.props;
|
||||
const { config, snapshot } = c;
|
||||
const { config: c, t, images } = this.props;
|
||||
const { config } = c;
|
||||
|
||||
const snapshotBase64 = 'data:image/png;base64,';
|
||||
// Determine which section(s) to be shown, depending on the searching criteria.
|
||||
@@ -1160,9 +1188,9 @@ class Settings extends React.Component {
|
||||
</BlockHeader>
|
||||
<BlockBody>
|
||||
<p>{t('settings.conditions.description_regionofinterest')}</p>
|
||||
{config.region && (
|
||||
{config.region && images && images.length > 0 && (
|
||||
<ImageCanvas
|
||||
image={snapshotBase64 + snapshot}
|
||||
image={snapshotBase64 + images[0]}
|
||||
polygons={config.region.polygon}
|
||||
rendered={false}
|
||||
onAddRegion={this.onAddRegion}
|
||||
@@ -2379,6 +2407,8 @@ class Settings extends React.Component {
|
||||
|
||||
const mapStateToProps = (state /* , ownProps */) => ({
|
||||
config: state.agent.config,
|
||||
connected: state.wss.connected,
|
||||
images: state.wss.images,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch /* , ownProps */) => ({
|
||||
@@ -2397,11 +2427,14 @@ const mapDispatchToProps = (dispatch /* , ownProps */) => ({
|
||||
dispatchAddRegion: (id, polygon) => dispatch(addRegion(id, polygon)),
|
||||
dispatchRemoveRegion: (id, polygon) => dispatch(removeRegion(id, polygon)),
|
||||
dispatchUpdateRegion: (id, polygon) => dispatch(updateRegion(id, polygon)),
|
||||
dispatchSend: (message) => dispatch(send(message)),
|
||||
});
|
||||
|
||||
Settings.propTypes = {
|
||||
t: PropTypes.func.isRequired,
|
||||
connected: PropTypes.bool.isRequired,
|
||||
config: PropTypes.objectOf(PropTypes.object).isRequired,
|
||||
images: PropTypes.array.isRequired,
|
||||
dispatchVerifyHub: PropTypes.func.isRequired,
|
||||
dispatchVerifyPersistence: PropTypes.func.isRequired,
|
||||
dispatchGetConfig: PropTypes.func.isRequired,
|
||||
@@ -2412,6 +2445,7 @@ Settings.propTypes = {
|
||||
dispatchRemoveRegion: PropTypes.func.isRequired,
|
||||
dispatchVerifyCamera: PropTypes.func.isRequired,
|
||||
dispatchVerifyOnvif: PropTypes.func.isRequired,
|
||||
dispatchSend: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default withTranslation()(
|
||||
|
||||
Reference in New Issue
Block a user