41b4bfd5 by Tom Johnson

- Fix for duration update in parser.

- Updated test suite now looks for manifest.totalDuration.
- Implemented ZEN-TOTAL-DURATION tag recognition.
1 parent dc304941
......@@ -141,6 +141,18 @@
this.trigger('data', event);
return;
}
match = (/^#ZEN-TOTAL-DURATION:?([0-9.]*)?/).exec(line);
if (match) {
event = {
type: 'tag',
tagType: 'totalduration'
};
if (match[1]) {
event.duration = parseInt(match[1], 10);
}
this.trigger('data', event);
return;
}
match = (/^#EXT-X-VERSION:?([0-9.]*)?/).exec(line);
if (match) {
event = {
......@@ -284,7 +296,8 @@
// the manifest is empty until the parse stream begins delivering data
this.manifest = {
allowCache: true
allowCache: true,
totalDuration: 0
};
// update the manifest with the m3u8 entry from the parse stream
......@@ -373,17 +386,34 @@
}
this.manifest.targetDuration = entry.duration;
},
'totalduration': function() {
if (!isFinite(entry.duration) || entry.duration < 0) {
this.trigger('warn', {
message: 'ignoring invalid total duration: ' + entry.duration
});
return;
}
this.manifest.totalDuration = entry.duration;
},
'endlist': function() {
var calculatedDuration = 0,
i;
for( i = 0; i < this.manifest.segments.length; i++) {
if(this.manifest.segments[i].duration) {
calculatedDuration += this.manifest.segments[i].duration;
} else if (this.manifest.targetDuration) {
calculatedDuration += this.manifest.targetDuration;
if(this.manifest.totalDuration === 0)
{
var calculatedDuration = 0,
i;
for( i = 0; i < this.manifest.segments.length; i++) {
if(this.manifest.segments[i].duration) {
calculatedDuration += this.manifest.segments[i].duration;
} else if (this.manifest.targetDuration > 0) {
calculatedDuration += this.manifest.targetDuration;
} else {
calculatedDuration += 0;
}
}
this.manifest.totalDuration = calculatedDuration;
this.trigger('info', {
message: 'updating total duration to use a calculated value'
})
}
this.trigger('durationUpdate', parseInt(calculatedDuration));
}
})[entry.tagType] || noop).call(self);
},
......
......@@ -164,6 +164,10 @@ var
parser.push(xhr.responseText);
player.hls.manifest = parser.manifest;
if(parser.manifest.totalDuration) {
player.duration(parser.manifest.totalDuration);
}
player.trigger('loadedmanifest');
if (parser.manifest.segments) {
......
{
"allowCache": true,
"targetDuration": 10,
"totalDuration": 40,
"mediaSequence": 0,
"playlistType": "VOD",
"segments": [{
......
{
"targetDuration": 10,
"totalDuration": 161.4167,
"allowCache": true,
"mediaSequence": 0,
"playlistType": "VOD",
......
{
"allowCache": true,
"targetDuration": 10,
"totalDuration": 161.4167,
"mediaSequence": 0,
"playlistType": "VOD",
"segments": [{
......
{
"targetDuration": 10,
"totalDuration": 10,
"allowCache": false,
"mediaSequence": 0,
"playlistType": "VOD",
......
{
"allowCache": true,
"targetDuration": 10,
"totalDuration": 40,
"mediaSequence": 0,
"playlistType": "VOD",
"segments": [{
......
{
"targetDuration": 10,
"totalDuration": 10,
"allowCache": true,
"mediaSequence": 0,
"playlistType": "VOD",
......
......@@ -3,6 +3,7 @@
"mediaSequence": 0,
"playlistType": "VOD",
"targetDuration": 8,
"totalDuration": 24.32,
"segments": [{
"duration": 6.64,
"uri": "/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts"
......
{
"allowCache": true,
"targetDuration": 10,
"totalDuration": 58,
"mediaSequence": 0,
"playlistType": "VOD",
"segments": [{
......
{
"allowCache": true,
"totalDuration": 0,
"playlists": [{
"attributes": {
"PROGRAM-ID": 1,
......
{
"allowCache": true,
"targetDuration": 10,
"totalDuration": 58,
"mediaSequence": 0,
"playlistType": "EVENT",
"segments": [{
......
{
"allowCache": true,
"targetDuration": 10,
"totalDuration": 164.7,
"mediaSequence": 0,
"playlistType": "VOD",
"segments": [{
......
{
"targetDuration": 10,
"totalDuration": 10,
"allowCache": true,
"mediaSequence": 0,
"playlistType": "VOD",
......
......@@ -3,6 +3,7 @@
"mediaSequence": 0,
"playlistType": "VOD",
"targetDuration": 8,
"totalDuration": 24.32,
"segments": [{
"duration": 6.64,
"uri": "/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts"
......
{
"allowCache": true,
"targetDuration": 10,
"totalDuration": 58,
"mediaSequence": 0,
"playlistType": "VOD",
"segments": [{
......
{
"allowCache": true,
"mediaSequence": 0,
"totalDuration": 161.4167,
"playlistType": "VOD",
"segments": [{
"duration": 10,
......
{
"allowCache": true,
"totalDuration": 0,
"playlists": [{
"attributes": {
"PROGRAM-ID": 1,
......
{
"allowCache": true,
"targetDuration": 10,
"totalDuration": 40,
"mediaSequence": 0,
"playlistType": "VOD",
"segments": [{
......
......@@ -2,6 +2,7 @@
"allowCache": true,
"mediaSequence": 0,
"playlistType": "VOD",
"totalDuration": 24.32,
"targetDuration": 8,
"segments": [{
"duration": 6.64,
......
{
"allowCache": true,
"mediaSequence": 0,
"totalDuration": 24.32,
"playlistType": "VOD",
"targetDuration": 8,
"segments": [{
......
......@@ -3,6 +3,7 @@
"mediaSequence": 0,
"playlistType": "VOD",
"targetDuration": 8,
"totalDuration": 30.64,
"segments": [{
"duration": 6.64,
"uri": "/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts"
......
{
"allowCache": true,
"mediaSequence": -11,
"totalDuration": 24.32,
"playlistType": "VOD",
"targetDuration": 8,
"segments": [{
......
{
"allowCache": true,
"targetDuration": 10,
"totalDuration": 161.4167,
"mediaSequence": 0,
"playlistType": "VOD",
"segments": [{
......
......@@ -3,6 +3,7 @@
"mediaSequence": 11,
"playlistType": "VOD",
"targetDuration": 8,
"totalDuration": 24.32,
"segments": [{
"duration": 6.64,
"uri": "/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts"
......