Socket
Socket
Sign inDemoInstall

shaka-player

Package Overview
Dependencies
Maintainers
3
Versions
327
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

shaka-player - npm Package Compare versions

Comparing version 2.2.8 to 2.2.9

test/cast/cast_receiver_integration.js

7

externs/shaka/text.js

@@ -305,2 +305,9 @@ /**

/**
* @override
* @exportDoc
*/
shakaExtern.TextDisplayer.prototype.destroy = function() {};
/**
* Append given text cues to the list of cues to be displayed.

@@ -307,0 +314,0 @@ *

12

lib/cast/cast_proxy.js

@@ -515,6 +515,16 @@ /**

if (name == 'getManifest') {
if (this.sender_.isCasting()) {
return function() {
shaka.log.error('getManifest() does not work while casting!');
return null;
};
}
return this.localPlayer_.getManifest.bind(this.localPlayer_);
}
// If we are casting, but the first update has not come in yet, use local
// getters, but not local methods.
if (this.sender_.isCasting() && !this.sender_.hasRemoteProperties()) {
if (shaka.cast.CastUtils.PlayerGetterMethods.indexOf(name) >= 0) {
if (shaka.cast.CastUtils.PlayerGetterMethods[name]) {
var value = /** @type {Object} */(this.localPlayer_)[name];

@@ -521,0 +531,0 @@ goog.asserts.assert(typeof value == 'function', 'only methods on Player');

@@ -78,2 +78,8 @@ /**

/** @private {number} */
this.updateNumber_ = 0;
/** @private {boolean} */
this.startUpdatingUpdateNumber_ = false;
/** @private {cast.receiver.CastMessageBus} */

@@ -193,2 +199,8 @@ this.shakaBus_ = null;

// Do not start excluding values from update messages until the video is
// fully loaded.
this.video_.addEventListener('loadeddata', function() {
this.startUpdatingUpdateNumber_ = true;
}.bind(this));
// Maintain idle state.

