Skip to content
This repository has been archived by the owner on Jan 12, 2019. It is now read-only.

Add a segment-metadata TextTrack that contains cues for the segments currently in the buffer #976

Merged
merged 6 commits into from
Mar 14, 2017

Conversation

mjneil
Copy link
Contributor

@mjneil mjneil commented Jan 24, 2017

Description

Currently, we do not expose or track segment information for the segments that are currently in the actual buffer. Being able to know which segment or rendition is currently being rendered on screen has been a much requested feature. This addition allows users to listen to cuechange events on the track and see the segment information for the currently rendered segment in the active cues list.

Specific Changes proposed

  • Adds a new TextTrack to the tech with the label segment-metadata
  • The Cues in the track directly correspond to the current state of the buffer at a segment level
  • As segments are appended to the buffer, a new cue is added to the track that has start and end times equal to the segment. If the segment being appended overlaps already buffered content, we remove any overlapping cues from the track so that the cues in the track are always the most up to date.
  • whenever data is removed from the buffer, we remove any cues that also fall inside the removed area

Requirements Checklist

  • Feature implemented / Bug fixed
  • Unit Tests updated or fixed
  • Docs/guides updated
  • Reviewed by Two Core Contributors


// for now we don't want the audio segment loader to also add cues to the segment
// metadata track
delete segmentLoaderOptions.segmentMetadataTrack;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to create two different objects.

Perhaps using Object.create to make the mainSegmentLoader_'s object with segmentMetadataTrack added to the base object.

@mjneil mjneil force-pushed the seg-metadata branch 2 times, most recently from d19ef4d to e490c7f Compare February 1, 2017 17:24
end
};
const Cue = window.WebKitDataCue || window.VTTCue;
const data = JSON.stringify(value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be more useful to just merge these properties onto the created cue object.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you mean if say you wanted the uri, accessing it should look like cue.uri instead of cue.value.uri?

* @method addSegmentMetadataCue_
*/
addSegmentMetadataCue_(segmentInfo) {
if (!this.segmentMetadataTrack_ || !segmentInfo) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have to be guarding against these.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right with not needing a check for segmentInfo but i think for check for the track is still needed since both the main and audio segment loaders are instances of this class, but the audio segment loader doesnt have a segment metadata track, so we just want this function to be a noop in that case

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call on checking for segmentMetadataTrack_

const cue = new Cue(start, end, data);

value.data = data;
cue.value = value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So cue ends up with a stringified value for its text, then has a value property which has the value object, including the stringified value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes and no. It mainly depends on the const Cue = window.WebKitDataCue || window.VTTCue; line. I was following what is done in contrib-media-sources when adding id3 tags, but WebKitDataCue is only in safari right now, and there are some small differences between WebKitDataCue and VTTCue. Mainly, WebKitDataCue does not have a text property but instead a value. For id3 tags this value property has a key and data property usually. My goal with these lines was to minimize the differences between the two cues so that you can just use cue.value in all the browsers. After having to explain this, it may just be better to only use VTTCue and not jump through all these hoops

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think keeping Safari support is a good idea (just in case). Maybe a comment and/or some kind of helper method would help.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well VTTCue is supported in safari, its just that WebKitDataCue is only supported in safari. Is it best practice to use these types of cues for certain purposes, or are they more general purpose and its not "wrong" to just use the VTTCue for safari as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deciding to stick with what we do for id3 metadata tags since these cues are another form of metadata

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's ok to do here since it's fairly simple and we're creating metadata tracks.

// verify stats
assert.equal(loader.mediaBytesTransferred, 30, '10 bytes');
assert.equal(loader.mediaRequests, 3, '1 request');
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would also be worth testing the behavior with overlapping times from a different timeline.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a test for overlapping segments is definitely a good call. I don't think being on a different timeline makes a different and needs to be tested. At the point of creating the cues, the start and end times have been converted to display time, so the non-congruent timestamps across discontinuities are not a factor

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

README.md Outdated
### Segment Metadata
You can get metadata about the segments currently in the buffer by using the `segment-metadata`
text track. You can get the metadata of the currently rendered segment by looking at the
tracks `activeCues` array. The metadata will be attached to the `cue.value` property and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

track's

README.md Outdated

```javascript
cue.value = {
uri: The Segment uri,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually for JS blocks it's good to try to keep it as standard JS. Maybe something like:

cue.value = {
  uri, // segment uri
  ...
};

// or:

let data = cue.value;
data.uri; // the segment uri
...

README.md Outdated
```javascript
cue.value = {
uri: The Segment uri,
timeline: Timeline of the segment,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be useful to say what the timeline is

return;
}

const playlist = segmentInfo.playlist;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can get rid of this and just use segmentInfo.playlist.uri below

@mjneil mjneil force-pushed the seg-metadata branch 2 times, most recently from b5ad752 to bac2f7b Compare February 21, 2017 19:56
@gesinger
Copy link
Contributor

gesinger commented Mar 4, 2017

Tested, but with the same code I can't get it working on IE11/Windows 7 (not even getting cuechange events from the segmentMetadataTrack), whereas it works even for Flash (and HTML) on Chrome/Mac.

@forbesjo
Copy link
Contributor

Looks good to me

@mjneil mjneil merged commit ab9a398 into videojs:master Mar 14, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants