Skip to content

Commit 1c282a3

Browse files
authored
feat: toJSON methods for text track serialization (videojs#8998)
1 parent 8842d37 commit 1c282a3

File tree

7 files changed

+128
-7
lines changed

7 files changed

+128
-7
lines changed

src/css/components/_volume.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@
160160
}
161161
}
162162

163-
// here
164163
// Update placement of circle icon when using SVG icons
165164
.vjs-slider-horizontal .vjs-volume-level .vjs-svg-icon {
166165
right: -0.3em;

src/js/tracks/text-track-list-converter.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* A serializable javascript representation of the TextTrack.
1919
* @private
2020
*/
21-
const trackToJson_ = function(track) {
21+
const trackToJson = function(track) {
2222
const ret = [
2323
'kind', 'label', 'language', 'id',
2424
'inBandMetadataTrackDispatchType', 'mode', 'src'
@@ -61,7 +61,7 @@ const textTracksToJson = function(tech) {
6161

6262
const trackObjs = Array.prototype.map.call(trackEls, (t) => t.track);
6363
const tracks = Array.prototype.map.call(trackEls, function(trackEl) {
64-
const json = trackToJson_(trackEl.track);
64+
const json = trackToJson(trackEl.track);
6565

6666
if (trackEl.src) {
6767
json.src = trackEl.src;
@@ -71,7 +71,7 @@ const textTracksToJson = function(tech) {
7171

7272
return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function(track) {
7373
return trackObjs.indexOf(track) === -1;
74-
}).map(trackToJson_));
74+
}).map(trackToJson));
7575
};
7676

7777
/**
@@ -97,4 +97,4 @@ const jsonToTextTracks = function(json, tech) {
9797
return tech.textTracks();
9898
};
9999

100-
export default {textTracksToJson, jsonToTextTracks, trackToJson_};
100+
export default {textTracksToJson, jsonToTextTracks, trackToJson};

src/js/tracks/text-track-list.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,15 @@ class TextTrackList extends TrackList {
5656
}
5757
}
5858
}
59+
60+
/**
61+
* Creates a serializable array of objects that contains serialized copies
62+
* of each text track.
63+
*
64+
* @return {Object[]} A serializable list of objects for the text track list
65+
*/
66+
toJSON() {
67+
return this.tracks_.map((track) => track.toJSON());
68+
}
5969
}
6070
export default TextTrackList;

src/js/tracks/text-track.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {TextTrackKind, TextTrackMode} from './track-enums';
77
import log from '../utils/log.js';
88
import window from 'global/window';
99
import Track from './track.js';
10+
import textTrackConverter from './text-track-list-converter.js';
1011
import { isCrossOrigin } from '../utils/url.js';
1112
import XHR from '@videojs/xhr';
1213
import {merge} from '../utils/obj';
@@ -420,6 +421,16 @@ class TextTrack extends Track {
420421
this.cues.setCues_(this.cues_);
421422
}
422423

424+
/**
425+
* Creates a copy of the text track and makes it serializable
426+
* by removing circular dependencies.
427+
*
428+
* @return {Object} The track information as a serializable object
429+
*/
430+
toJSON() {
431+
return textTrackConverter.trackToJson(this);
432+
}
433+
423434
/**
424435
* Remove a cue from our internal list
425436
*

test/unit/tracks/text-track-list-converter.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ if (Html5.supportsNativeTextTracks()) {
3232
track.srclang = 'en';
3333
track.label = 'English';
3434

35-
assert.deepEqual(cleanup(c.trackToJson_(track.track)), {
35+
assert.deepEqual(cleanup(c.trackToJson(track.track)), {
3636
kind: 'captions',
3737
label: 'English',
3838
language: 'en',
@@ -181,7 +181,7 @@ QUnit.test('trackToJson_ produces correct representation for emulated track obje
181181
}
182182
});
183183

184-
assert.deepEqual(cleanup(c.trackToJson_(track)), {
184+
assert.deepEqual(cleanup(c.trackToJson(track)), {
185185
src: 'example.com/english.vtt',
186186
kind: 'captions',
187187
label: 'English',

test/unit/tracks/text-track-list.test.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,46 @@ QUnit.test('trigger "change" event when mode changes on a TextTrack', function(a
6060
ttl.removeTrack(tt);
6161
tech.dispose();
6262
});
63+
64+
QUnit.test('toJSON', function(assert) {
65+
const tech = new TechFaker();
66+
const ttl = new TextTrackList([]);
67+
68+
let textTrackListJSON = ttl.toJSON();
69+
70+
assert.ok(textTrackListJSON.length === 0, 'an empty array is returned when the list is empty');
71+
72+
const tt1 = new TextTrack({tech});
73+
74+
ttl.addTrack(tt1);
75+
textTrackListJSON = ttl.toJSON();
76+
77+
assert.equal(textTrackListJSON[0].id, tt1.id, 'text track in array of JSON should match the original track');
78+
assert.notOk(textTrackListJSON[0].tech_, 'tech_ should not exist on the text track value in the JSON list');
79+
80+
const tt2 = new TextTrack({tech});
81+
const tt3 = new TextTrack({tech});
82+
83+
ttl.addTrack(tt2);
84+
ttl.addTrack(tt3);
85+
textTrackListJSON = ttl.toJSON();
86+
87+
assert.equal(textTrackListJSON[1].id, tt2.id, 'text track in second spot of array should match the original track');
88+
assert.equal(textTrackListJSON[2].id, tt3.id, 'text track in third spot of array should match the original track');
89+
});
90+
91+
QUnit.test('serialize', function(assert) {
92+
const tech = new TechFaker();
93+
const tt1 = new TextTrack({tech});
94+
const tt2 = new TextTrack({tech});
95+
const tt3 = new TextTrack({tech});
96+
const ttl = new TextTrackList([tt1, tt2, tt3]);
97+
98+
const serializedTrackList = JSON.stringify(ttl);
99+
100+
assert.notOk(serializedTrackList.includes('"tech_":'), 'tech_ does not exist in the serialized data');
101+
102+
assert.ok(serializedTrackList.includes(`"id":"${tt1.id}"`), 'serialzed track is found for text track 1');
103+
assert.ok(serializedTrackList.includes(`"id":"${tt2.id}"`), 'serialzed track is found for text track 2');
104+
assert.ok(serializedTrackList.includes(`"id":"${tt3.id}"`), 'serialzed track is found for text track 3');
105+
});

test/unit/tracks/text-track.test.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,3 +746,61 @@ QUnit.test('stops processing if vttjs loading errored out', function(assert) {
746746
testTech.off();
747747
log.error = oldLogError;
748748
});
749+
750+
QUnit.test('toJSON', function(assert) {
751+
const tt = new TextTrack({
752+
tech: this.tech
753+
});
754+
755+
tt.addCue({
756+
id: '1',
757+
startTime: 1,
758+
endTime: 2.555
759+
});
760+
tt.addCue({
761+
id: '2',
762+
startTime: 2.555,
763+
endTime: 2.555
764+
});
765+
766+
const jsonTrack = tt.toJSON();
767+
768+
// Properties we want copied are copied correctly
769+
assert.equal(tt.id, jsonTrack.id, 'the id for the copied track stayed the same');
770+
assert.equal(tt.mode, jsonTrack.mode, 'the mode for the copied track stayed the same');
771+
assert.equal(tt.kind, jsonTrack.kind, 'the kind for the copied track stayed the same');
772+
773+
// The tech_ property stays on the original track, but is removed from the copy
774+
assert.ok(tt.tech_, 'the tech exists on the original track');
775+
assert.notOk(jsonTrack.tech_, 'the tech does not exist on the copied track');
776+
});
777+
778+
QUnit.test('serialize', function(assert) {
779+
const tt = new TextTrack({
780+
tech: this.tech
781+
});
782+
783+
tt.addCue({
784+
id: '1',
785+
startTime: 1,
786+
endTime: 2.555
787+
});
788+
tt.addCue({
789+
id: '2',
790+
startTime: 2.555,
791+
endTime: 2.555
792+
});
793+
794+
const serializedTrack = JSON.stringify(tt);
795+
796+
// Ensure tech was not removed from the actual track
797+
assert.ok(tt.tech_, 'the tech exists on the original track');
798+
799+
// Values from the track should be found in the serialized string
800+
assert.ok(serializedTrack.includes(`"id":"${tt.id}"`), 'serialized data should include id');
801+
assert.ok(serializedTrack.includes(`"mode":"${tt.mode}"`), 'serialized data should include mode');
802+
assert.ok(serializedTrack.includes(`"kind":"${tt.kind}"`), 'serialized data should include cues');
803+
804+
// tech_ should not be found in the serialized string
805+
assert.notOk(serializedTrack.includes('"tech_":'), 'serialized data should not include tech_');
806+
});

0 commit comments

Comments
 (0)