-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
issue/3619 CMCD #3662
issue/3619 CMCD #3662
Conversation
…haka-player into issue/3619-cmcd # Conflicts: # externs/shaka/player.js
Visual Studio Code has different formatting rules than the Shaka project. This can be overridden by adding custom settings via the .vscode/settings.json file. This folder should not be committed.
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall. Just a few comments. Thanks!
externs/shaka/player.js
Outdated
* A GUID identifying the current playback session. A playback session | ||
* typically ties together segments belonging to a single media asset. | ||
* Maximum length is 64 characters. It is RECOMMENDED to conform to the UUID | ||
* specification. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we please add a note that by default, we will generate a session ID for you on each load()
call?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The doc for the sessionId
config property have been updated.
lib/hls/hls_parser.js
Outdated
@@ -1488,7 +1493,7 @@ shaka.hls.HlsParser = class { | |||
pixelAspectRatio: undefined, | |||
width: undefined, | |||
height: undefined, | |||
bandwidth: undefined, | |||
bandwidth: bandwidth, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bandwidth in HLS is really only known at the Variant level, not for individual streams.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change has been reverted.
lib/hls/hls_parser.js
Outdated
fullRequest, | ||
type, | ||
reference instanceof shaka.media.InitSegmentReference, | ||
reference.endTime - reference.startTime, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm not mistaken, InitSegmentReference doesn't have start and end times. Is it okay for this argument to modifySegmentReference to be NaN?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the serialization function will ignore NaN
, null
, undefined
and ''
values.
lib/player.js
Outdated
@@ -7,6 +7,7 @@ | |||
goog.provide('shaka.Player'); | |||
|
|||
goog.require('goog.asserts'); | |||
goog.require('shaka.util.CmcdManager'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Please alphabetize these requirements
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alphabetized
lib/util/cmcd_manager.js
Outdated
*/ | ||
configure(config) { | ||
this.config_ = config; | ||
this.sid_ = config.sessionId || window.crypto.randomUUID(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other components, configure() is something that can be called multiple times during the life of the component, to update the config. Here, CMCD config is locked in once playback starts in load().
It isn't necessarily a problem that the config is locked in for playback, but if that's the case, I suggest you move the config to the constructor. That way, someone doesn't later call this component's configure() method from Player's configure() to update the config, triggering changes to the session ID mid-playback.
Alternately, if you write a unit test on Player that proves that configure() of CmcdManager is only called once during load(), and not during subsequent configure() calls, that would suffice to prevent mistakes, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cmcd configuration has been moved into the constructor
lib/util/cmcd_manager.js
Outdated
*/ | ||
getObjectType_(type, init, mimeType, codecs) { | ||
if (type == 'text' && mimeType === 'text/vtt') { | ||
return shaka.util.CmcdManager.ObjectType.CAPTION; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is "caption" really spec'd to mean "VTT" in CMCD?
I thought the meaning of caption was something like CC/CEA608 for the deaf, where as everything else was subtitles (for the hearing, but in another language).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spec defines two text related object types:
c
= caption or subtitlett
= ISOBMFF timed text track
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then it sounds like this condition is completely unnecessary. You already have a check for type == 'text' below. This extra condition at the top is redundant with that one, and would also suppress INIT
type for the init segments of text streams embedded in MP4.
lib/util/cmcd_manager.js
Outdated
if (mimeType === 'application/mp4') { | ||
return shaka.util.CmcdManager.ObjectType.TIMED_TEXT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If "TIMED_TEXT" corresponds to TTML, then this seems wrong. Both VTT and TTML can appear in mp4 containers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is my understanding that TIMED_TEXT
refers to text based content delivered via a container, and CAPTION
refers to text based content delivered via a text file.
case 'video/webm': | ||
case 'video/mp4': | ||
return shaka.util.CmcdManager.ObjectType.MUXED; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is meant by "muxed"? Does that imply audio & video together in the stream?
What about TS containers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MUXED
refers to a segment that contains both audio and video. This function is only called when src
is being used to load the video, which would be mp4 and web files, and hls manifests in Safari. Are there any others that are missing?
lib/util/cmcd_manager.js
Outdated
for (const range of ranges) { | ||
if (range.start < start) { | ||
start = range.start; | ||
} | ||
if (range.end > end) { | ||
end = range.end; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the ranges are sorted and disjoint. So if the list is non-empty, you should be able to do start = ranges[0].start
and end = ranges.pop().end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wilaw Is the value of bl
supposed to represent just the forward buffer, or the entire buffer length?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, forward buffer only. And only the immediate contiguous range in front of the current playhead, in the case that you have a multi-part forward buffer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The getBufferLength_
function has been updated.
const stream = variant[type] || variant; | ||
if (stream.bandwidth > top.bandwidth) { | ||
top = stream; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For HLS compatibility, I believe you should be using variant.bandwidth instead of stream.bandwidth.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We originally used the variant bandwidth. This was flagged as an error during the spec compliance testing because the top bitrate didn't match any of the values in the manifest (because the variant bandwidth is an aggregate). This is why we first look for the specific value from variant.video.bandwidth
and variant.audio.bandwidth
, then fallback to variant.bandwidth
.
lib/util/cmcd_manager.js
Outdated
*/ | ||
getObjectType_(type, init, mimeType, codecs) { | ||
if (type == 'text' && mimeType === 'text/vtt') { | ||
return shaka.util.CmcdManager.ObjectType.CAPTION; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then it sounds like this condition is completely unnecessary. You already have a check for type == 'text' below. This extra condition at the top is redundant with that one, and would also suppress INIT
type for the init segments of text streams embedded in MP4.
return NaN; | ||
} | ||
|
||
return (range.end - start) * 1000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a utility for this that you might want to use instead: shaka.media.TimeRangesUtils
return shaka.media.TimeRangesUtils.bufferedAheadOf(video.buffered, video.currentTime);
It wouldn't cover text, though, so feel free to keep this implementation if you like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left the getBufferInfo_
calculation as is so that text buffers are covered. The redundant conditional in getObjectType_
has been removed.
Looks good, but there seems to be a merge conflict. Can you take a look? |
Resolved. |
All tests passed! |
Thank you for your contribution! |
When I tried to run Shaka Player tests via HTTP with this feature, all lot of them (~100) fail on:
Previously, there was no such issue. @joeyparrish, is it a regression or expected behaviour? Should it be possible to run tests via HTTP? Or maybe HTTPS is the only supported protocol? |
It should be possible to run tests over HTTP. There should be two paths to making this work:
If the polyfill is not working on plain HTTP pages, please file a bug and we can investigate. Thanks! |
I tried the first path (localhost), but it didn't work. I guess that my browser (Tizen TV) does not support randomUUID API so switching to a secure context does not help. It seems that polyfill is not installed properly, see my patch: ppaneksamsung@b0d760e. |
@joeyparrish, Congratulations on the latest release! |
In semantic versioning, new features require a minor release, which would put CMCD support in v3.3. With updates pushed to all existing release branches yesterday, I'm working on the new v3.3.x branch and v3.3.0 release today (though the process may spill into next week). |
@joeyparrish Thank you very much!! Extremely appreciated - ViacomCBS team. |
Description
Add support for including Common Media Client Data (CMCD) in outgoing requests.
Fixes #3619.
Type of change
not work as expected)
Checklist:
./build/all.py
and the build passes./build/test.py
and all tests pass