@@ -358,10 +370,20 @@ this.player_.addEventListener('loading', function() {

var playerGetters = shaka.cast.CastUtils.PlayerGetterMethods;
if (this.player_.isLive())
playerGetters = playerGetters.concat(
shaka.cast.CastUtils.PlayerGetterMethodsThatRequireLive);
playerGetters.forEach(function(name) {
update['player'][name] = /** @type {Object} */(this.player_)[name]();
}.bind(this));
// TODO: Instead of this variable frequency update system, instead cache the
// previous player state and only send over changed values, with complete
// updates every ~20 updates to account for dropped messages.
if (this.player_.isLive()) {
for (var name in shaka.cast.CastUtils.PlayerGetterMethodsThatRequireLive) {
var frequency =
shaka.cast.CastUtils.PlayerGetterMethodsThatRequireLive[name];
if (this.updateNumber_ % frequency == 0)
update['player'][name] = /** @type {Object} */(this.player_)[name]();
}
}
for (var name in shaka.cast.CastUtils.PlayerGetterMethods) {
var frequency = shaka.cast.CastUtils.PlayerGetterMethods[name];
if (this.updateNumber_ % frequency == 0)
update['player'][name] = /** @type {Object} */(this.player_)[name]();
}
// Volume attributes are tied to the system volume.

@@ -375,2 +397,8 @@ var manager = cast.receiver.CastReceiverManager.getInstance();

// Only start progressing the update number once data is loaded,
// just in case any of the "rarely changing" properties with less frequent
// update messages changes significantly during the loading process.
if (this.startUpdatingUpdateNumber_)
this.updateNumber_ += 1;
this.sendMessage_({

@@ -428,2 +456,6 @@ 'type': 'update',

case 'init':
// Reset update message frequency values after initialization.
this.updateNumber_ = 0;
this.startUpdatingUpdateNumber_ = false;
this.initState_(message['initState'], message['appData']);

@@ -471,2 +503,7 @@ // The sender is supposed to reflect the cast system volume after

var methodName = message['methodName'];
if (targetName == 'player' && methodName == 'load') {
// Reset update message frequency values after a load.
this.updateNumber_ = 0;
this.startUpdatingUpdateNumber_ = false;
}
var args = message['args'];

@@ -549,2 +586,6 @@ var id = message['id'];

case 'LOAD':
// Reset update message frequency values after a load.
this.updateNumber_ = 0;
this.startUpdatingUpdateNumber_ = false;
var mediaInfo = message['media'];

@@ -551,0 +592,0 @@ var contentId = mediaInfo['contentId'];

4

lib/cast/cast_sender.js

@@ -331,3 +331,3 @@ /**

} else if (targetName == 'player') {
if (CastUtils.PlayerGetterMethodsThatRequireLive.indexOf(property) >= 0) {
if (CastUtils.PlayerGetterMethodsThatRequireLive[property]) {
var isLive = this.get('player', 'isLive')();

@@ -347,3 +347,3 @@ goog.asserts.assert(isLive,

}
if (CastUtils.PlayerGetterMethods.indexOf(property) >= 0) {
if (CastUtils.PlayerGetterMethods[property]) {
return this.propertyGetter_.bind(this, targetName, property);

@@ -350,0 +350,0 @@ }

@@ -110,25 +110,27 @@ /**

* Player getter methods that are proxied while casting.
* @const {!Array.<string>}
* The key is the method, the value is the frequency of updates.
* Frequency 1 translates to every update; frequency 2 to every 2 updates, etc.
* @const {!Object.<string, number>}
*/
shaka.cast.CastUtils.PlayerGetterMethods = [
'drmInfo',
'getAudioLanguages',
'getBufferedInfo',
'getConfiguration',
'getExpiration',
'getManifest',
'getManifestUri',
'getPlaybackRate',
'getTextLanguages',
'getTextTracks',
'getStats',
'getVariantTracks',
'isAudioOnly',
'isBuffering',
'isInProgress',
'isLive',
'isTextTrackVisible',
'keySystem',
'seekRange'
];
shaka.cast.CastUtils.PlayerGetterMethods = {
'drmInfo': 20,
'getAudioLanguages': 2,
'getBufferedInfo': 2,
'getConfiguration': 2,
'getExpiration': 2,
// Note that the 'getManifest' property is not proxied, as it is very large.
'getManifestUri': 2,
'getPlaybackRate': 2,
'getTextLanguages': 2,
'getTextTracks': 2,
'getStats': 5,
'getVariantTracks': 2,
'isAudioOnly': 10,
'isBuffering': 1,
'isInProgress': 1,
'isLive': 10,
'isTextTrackVisible': 1,
'keySystem': 10,
'seekRange': 1
};

@@ -139,8 +141,10 @@

* a livestream.
* @const {!Array.<string>}
* The key is the method, the value is the frequency of updates.
* Frequency 1 translates to every update; frequency 2 to every 2 updates, etc.
* @const {!Object.<string, number>}
*/
shaka.cast.CastUtils.PlayerGetterMethodsThatRequireLive = [
'getPlayheadTimeAsDate',
'getPresentationStartTimeAsDate'
];
shaka.cast.CastUtils.PlayerGetterMethodsThatRequireLive = {
'getPlayheadTimeAsDate': 1,
'getPresentationStartTimeAsDate': 20
};

@@ -147,0 +151,0 @@

@@ -316,2 +316,3 @@ /**

var timescale = info.timescale;
var scaledPresentationTimeOffset = info.scaledPresentationTimeOffset;

@@ -324,2 +325,4 @@ var template = info.mediaTemplate;

var find = function(periodTime) {
var segmentTime = periodTime + scaledPresentationTimeOffset;
if (periodTime < 0)

@@ -330,9 +333,13 @@ return null;

return Math.floor(periodTime / segmentDuration);
return Math.floor(segmentTime / segmentDuration);
};
var get = function(position) {
var segmentStart = position * segmentDuration;
var segmentStart =
position * segmentDuration - scaledPresentationTimeOffset;
// Cap the segment end at the period end, to avoid period transition issues
// in StreamingEngine.
var segmentEnd = Math.min(segmentStart + segmentDuration, periodDuration);
// Do not construct segments references that should not exist.
if (segmentStart < 0)
if (segmentEnd < 0)
return null;

@@ -350,4 +357,3 @@ else if (periodDuration && segmentStart >= periodDuration)

return new shaka.media.SegmentReference(
position, segmentStart, segmentStart + segmentDuration, getUris, 0,
null);
position, segmentStart, segmentEnd, getUris, 0, null);
};

@@ -354,0 +360,0 @@

@@ -162,3 +162,2 @@ /**

'video/mp2t; codecs="ec-3"',
'video/mp2t; codecs="mp4a.40.2"',
// WebVTT types

@@ -165,0 +164,0 @@ 'text/vtt',

@@ -47,4 +47,5 @@ /**

goog.asserts.assert(target, 'XHR onload has no target!');
var headers = target.getAllResponseHeaders().split('\r\n').reduce(
// Since IE/Edge incorrectly return the header with a leading new line
// character ('\n'), we trim the header here.
var headers = target.getAllResponseHeaders().trim().split('\r\n').reduce(
function(all, part) {

@@ -51,0 +52,0 @@ /** @type {!Array.<string>} */

@@ -263,2 +263,9 @@ /**

.then(function() {
// Do not hold onto the segment data after it has been stored in the
// database. See https://github.com/google/shaka-player/issues/1167
// Note that an automated regression test for this is not feasible, so
// anyone refactoring this code must take care to manually test memory
// consumption as detailed in the issue comments on github.
segment.segmentDb.data = null;
if (!this.manifest_) {

@@ -265,0 +272,0 @@ return Promise.reject(new shaka.util.Error(

@@ -151,3 +151,3 @@ /**

presentationTimeline: timeline,
minBufferTime: 10,
minBufferTime: 2,
offlineSessionIds: manifest.sessionIds,

@@ -154,0 +154,0 @@ periods: manifest.periods.map(function(period) {

@@ -718,3 +718,4 @@ /**

var sessions = this.drmEngine_.getSessionIds();
if (drmInfo) {
if (drmInfo && this.config_.usePersistentLicense) {
if (!sessions.length) {

@@ -721,0 +722,0 @@ throw new shaka.util.Error(

@@ -223,2 +223,3 @@ /**

/* TODO(#1188): region interface is untested and must be verified
if (window.VTTRegion && shakaCue.region) {

@@ -232,2 +233,3 @@ var region = new VTTRegion();

}
*/

@@ -234,0 +236,0 @@ return vttCue;

@@ -371,2 +371,3 @@ /**

// TODO(#1188): label region units from TTML as pixels, not percentage
var origin = TtmlTextParser.getStyleAttribute_(

@@ -382,2 +383,3 @@ cueElement, region, styles, 'tts:origin');

// TODO(#1188): label region units from TTML as pixels, not percentage
var extent = TtmlTextParser.getStyleAttribute_(

@@ -384,0 +386,0 @@ cueElement, region, styles, 'tts:extent');

@@ -123,2 +123,4 @@ /**

// TODO(#1188): VTT regions are not parsed yet
var id = null;

@@ -125,0 +127,0 @@ var index = text[0].indexOf('-->');

@@ -123,3 +123,5 @@ /**

// http://goo.gl/N6Ff27
shaka.log.error('Uncaught exception in event handler', exception);
shaka.log.error('Uncaught exception in event handler', exception,
exception ? exception.message : null,
exception ? exception.stack : null);
}

@@ -126,0 +128,0 @@

{
"name": "shaka-player",
"description": "DASH/EME video player library",
"version": "2.2.8",
"version": "2.2.9",
"homepage": "https://github.com/google/shaka-player",

@@ -6,0 +6,0 @@ "author": "Google",

@@ -922,9 +922,11 @@ /**

var castMembers =
CastUtils.PlayerVoidMethods.concat(CastUtils.PlayerGetterMethods);
castMembers =
castMembers.concat(CastUtils.PlayerGetterMethodsThatRequireLive);
castMembers.forEach(function(name) {
CastUtils.PlayerVoidMethods.forEach(function(name) {
player[name] = jasmine.createSpy(name);
});
for (var name in CastUtils.PlayerGetterMethods) {
player[name] = jasmine.createSpy(name);
}
for (var name in CastUtils.PlayerGetterMethodsThatRequireLive) {
player[name] = jasmine.createSpy(name);
}
CastUtils.PlayerPromiseMethods.forEach(function(name) {

@@ -931,0 +933,0 @@ player[name] = jasmine.createSpy(name).and.returnValue(Promise.resolve());

@@ -31,2 +31,3 @@ /**

'destroy', // Should use CastProxy.destroy instead
'getManifest', // Too large to proxy

@@ -45,5 +46,7 @@ // Test helper methods (not @export'd)

var castMembers = CastUtils.PlayerVoidMethods
.concat(CastUtils.PlayerGetterMethods)
.concat(CastUtils.PlayerPromiseMethods)
.concat(CastUtils.PlayerGetterMethodsThatRequireLive);
.concat(CastUtils.PlayerPromiseMethods);
for (var name in CastUtils.PlayerGetterMethods)
castMembers.push(name);
for (var name in CastUtils.PlayerGetterMethodsThatRequireLive)
castMembers.push(name);
var playerMembers = Object.keys(shaka.Player.prototype).filter(

@@ -50,0 +53,0 @@ function(name) {

@@ -79,2 +79,45 @@ /**

});
it('honors presentationTimeOffset', function(done) {
var source = Dash.makeSimpleManifestText([
'<SegmentTemplate media="s$Number$.mp4" duration="10"',
' presentationTimeOffset="50" />'
], 30 /* duration */);
// Due to PTO, the first segment is number 6 and position 5.
var references = [
ManifestParser.makeReference('s6.mp4', 5, 0, 10, baseUri),
ManifestParser.makeReference('s7.mp4', 6, 10, 20, baseUri),
ManifestParser.makeReference('s8.mp4', 7, 20, 30, baseUri)
];
Dash.testSegmentIndex(done, source, references);
});
it('handles segments larger than the period', function(done) {
var source = Dash.makeSimpleManifestText([
'<SegmentTemplate media="s$Number$.mp4" duration="60" />'
], 30 /* duration */);
// The first segment is number 1 and position 0.
// Although the segment is 60 seconds long, it is clipped to the period
// duration of 30 seconds.
var references = [
ManifestParser.makeReference('s1.mp4', 0, 0, 30, baseUri)
];
Dash.testSegmentIndex(done, source, references);
});
it('allows negative start times', function(done) {
var source = Dash.makeSimpleManifestText([
'<SegmentTemplate media="s$Number$.mp4" duration="60"',
' presentationTimeOffset="50" />'
], 70 /* duration */);
// Due to PTO, the first segment has a negative start time. It is
// included because it is partially within the period.
var references = [
ManifestParser.makeReference('s1.mp4', 0, -50, 10, baseUri),
ManifestParser.makeReference('s2.mp4', 1, 10, 70, baseUri)
];
Dash.testSegmentIndex(done, source, references);
});
});

@@ -81,0 +124,0 @@

@@ -133,5 +133,5 @@ /**

'com.widevine.alpha':
'http://drm-widevine-licensing.axtest.net/AcquireLicense',
'https://drm-widevine-licensing.axtest.net/AcquireLicense',
'com.microsoft.playready':
'http://drm-playready-licensing.axtest.net/AcquireLicense'
'https://drm-playready-licensing.axtest.net/AcquireLicense'
}

@@ -138,0 +138,0 @@ };

@@ -40,2 +40,7 @@ /**

});
jasmine.Ajax.stubRequest('https://foo.bar/withemptyline').andReturn({
'response': new ArrayBuffer(0),
'status': 200,
'responseHeaders': { '\nFOO': 'BAR' }
});
jasmine.Ajax.stubRequest('https://foo.bar/302').andReturn({

@@ -64,2 +69,3 @@ 'response': new ArrayBuffer(10),

});
jasmine.Ajax.stubRequest('https://foo.bar/timeout').andTimeout();

@@ -105,2 +111,6 @@ jasmine.Ajax.stubRequest('https://foo.bar/error').andError();

it('succeeds with empty line in response', function(done) {
testSucceedsWithEmptyLine('https://foo.bar/withemptyline', done);
});
it('gets redirect URLs with 302 status', function(done) {

@@ -187,3 +197,28 @@ testSucceeds('https://foo.bar/302', done,

}
/**
* Since IE/Edge incorrectly return the header with a leading new line
* character ('\n'), we need to trim the response header.
* @param {string} uri
* @param {function()} done
* @param {string=} opt_overrideUri
*/
function testSucceedsWithEmptyLine(uri, done, opt_overrideUri) {
var request = shaka.net.NetworkingEngine.makeRequest(
[uri], retryParameters);
shaka.net.HttpPlugin(uri, request)
.catch(fail)
.then(function(response) {
expect(jasmine.Ajax.requests.mostRecent().url).toBe(uri);
expect(response).toBeTruthy();
expect(response.uri).toBe(opt_overrideUri || uri);
expect(response.data).toBeTruthy();
expect(response.fromCache).toBe(false);
expect(response.headers).toBeTruthy();
// Returned header names do not contain empty lines.
expect(response.headers['foo']).toBe('BAR');
})
.then(done);
}
});

