1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-04 10:19:24 +02:00
Daniel Neto 2023-10-25 10:14:46 -03:00
parent b6d47e94c8
commit 65f15c7e46
2882 changed files with 382239 additions and 10785 deletions

View file

@ -9,6 +9,7 @@ import {
import { stringToMpdXml } from '../src/stringToMpdXml';
import errors from '../src/errors';
import QUnit from 'qunit';
import { stub } from 'sinon';
import { toPlaylists } from '../src/toPlaylists';
import decodeB64ToUint8Array from '@videojs/vhs-utils/es/decode-b64-to-uint8-array';
import { findChildren } from '../src/utils/xml';
@ -16,23 +17,23 @@ import { findChildren } from '../src/utils/xml';
QUnit.module('buildBaseUrls');
QUnit.test('returns reference urls when no BaseURL nodes', function(assert) {
const reference = ['https://example.com/', 'https://foo.com/'];
const reference = [{ baseUrl: 'https://example.com/' }, { baseUrl: 'https://foo.com/' }];
assert.deepEqual(buildBaseUrls(reference, []), reference, 'returns reference urls');
});
QUnit.test('single reference url with single BaseURL node', function(assert) {
const reference = ['https://example.com'];
const reference = [{ baseUrl: 'https://example.com' }];
const node = [{ textContent: 'bar/' }];
const expected = ['https://example.com/bar/'];
const expected = [{ baseUrl: 'https://example.com/bar/' }];
assert.deepEqual(buildBaseUrls(reference, node), expected, 'builds base url');
});
QUnit.test('multiple reference urls with single BaseURL node', function(assert) {
const reference = ['https://example.com/', 'https://foo.com/'];
const reference = [{ baseUrl: 'https://example.com/' }, { baseUrl: 'https://foo.com/' }];
const node = [{ textContent: 'bar/' }];
const expected = ['https://example.com/bar/', 'https://foo.com/bar/'];
const expected = [{ baseUrl: 'https://example.com/bar/' }, { baseUrl: 'https://foo.com/bar/' }];
assert.deepEqual(
buildBaseUrls(reference, node), expected,
@ -41,36 +42,38 @@ QUnit.test('multiple reference urls with single BaseURL node', function(assert)
});
QUnit.test('multiple BaseURL nodes with single reference url', function(assert) {
const reference = ['https://example.com/'];
const reference = [{ baseUrl: 'https://example.com/' }];
const nodes = [{ textContent: 'bar/' }, { textContent: 'baz/' }];
const expected = ['https://example.com/bar/', 'https://example.com/baz/'];
const expected = [{ baseUrl: 'https://example.com/bar/' }, { baseUrl: 'https://example.com/baz/' }];
assert.deepEqual(buildBaseUrls(reference, nodes), expected, 'base url for each node');
});
QUnit.test('multiple reference urls with multiple BaseURL nodes', function(assert) {
const reference = ['https://example.com/', 'https://foo.com/', 'http://example.com'];
const reference = [
{ baseUrl: 'https://example.com/' }, { baseUrl: 'https://foo.com/' }, { baseUrl: 'http://example.com' }
];
const nodes =
[{ textContent: 'bar/' }, { textContent: 'baz/' }, { textContent: 'buzz/' }];
const expected = [
'https://example.com/bar/',
'https://example.com/baz/',
'https://example.com/buzz/',
'https://foo.com/bar/',
'https://foo.com/baz/',
'https://foo.com/buzz/',
'http://example.com/bar/',
'http://example.com/baz/',
'http://example.com/buzz/'
{ baseUrl: 'https://example.com/bar/' },
{ baseUrl: 'https://example.com/baz/' },
{ baseUrl: 'https://example.com/buzz/' },
{ baseUrl: 'https://foo.com/bar/' },
{ baseUrl: 'https://foo.com/baz/' },
{ baseUrl: 'https://foo.com/buzz/' },
{ baseUrl: 'http://example.com/bar/' },
{ baseUrl: 'http://example.com/baz/' },
{ baseUrl: 'http://example.com/buzz/' }
];
assert.deepEqual(buildBaseUrls(reference, nodes), expected, 'creates all base urls');
});
QUnit.test('absolute BaseURL overwrites reference', function(assert) {
const reference = ['https://example.com'];
const reference = [{ baseUrl: 'https://example.com' }];
const node = [{ textContent: 'https://foo.com/bar/' }];
const expected = ['https://foo.com/bar/'];
const expected = [{ baseUrl: 'https://foo.com/bar/'}];
assert.deepEqual(
buildBaseUrls(reference, node), expected,
@ -78,6 +81,40 @@ QUnit.test('absolute BaseURL overwrites reference', function(assert) {
);
});
QUnit.test('reference attributes are ignored when there is a BaseURL node', function(assert) {
const reference = [{ baseUrl: 'https://example.com', attributes: [{ name: 'test', value: 'wow' }] }];
const node = [{ textContent: 'https://foo.com/bar/' }];
const expected = [{ baseUrl: 'https://foo.com/bar/' }];
assert.deepEqual(
buildBaseUrls(reference, node), expected,
'baseURL attributes are not included'
);
});
QUnit.test('BasURL attributes are still added with a reference', function(assert) {
const reference = [{ baseUrl: 'https://example.com' }];
const node = [{ textContent: 'https://foo.com/bar/', attributes: [{ name: 'test', value: 'wow' }] }];
const expected = [{ baseUrl: 'https://foo.com/bar/', test: 'wow' }];
assert.deepEqual(
buildBaseUrls(reference, node), expected,
'baseURL attributes are included'
);
});
QUnit.test('attributes are replaced when both reference and BaseURL have the same attributes', function(assert) {
const reference = [{ baseUrl: 'https://example.com', attributes: [{ name: 'test', value: 'old' }] }];
const node = [{ textContent: 'https://foo.com/bar/', attributes: [{ name: 'test', value: 'new' }] }];
const expected = [{ baseUrl: 'https://foo.com/bar/', test: 'new' }];
assert.deepEqual(
buildBaseUrls(reference, node), expected,
'baseURL attributes are included'
);
});
QUnit.module('getPeriodStart');
QUnit.test('gets period start when available', function(assert) {
@ -546,6 +583,7 @@ QUnit.test('end to end - basic', function(assert) {
`), { NOW });
const expected = {
contentSteeringInfo: null,
eventStream: [],
locations: undefined,
representationInfo: [{
@ -593,6 +631,82 @@ QUnit.test('end to end - basic', function(assert) {
assert.deepEqual(actual, expected);
});
QUnit.test('end to end - basic using manifest uri', function(assert) {
const NOW = Date.now();
const actual = inheritAttributes(stringToMpdXml(`
<MPD mediaPresentationDuration="PT30S" >
<BaseURL>base/</BaseURL>
<Period>
<AdaptationSet mimeType="video/mp4" >
<Role value="main"></Role>
<SegmentTemplate></SegmentTemplate>
<Representation
bandwidth="5000000"
codecs="avc1.64001e"
height="404"
id="test"
width="720">
</Representation>
</AdaptationSet>
<AdaptationSet mimeType="text/vtt" lang="en">
<Representation bandwidth="256" id="en">
<BaseURL>en.vtt</BaseURL>
</Representation>
</AdaptationSet>
</Period>
</MPD>
`), { NOW, manifestUri: 'https://www.test.com' });
const expected = {
contentSteeringInfo: null,
eventStream: [],
locations: undefined,
representationInfo: [{
attributes: {
bandwidth: 5000000,
baseUrl: 'https://www.test.com/base/',
codecs: 'avc1.64001e',
height: 404,
id: 'test',
mediaPresentationDuration: 30,
mimeType: 'video/mp4',
periodStart: 0,
role: {
value: 'main'
},
sourceDuration: 30,
type: 'static',
width: 720,
NOW,
clientOffset: 0
},
segmentInfo: {
template: {}
}
}, {
attributes: {
bandwidth: 256,
baseUrl: 'https://www.test.com/base/en.vtt',
id: 'en',
lang: 'en',
mediaPresentationDuration: 30,
mimeType: 'text/vtt',
periodStart: 0,
role: {},
sourceDuration: 30,
type: 'static',
NOW,
clientOffset: 0
},
segmentInfo: {}
}]
};
assert.equal(actual.representationInfo.length, 2);
assert.deepEqual(actual, expected);
});
QUnit.test('end to end - basic dynamic', function(assert) {
const NOW = Date.now();
@ -621,6 +735,7 @@ QUnit.test('end to end - basic dynamic', function(assert) {
`), { NOW });
const expected = {
contentSteeringInfo: null,
eventStream: [],
locations: undefined,
representationInfo: [{
@ -666,6 +781,303 @@ QUnit.test('end to end - basic dynamic', function(assert) {
assert.deepEqual(actual, expected);
});
QUnit.test('end to end - content steering - non resolvable base URLs', function(assert) {
const NOW = Date.now();
const actual = inheritAttributes(stringToMpdXml(`
<MPD type="dyanmic">
<ContentSteering defaultServiceLocation="beta" queryBeforeStart="false" proxyServerURL="http://127.0.0.1:3455/steer">https://example.com/app/url</ContentSteering>
<BaseURL serviceLocation="alpha">https://cdn1.example.com/</BaseURL>
<BaseURL serviceLocation="beta">https://cdn2.example.com/</BaseURL>
<Period start="PT0S">
<AdaptationSet mimeType="video/mp4">
<Role value="main"></Role>
<SegmentTemplate></SegmentTemplate>
<Representation
bandwidth="5000000"
codecs="avc1.64001e"
height="404"
id="test"
width="720">
</Representation>
</AdaptationSet>
<AdaptationSet mimeType="text/vtt" lang="en">
<Representation bandwidth="256" id="en">
<BaseURL>https://example.com/en.vtt</BaseURL>
</Representation>
</AdaptationSet>
</Period>
</MPD>
`), { NOW, manifestUri: 'https://www.test.com' });
// Note that we expect to see the `contentSteeringInfo` object set with the
// proper values. We also expect to see the `serviceLocation` property set to
// the correct values inside of the correct representations.
const expected = {
contentSteeringInfo: {
defaultServiceLocation: 'beta',
proxyServerURL: 'http://127.0.0.1:3455/steer',
queryBeforeStart: false,
serverURL: 'https://example.com/app/url'
},
eventStream: [],
locations: undefined,
representationInfo: [
{
attributes: {
NOW,
bandwidth: 5000000,
baseUrl: 'https://cdn1.example.com/',
clientOffset: 0,
codecs: 'avc1.64001e',
height: 404,
id: 'test',
mimeType: 'video/mp4',
periodStart: 0,
role: {
value: 'main'
},
serviceLocation: 'alpha',
sourceDuration: 0,
type: 'dyanmic',
width: 720
},
segmentInfo: {
template: {}
}
},
{
attributes: {
NOW,
bandwidth: 5000000,
baseUrl: 'https://cdn2.example.com/',
clientOffset: 0,
codecs: 'avc1.64001e',
height: 404,
id: 'test',
mimeType: 'video/mp4',
periodStart: 0,
role: {
value: 'main'
},
serviceLocation: 'beta',
sourceDuration: 0,
type: 'dyanmic',
width: 720
},
segmentInfo: {
template: {}
}
},
{
attributes: {
NOW,
bandwidth: 256,
baseUrl: 'https://example.com/en.vtt',
clientOffset: 0,
id: 'en',
lang: 'en',
mimeType: 'text/vtt',
periodStart: 0,
role: {},
sourceDuration: 0,
type: 'dyanmic'
},
segmentInfo: {}
},
{
attributes: {
NOW,
bandwidth: 256,
baseUrl: 'https://example.com/en.vtt',
clientOffset: 0,
id: 'en',
lang: 'en',
mimeType: 'text/vtt',
periodStart: 0,
role: {},
sourceDuration: 0,
type: 'dyanmic'
},
segmentInfo: {}
}
]
};
assert.equal(actual.representationInfo.length, 4);
assert.deepEqual(actual, expected);
});
QUnit.test('end to end - content steering - resolvable base URLs', function(assert) {
const NOW = Date.now();
const actual = inheritAttributes(stringToMpdXml(`
<MPD type="dyanmic">
<ContentSteering defaultServiceLocation="beta" queryBeforeStart="false" proxyServerURL="http://127.0.0.1:3455/steer">https://example.com/app/url</ContentSteering>
<BaseURL serviceLocation="alpha">https://cdn1.example.com/</BaseURL>
<BaseURL serviceLocation="beta">https://cdn2.example.com/</BaseURL>
<Period start="PT0S">
<AdaptationSet mimeType="video/mp4">
<Role value="main"></Role>
<SegmentTemplate></SegmentTemplate>
<Representation
bandwidth="5000000"
codecs="avc1.64001e"
height="404"
id="test"
width="720">
</Representation>
<BaseURL>/video</BaseURL>
</AdaptationSet>
<AdaptationSet mimeType="text/vtt" lang="en">
<Representation bandwidth="256" id="en">
<BaseURL>/vtt</BaseURL>
</Representation>
</AdaptationSet>
</Period>
</MPD>
`), { NOW, manifestUri: 'https://www.test.com' });
// Note that we expect to see the `contentSteeringInfo` object set with the
// proper values. We also expect to see the `serviceLocation` property set to
// the correct values inside of the correct representations.
//
// Also note that some of the representations have '/video' appended
// to the end of the baseUrls
const expected = {
contentSteeringInfo: {
defaultServiceLocation: 'beta',
proxyServerURL: 'http://127.0.0.1:3455/steer',
queryBeforeStart: false,
serverURL: 'https://example.com/app/url'
},
eventStream: [],
locations: undefined,
representationInfo: [
{
attributes: {
NOW,
bandwidth: 5000000,
baseUrl: 'https://cdn1.example.com/video',
clientOffset: 0,
codecs: 'avc1.64001e',
height: 404,
id: 'test',
mimeType: 'video/mp4',
periodStart: 0,
role: {
value: 'main'
},
serviceLocation: 'alpha',
sourceDuration: 0,
type: 'dyanmic',
width: 720
},
segmentInfo: {
template: {}
}
},
{
attributes: {
NOW,
bandwidth: 5000000,
baseUrl: 'https://cdn2.example.com/video',
clientOffset: 0,
codecs: 'avc1.64001e',
height: 404,
id: 'test',
mimeType: 'video/mp4',
periodStart: 0,
role: {
value: 'main'
},
serviceLocation: 'beta',
sourceDuration: 0,
type: 'dyanmic',
width: 720
},
segmentInfo: {
template: {}
}
},
{
attributes: {
NOW,
bandwidth: 256,
baseUrl: 'https://cdn1.example.com/vtt',
clientOffset: 0,
id: 'en',
lang: 'en',
mimeType: 'text/vtt',
periodStart: 0,
role: {},
serviceLocation: 'alpha',
sourceDuration: 0,
type: 'dyanmic'
},
segmentInfo: {}
},
{
attributes: {
NOW,
bandwidth: 256,
baseUrl: 'https://cdn2.example.com/vtt',
clientOffset: 0,
id: 'en',
lang: 'en',
mimeType: 'text/vtt',
periodStart: 0,
role: {},
serviceLocation: 'beta',
sourceDuration: 0,
type: 'dyanmic'
},
segmentInfo: {}
}
]
};
assert.equal(actual.representationInfo.length, 4);
assert.deepEqual(actual, expected);
});
QUnit.test('Too many content steering tags sends a warning to the eventHandler', function(assert) {
const handlerStub = stub();
const NOW = Date.now();
inheritAttributes(stringToMpdXml(`
<MPD type="dyanmic">
<ContentSteering defaultServiceLocation="alpha" queryBeforeStart="false" proxyServerURL="http://127.0.0.1:3455/steer">https://example.com/app/url</ContentSteering>
<ContentSteering defaultServiceLocation="beta" queryBeforeStart="false" proxyServerURL="http://127.0.0.1:3455/steer">https://example.com/app/url</ContentSteering>
<BaseURL serviceLocation="alpha">https://cdn1.example.com/</BaseURL>
<BaseURL serviceLocation="beta">https://cdn2.example.com/</BaseURL>
<Period start="PT0S">
<AdaptationSet mimeType="video/mp4">
<Role value="main"></Role>
<SegmentTemplate></SegmentTemplate>
<Representation
bandwidth="5000000"
codecs="avc1.64001e"
height="404"
id="test"
width="720">
</Representation>
</AdaptationSet>
<AdaptationSet mimeType="text/vtt" lang="en">
<Representation bandwidth="256" id="en">
<BaseURL>/video</BaseURL>
</Representation>
</AdaptationSet>
</Period>
</MPD>
`), { NOW, manifestUri: 'https://www.test.com', eventHandler: handlerStub });
assert.ok(handlerStub.calledWith({
type: 'warn',
message: 'The MPD manifest should contain no more than one ContentSteering tag'
}));
});
QUnit.test('end to end - basic multiperiod', function(assert) {
const NOW = Date.now();
@ -703,6 +1115,7 @@ QUnit.test('end to end - basic multiperiod', function(assert) {
`), { NOW });
const expected = {
contentSteeringInfo: null,
eventStream: [],
locations: undefined,
representationInfo: [{
@ -790,6 +1203,7 @@ QUnit.test('end to end - inherits BaseURL from all levels', function(assert) {
`), { NOW });
const expected = {
contentSteeringInfo: null,
eventStream: [],
locations: undefined,
representationInfo: [{
@ -867,6 +1281,7 @@ QUnit.test('end to end - alternate BaseURLs', function(assert) {
`), { NOW });
const expected = {
contentSteeringInfo: null,
eventStream: [],
locations: undefined,
representationInfo: [{
@ -1035,6 +1450,7 @@ QUnit.test(
`), { NOW });
const expected = {
contentSteeringInfo: null,
eventStream: [],
locations: undefined,
representationInfo: [{
@ -1148,6 +1564,7 @@ QUnit.test(
`), { NOW });
const expected = {
contentSteeringInfo: null,
eventStream: [],
locations: undefined,
representationInfo: [{
@ -1272,6 +1689,7 @@ QUnit.test(
`), { NOW });
const expected = {
contentSteeringInfo: null,
eventStream: [],
locations: undefined,
representationInfo: [{
@ -2116,6 +2534,7 @@ QUnit.test('keySystem info for representation - lowercase UUIDs', function(asser
// inconsistent quoting because of quote-props
const expected = {
contentSteeringInfo: null,
eventStream: [],
locations: undefined,
representationInfo: [{
@ -2203,6 +2622,7 @@ QUnit.test('keySystem info for representation - uppercase UUIDs', function(asser
// inconsistent quoting because of quote-props
const expected = {
contentSteeringInfo: null,
eventStream: [],
locations: undefined,
representationInfo: [{
@ -2372,6 +2792,7 @@ QUnit.test('gets eventStream from inheritAttributes', function(assert) {
</Period>
</MPD>`);
const expected = {
contentSteeringInfo: null,
eventStream: [
{
end: 15,
@ -2481,6 +2902,7 @@ QUnit.test('gets eventStream from inheritAttributes with data in Event tags', fu
</Period>
</MPD>`);
const expected = {
contentSteeringInfo: null,
eventStream: [
{
end: 15,