UNTESTED: note trailing zeros in /recordings reply
This commit is contained in:
parent
ecbe86153d
commit
ad35a1ca5e
|
@ -332,6 +332,13 @@ arbitrary order. Each recording object has the following properties:
|
||||||
* `videoSamples`: the number of samples (aka frames) of video in this
|
* `videoSamples`: the number of samples (aka frames) of video in this
|
||||||
recording.
|
recording.
|
||||||
* `sampleFileBytes`: the number of bytes of video in this recording.
|
* `sampleFileBytes`: the number of bytes of video in this recording.
|
||||||
|
* `hasTrailingZero`: the final frame of the final recording id described by
|
||||||
|
this row (`endId` if present, otherwise `startId`) has a duration of 0.
|
||||||
|
A frame's duration is calculated by subtracting its timestamp from the
|
||||||
|
following frame's timestamp. When a run ends, there's no following frame
|
||||||
|
and Moonfire NVR fills in a duration of 0. When using `/view.mp4`, it's
|
||||||
|
not possible to append additional segments after such frames, as noted
|
||||||
|
below.
|
||||||
|
|
||||||
Under the property `videoSampleEntries`, an object mapping ids to objects with
|
Under the property `videoSampleEntries`, an object mapping ids to objects with
|
||||||
the following properties:
|
the following properties:
|
||||||
|
@ -456,8 +463,9 @@ Bugs and limitations:
|
||||||
* The final recording in every "run" ends with a frame that has duration 0.
|
* The final recording in every "run" ends with a frame that has duration 0.
|
||||||
It's not possible to append additional segments after such a frame;
|
It's not possible to append additional segments after such a frame;
|
||||||
the server will return an error like `Invalid argument: unable to append
|
the server will return an error like `Invalid argument: unable to append
|
||||||
recording 2/16672 after recording 2/16671 with trailing zero`.
|
recording 2/16672 after recording 2/16671 with trailing zero`. See also
|
||||||
(See [#178](https://github.com/scottlamb/moonfire-nvr/issues/178).)
|
`hasTrailingZero` above, and
|
||||||
|
[#178](https://github.com/scottlamb/moonfire-nvr/issues/178).
|
||||||
|
|
||||||
### `GET /api/cameras/<uuid>/<stream>/view.mp4.txt`
|
### `GET /api/cameras/<uuid>/<stream>/view.mp4.txt`
|
||||||
|
|
||||||
|
|
|
@ -208,6 +208,7 @@ pub struct ListAggregatedRecordingsRow {
|
||||||
pub open_id: u32,
|
pub open_id: u32,
|
||||||
pub first_uncommitted: Option<i32>,
|
pub first_uncommitted: Option<i32>,
|
||||||
pub growing: bool,
|
pub growing: bool,
|
||||||
|
pub has_trailing_zero: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ListAggregatedRecordingsRow {
|
impl ListAggregatedRecordingsRow {
|
||||||
|
@ -231,6 +232,7 @@ impl ListAggregatedRecordingsRow {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
growing,
|
growing,
|
||||||
|
has_trailing_zero: (row.flags & RecordingFlags::TrailingZero as i32) != 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1352,6 +1354,7 @@ impl LockedDatabase {
|
||||||
let run_start_id = recording_id - row.run_offset;
|
let run_start_id = recording_id - row.run_offset;
|
||||||
let uncommitted = (row.flags & RecordingFlags::Uncommitted as i32) != 0;
|
let uncommitted = (row.flags & RecordingFlags::Uncommitted as i32) != 0;
|
||||||
let growing = (row.flags & RecordingFlags::Growing as i32) != 0;
|
let growing = (row.flags & RecordingFlags::Growing as i32) != 0;
|
||||||
|
let has_trailing_zero = (row.flags & RecordingFlags::TrailingZero as i32) != 0;
|
||||||
use std::collections::btree_map::Entry;
|
use std::collections::btree_map::Entry;
|
||||||
match aggs.entry(run_start_id) {
|
match aggs.entry(run_start_id) {
|
||||||
Entry::Occupied(mut e) => {
|
Entry::Occupied(mut e) => {
|
||||||
|
@ -1396,6 +1399,7 @@ impl LockedDatabase {
|
||||||
a.first_uncommitted = a.first_uncommitted.or(Some(recording_id));
|
a.first_uncommitted = a.first_uncommitted.or(Some(recording_id));
|
||||||
}
|
}
|
||||||
a.growing = growing;
|
a.growing = growing;
|
||||||
|
a.has_trailing_zero = has_trailing_zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Entry::Vacant(e) => {
|
Entry::Vacant(e) => {
|
||||||
|
|
|
@ -493,6 +493,9 @@ pub struct Recording {
|
||||||
|
|
||||||
#[serde(skip_serializing_if = "Not::not")]
|
#[serde(skip_serializing_if = "Not::not")]
|
||||||
pub growing: bool,
|
pub growing: bool,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "Not::not")]
|
||||||
|
pub has_trailing_zero: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
|
|
|
@ -765,6 +765,7 @@ impl Service {
|
||||||
video_samples: row.video_samples,
|
video_samples: row.video_samples,
|
||||||
video_sample_entry_id: row.video_sample_entry_id,
|
video_sample_entry_id: row.video_sample_entry_id,
|
||||||
growing: row.growing,
|
growing: row.growing,
|
||||||
|
has_trailing_zero: row.has_trailing_zero,
|
||||||
});
|
});
|
||||||
if !out
|
if !out
|
||||||
.video_sample_entries
|
.video_sample_entries
|
||||||
|
|
Loading…
Reference in New Issue