mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-11-20 01:50:24 -05:00
reorganize /recordings JSON response
I want to start returning the pixel aspect ratio of each video sample entry. It's silly to duplicate it for each returned recording, so let's instead return a videoSampleEntryId and then put all the information about each VSE once. This change doesn't actually handle pixel aspect ratio server-side yet. Most likely I'll require a new schema version for that, to store it as a new column in the database. Codec-specific logic in the database layer is awkward and I'd like to avoid it. I did a similar schema change to add the rfc6381_codec. I also adjusted ui-src/lib/models/Recording.js in a few ways: * fixed a couple mismatches between its field name and the key defined in the API. Consistency aids understanding. * dropped all the getters in favor of just setting the fields (with type annotations) as described here: https://google.github.io/styleguide/jsguide.html#features-classes-fields * where the wire format used undefined (to save space), translate it to a more natural null or false.
This commit is contained in:
@@ -111,10 +111,10 @@ export default class MoonfireAPI {
|
||||
videoPlayUrl(cameraUUID, streamType, recording, trimmedRange,
|
||||
timestampTrack = true) {
|
||||
let sParam = recording.startId;
|
||||
if (recording.endId !== undefined) {
|
||||
if (recording.endId !== null) {
|
||||
sParam += '-' + recording.endId;
|
||||
}
|
||||
if (recording.firstUncommitted !== undefined) {
|
||||
if (recording.firstUncommitted !== null) {
|
||||
sParam += '@' + recording.openId; // disambiguate.
|
||||
}
|
||||
let rel = '';
|
||||
@@ -124,7 +124,7 @@ export default class MoonfireAPI {
|
||||
rel += '-';
|
||||
if (recording.endTime90k > trimmedRange.endTime90k) {
|
||||
rel += trimmedRange.endTime90k - recording.startTime90k;
|
||||
} else if (recording.growing !== undefined) {
|
||||
} else if (recording.growing) {
|
||||
// View just the portion described by recording.
|
||||
rel += recording.endTime90k - recording.startTime90k;
|
||||
}
|
||||
|
||||
@@ -39,51 +39,46 @@ export default class Recording {
|
||||
/**
|
||||
* Accept JSON data to be encapsulated
|
||||
*
|
||||
* @param {object} recordingJson JSON for a recording
|
||||
* @param {object} recordingJson JSON for a recording
|
||||
* @param {object} videoSampleEntryJson JSON for a video sample entry
|
||||
*/
|
||||
constructor(recordingJson) {
|
||||
this.json_ = recordingJson;
|
||||
}
|
||||
constructor(recordingJson, videoSampleEntryJson) {
|
||||
/** @const {!number} */
|
||||
this.startId = recordingJson.startId;
|
||||
|
||||
/** @return {Number} */
|
||||
get startId() {
|
||||
return this.json_.startId;
|
||||
}
|
||||
/** @const {?number} */
|
||||
this.endId = recordingJson.endId !== undefined ? recordingJson.endId : null;
|
||||
|
||||
/** @return {Number} */
|
||||
get endId() {
|
||||
return this.json_.endId;
|
||||
}
|
||||
/** @const {!number} */
|
||||
this.openId = recordingJson.openId;
|
||||
|
||||
/** @return {Number} */
|
||||
get openId() {
|
||||
return this.json_.openId;
|
||||
}
|
||||
/** @const {?number} */
|
||||
this.firstUncommitted = recordingJson.firstUncommitted !== undefined
|
||||
? recordingJson.firstUncommitted : null;
|
||||
|
||||
/** @return {Number} or undefined */
|
||||
get firstUncommitted() {
|
||||
return this.json_.firstUncommitted;
|
||||
}
|
||||
/** @const {!boolean} */
|
||||
this.growing = recordingJson.growing || false;
|
||||
|
||||
/** @return {Boolean} or undefined */
|
||||
get growing() {
|
||||
return this.json_.growing;
|
||||
}
|
||||
/** @const {!number} */
|
||||
this.startTime90k = recordingJson.startTime90k;
|
||||
|
||||
/**
|
||||
* Return start time of recording in 90k units.
|
||||
* @return {Number} Time in units of 90k parts of a second
|
||||
*/
|
||||
get startTime90k() {
|
||||
return this.json_.startTime90k;
|
||||
}
|
||||
/** @const {!number} */
|
||||
this.endTime90k = recordingJson.endTime90k;
|
||||
|
||||
/**
|
||||
* Return end time of recording in 90k units.
|
||||
* @return {Number} Time in units of 90k parts of a second
|
||||
*/
|
||||
get endTime90k() {
|
||||
return this.json_.endTime90k;
|
||||
/** @const {!number} */
|
||||
this.sampleFileBytes = recordingJson.sampleFileBytes;
|
||||
|
||||
/** @const {!number} */
|
||||
this.videoSamples = recordingJson.videoSamples;
|
||||
|
||||
/** @const {!string} */
|
||||
this.videoSampleEntrySha1 = videoSampleEntryJson.sha1;
|
||||
|
||||
/** @const {!number} */
|
||||
this.videoSampleEntryWidth = videoSampleEntryJson.width;
|
||||
|
||||
/** @const {!number} */
|
||||
this.videoSampleEntryHeight = videoSampleEntryJson.height;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +86,7 @@ export default class Recording {
|
||||
* @return {Number} Time in units of 90k parts of a second
|
||||
*/
|
||||
get duration90k() {
|
||||
return this.json_.endTime90k - this.json_.startTime90k;
|
||||
return this.endTime90k - this.startTime90k;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,49 +107,4 @@ export default class Recording {
|
||||
get duration() {
|
||||
return this.duration90k / 90000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of bytes used by sample storage.
|
||||
*
|
||||
* @return {Number} Total bytes used
|
||||
*/
|
||||
get sampleFileBytes() {
|
||||
return this.json_.sampleFileBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of video samples (frames) for the recording.
|
||||
*
|
||||
* @return {Number} Total bytes used
|
||||
*/
|
||||
get frameCount() {
|
||||
return this.json_.videoSamples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the has for the video samples.
|
||||
*
|
||||
* @return {String} Hash
|
||||
*/
|
||||
get videoSampleEntryHash() {
|
||||
return this.json_.videoSampleEntrySha1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of the frame(s) of the video samples.
|
||||
*
|
||||
* @return {Number} Width in pixels
|
||||
*/
|
||||
get videoSampleEntryWidth() {
|
||||
return this.json_.videoSampleEntryWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the frame(s) of the video samples.
|
||||
*
|
||||
* @return {Number} Height in pixels
|
||||
*/
|
||||
get videoSampleEntryHeight() {
|
||||
return this.json_.videoSampleEntryHeight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ export default class RecordingFormatter {
|
||||
recording.videoSampleEntryWidth +
|
||||
'x' +
|
||||
recording.videoSampleEntryHeight,
|
||||
frameRate: frameRateFmt.format(recording.frameCount / duration),
|
||||
frameRate: frameRateFmt.format(recording.videoSamples / duration),
|
||||
size: sizeFmt.format(recording.sampleFileBytes / 1048576) + ' MB',
|
||||
rate:
|
||||
sizeFmt.format(recording.sampleFileBytes / duration * 0.000008) +
|
||||
|
||||
@@ -256,13 +256,14 @@ export default class RecordingsView {
|
||||
*
|
||||
* The data is expected to be an array with recording objects.
|
||||
*
|
||||
* @param {String} recordingsJSON JSON data (array)
|
||||
* @param {object} recordingsJSON JSON data (object)
|
||||
*/
|
||||
set recordingsJSON(recordingsJSON) {
|
||||
this.showLoading = false;
|
||||
// Store as model objects
|
||||
this._recordings = recordingsJSON.map(function(r) {
|
||||
return new Recording(r);
|
||||
this._recordings = recordingsJSON.recordings.map(function(r) {
|
||||
const vse = recordingsJSON.videoSampleEntries[r.videoSampleEntryId];
|
||||
return new Recording(r, vse);
|
||||
});
|
||||
|
||||
const tbody = this._element;
|
||||
|
||||
Reference in New Issue
Block a user