-
Notifications
You must be signed in to change notification settings - Fork 426
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
feat: setup EME key systems for HLS as well as DASH #629
Changes from all commits
d4fc059
8bf40bf
3dd7d48
dba0c52
df9cfed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ import { | |
import { version } from '../package.json'; | ||
// import needed to register middleware | ||
import './middleware-set-current-time'; | ||
import { isAudioCodec, isVideoCodec, parseContentType } from './util/codecs'; | ||
|
||
const Hls = { | ||
PlaylistLoader, | ||
|
@@ -140,18 +141,54 @@ Hls.canPlaySource = function() { | |
'your player\'s techOrder.'); | ||
}; | ||
|
||
const emeKeySystems = (keySystemOptions, videoPlaylist, audioPlaylist) => { | ||
const emeKeySystems = (keySystemOptions, mainSegmentLoader, audioSegmentLoader) => { | ||
if (!keySystemOptions) { | ||
return keySystemOptions; | ||
} | ||
|
||
let videoMimeType; | ||
let audioMimeType; | ||
|
||
// if there is a mimeType associated with the audioSegmentLoader, then the audio | ||
// and video mimeType and codec strings are already in the format we need to | ||
// pass with the other key systems | ||
if (audioSegmentLoader.mimeType_) { | ||
videoMimeType = mainSegmentLoader.mimeType_; | ||
gkatsev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
audioMimeType = audioSegmentLoader.mimeType_; | ||
|
||
// if there is no audioSegmentLoader mimeType, then we have to create the | ||
// the audio and video mimeType/codec strings from information extrapolated | ||
// from the mainSegmentLoader mimeType (ex. 'video/mp4; codecs="mp4, avc1"' --> | ||
// 'video/mp4; codecs="avc1"' and 'audio/mp4; codecs="mp4"') | ||
} else { | ||
const parsedMimeType = parseContentType(mainSegmentLoader.mimeType_); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know if we will see this behavior in the wild, but it is possible that, with |
||
const codecs = parsedMimeType.parameters.codecs.split(','); | ||
|
||
let audioCodec; | ||
let videoCodec; | ||
|
||
codecs.forEach(codec => { | ||
codec = codec.trim(); | ||
|
||
if (isAudioCodec(codec)) { | ||
brandonocasey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
audioCodec = codec; | ||
} else if (isVideoCodec(codec)) { | ||
videoCodec = codec; | ||
} | ||
}); | ||
|
||
videoMimeType = `${parsedMimeType.type}; codecs="${videoCodec}"`; | ||
audioMimeType = `${parsedMimeType.type.replace('video', 'audio')}; codecs="${audioCodec}"`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We must have gotten away with it before because we haven't seen DRM protected audio/video only streams, but we may want to consider that possibility. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, we did just recently get a question about that. I think, for now, we can continue not supporting it, but definitely something we should fix eventually. |
||
} | ||
|
||
// upsert the content types based on the selected playlist | ||
const keySystemContentTypes = {}; | ||
const videoPlaylist = mainSegmentLoader.playlist_; | ||
|
||
for (let keySystem in keySystemOptions) { | ||
keySystemContentTypes[keySystem] = { | ||
audioContentType: `audio/mp4; codecs="${audioPlaylist.attributes.CODECS}"`, | ||
videoContentType: `video/mp4; codecs="${videoPlaylist.attributes.CODECS}"` | ||
audioContentType: audioMimeType, | ||
videoContentType: videoMimeType | ||
}; | ||
|
||
if (videoPlaylist.contentProtection && | ||
|
@@ -172,16 +209,16 @@ const emeKeySystems = (keySystemOptions, videoPlaylist, audioPlaylist) => { | |
}; | ||
|
||
const setupEmeOptions = (hlsHandler) => { | ||
if (hlsHandler.options_.sourceType !== 'dash') { | ||
return; | ||
} | ||
const mainSegmentLoader = hlsHandler.masterPlaylistController_.mainSegmentLoader_; | ||
const audioSegmentLoader = hlsHandler.masterPlaylistController_.audioSegmentLoader_; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this work for both muxed and umuxed content? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean by "this"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current changes really. Specifically, with muxed audio, we don't have a separate audio segment loader. We should make sure that this works in either case, or at least, doesn't break existing streams. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I guess it's unlikely to break existing streams because dash is always unmuxed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the content is muxed, then |
||
|
||
const player = videojs.players[hlsHandler.tech_.options_.playerId]; | ||
|
||
if (player.eme) { | ||
const sourceOptions = emeKeySystems( | ||
hlsHandler.source_.keySystems, | ||
hlsHandler.playlists.media(), | ||
hlsHandler.masterPlaylistController_.mediaTypes_.AUDIO.activePlaylistLoader.media() | ||
mainSegmentLoader, | ||
audioSegmentLoader | ||
); | ||
|
||
if (sourceOptions) { | ||
|
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.
Since mainSegmentLoader and audioSegmentLoader are only used for their mimeType_ properties and the mainSegmentLoader's playlist for contentProtection, it might simplify the function to just accept those as parameters (audioMimeType, videoMimeType, and contentProtection). Can even make a function with the first part of this function's logic to do the initial work of getting the mime types from the loaders and then pass the result in directly.