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:
Scott Lamb
2020-03-13 21:20:51 -07:00
parent 317a620e6e
commit 3968bfe912
8 changed files with 141 additions and 136 deletions

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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) +

View File

@@ -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;