@@ -24,2 +24,4 @@ /**

var dbEngine;
/** @type {!shaka.util.EventManager} */
var eventManager;
/** @type {!shaka.offline.Storage} */

@@ -54,2 +56,3 @@ var storage;

beforeEach(function(done) {
eventManager = new shaka.util.EventManager();
player = new shaka.Player(video);

@@ -63,5 +66,8 @@ player.addEventListener('error', fail);

afterEach(function(done) {
Promise.all([storage.destroy(), player.destroy(), dbEngine.destroy()])
.catch(fail)
.then(done);
Promise.all([
eventManager.destroy(),
storage.destroy(),
player.destroy(),
dbEngine.destroy()
]).catch(fail).then(done);
});

@@ -200,15 +206,21 @@

function(done) {
if (!support['offline']) {
pending('Offline not supported');
}
// Because this does not rely on persistent licenses, it should be
// testable with PlayReady as well as Widevine.
if (!support['offline'] ||
!support.drm['com.widevine.alpha'] ||
if (!support.drm['com.widevine.alpha'] &&
!support.drm['com.microsoft.playready']) {
pending('Offline or DRM not supported');
pending('Widevine/PlayReady not supported');
}
shaka.test.TestScheme.setupPlayer(player, 'sintel-enc');
// Because we do not need a persistent license, we also do not need init
// data in the manifest. Using this covers issue #1159, where we used
// to throw an error inappropriately.
shaka.test.TestScheme.setupPlayer(player, 'multidrm_no_init_data');
var storedContent;
storage.configure({ usePersistentLicense: false });
storage.store('test:sintel-enc')
storage.store('test:multidrm_no_init_data')
.then(function(content) {

@@ -229,3 +241,3 @@ storedContent = content;

video.play();
return shaka.test.Util.delay(10);
return waitForTime(3);
})

@@ -249,2 +261,23 @@ .then(function() {

});
/**
* @param {number} time
* @return {!Promise}
*/
function waitForTime(time) {
var p = new shaka.util.PublicPromise();
var onTimeUpdate = function() {
if (video.currentTime >= time) {
p.resolve();
}
};
eventManager.listen(video, 'timeupdate', onTimeUpdate);
onTimeUpdate(); // In case we're already there.
var timeout = shaka.test.Util.delay(30).then(function() {
throw 'Timeout waiting for time';
});
return Promise.race([p, timeout]);
}
});

@@ -359,2 +359,42 @@ /**

describe('TextDisplayer plugin', function() {
// Simulate the use of an external TextDisplayer plugin.
var textDisplayer;
beforeEach(function() {
textDisplayer = {
destroy: jasmine.createSpy('destroy'),
append: jasmine.createSpy('append'),
remove: jasmine.createSpy('remove'),
isTextVisible: jasmine.createSpy('isTextVisible'),
setTextVisibility: jasmine.createSpy('setTextVisibility')
};
textDisplayer.destroy.and.returnValue(Promise.resolve());
textDisplayer.isTextVisible.and.returnValue(true);
player.configure({
textDisplayFactory: function() { return textDisplayer; }
});
// Make sure the configuration was taken.
var configuredFactory = player.getConfiguration().textDisplayFactory;
var configuredTextDisplayer = new configuredFactory();
expect(configuredTextDisplayer).toBe(textDisplayer);
});
// Regression test for https://github.com/google/shaka-player/issues/1187
it('does not throw on destroy', function(done) {
player.load('test:sintel_compiled').then(function() {
video.play();
return waitUntilPlayheadReaches(video, 1, 10);
}).then(function() {
return player.unload();
}).then(function() {
// Before we fixed #1187, the call to destroy() on textDisplayer was
// renamed in the compiled version and could not be called.
expect(textDisplayer.destroy).toHaveBeenCalled();
}).catch(fail).then(done);
});
});
/**

@@ -361,0 +401,0 @@ * @param {!HTMLMediaElement} video

@@ -43,3 +43,5 @@ /**

var expectedRef = references[i];
var position = stream.findSegmentPosition(expectedRef.startTime);
// Don't query negative times. Query 0 instead.
var startTime = Math.max(0, expectedRef.startTime);
var position = stream.findSegmentPosition(startTime);
expect(position).not.toBe(null);

@@ -46,0 +48,0 @@ var actualRef =

@@ -94,2 +94,17 @@ /**

goog.asserts.assert(!store[value.key], 'Value must not already exist');
if (value.data) {
// Clone the data and value, so the caller can wipe its version.
var clonedData = null;
if (value.data) {
clonedData = new ArrayBuffer(value.data.byteLength);
(new Uint8Array(clonedData)).set(new Uint8Array(value.data));
}
value = {
key: value.key,
data: clonedData
};
}
store[value.key] = value;

@@ -96,0 +111,0 @@ return Promise.resolve();

@@ -206,5 +206,5 @@ /**

'com.widevine.alpha':
'//drm-widevine-licensing.axtest.net/AcquireLicense',
'https://drm-widevine-licensing.axtest.net/AcquireLicense',
'com.microsoft.playready':
'//drm-playready-licensing.axtest.net/AcquireLicense'
'https://drm-playready-licensing.axtest.net/AcquireLicense'
},

@@ -220,2 +220,39 @@ licenseRequestHeaders: {

duration: 30
},
'multidrm_no_init_data': {
video: {
initSegmentUri: '/base/test/test/assets/multidrm-video-init.mp4',
mvhdOffset: 0x72,
segmentUri: '/base/test/test/assets/multidrm-video-segment.mp4',
tfdtOffset: 0x78,
segmentDuration: 4,
presentationTimeOffset: 0,
mimeType: 'video/mp4',
codecs: 'avc1.64001e'
},
audio: {
initSegmentUri: '/base/test/test/assets/multidrm-audio-init.mp4',
mvhdOffset: 0x72,
segmentUri: '/base/test/test/assets/multidrm-audio-segment.mp4',
tfdtOffset: 0x7c,
segmentDuration: 4,
presentationTimeOffset: 0,
mimeType: 'audio/mp4',
codecs: 'mp4a.40.2'
},
licenseServers: {
'com.widevine.alpha':
'https://drm-widevine-licensing.axtest.net/AcquireLicense',
'com.microsoft.playready':
'https://drm-playready-licensing.axtest.net/AcquireLicense'
},
licenseRequestHeaders: {
'X-AxDRM-Message':
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5' +
'X2lkIjoiNjllNTQwODgtZTllMC00NTMwLThjMWEtMWViNmRjZDBkMTRlIiwibWVzc' +
'2FnZSI6eyJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIj' +
'oiNmU1YTFkMjYtMjc1Ny00N2Q3LTgwNDYtZWFhNWQxZDM0YjVhIn1dfX0.yF7PflO' +
'Pv9qHnu3ZWJNZ12jgkqTabmwXbDWk_47tLNE'
},
duration: 30
}

@@ -222,0 +259,0 @@ };

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc