UNPKG

@eyevinn/m3u8

Version:

streaming m3u8 parser for Apple's HTTP Live Streaming protocol

242 lines (198 loc) 6.94 kB
var fs = require('fs'), { Readable } = require('stream'), M3U = require('../m3u'), sinon = require('sinon'), should = require('should'); describe('m3u', function() { describe('#set', function() { it('should set property on m3u', function() { var m3u = getM3u(); m3u.set('EXT-X-I-FRAMES-ONLY', true); m3u.properties.iframesOnly.should.be.true; }); }); describe('#get', function() { it('should get property from m3u', function() { var m3u = getM3u(); m3u.properties.version = 4; m3u.get('version').should.eql(4); }); }); describe('#addItem', function() { it('should add item to typed array', function() { var m3u = getM3u(); m3u.items.PlaylistItem.length.should.eql(0); m3u.addItem(new M3U.PlaylistItem); m3u.items.PlaylistItem.length.should.eql(1); }); }); describe('#addPlaylistItem', function() { it('should create and add a PlaylistItem', function() { var m3u = getM3u(); m3u.addPlaylistItem({}); m3u.items.PlaylistItem.length.should.eql(1); }); }); describe('#removePlaylistItem', function() { it('should remove a PlaylistItem at a specifed index', function() { var m3u = getM3u(); m3u.addPlaylistItem({}); m3u.removePlaylistItem(0); m3u.items.PlaylistItem.length.should.eql(0); }); }); describe('#removePlaylistItemOutOfRange', function() { it('should thow an error when trying to remove a playlist item out of range', function() { var m3u = getM3u(); m3u.addPlaylistItem({}); m3u.addPlaylistItem({}); m3u.removePlaylistItem.bind(m3u, 3).should.throw(RangeError); }); }); describe('#addMediaItem', function() { it('should create and add a MediaItem', function() { var m3u = getM3u(); m3u.addMediaItem({}); m3u.items.MediaItem.length.should.eql(1); }); }); describe('#addStreamItem', function() { it('should create and add a StreamItem', function() { var m3u = getM3u(); m3u.addStreamItem({}); m3u.items.StreamItem.length.should.eql(1); }); }); describe('#addIframeStreamItem', function() { it('should create and add a IframeStreamItem', function() { var m3u = getM3u(); m3u.addIframeStreamItem({}); m3u.items.IframeStreamItem.length.should.eql(1); }); }); describe('#totalDuration', function() { it('should total duration of every PlaylistItem', function() { var m3u = getM3u(); m3u.addPlaylistItem({ duration: 10 }); m3u.addPlaylistItem({ duration: 4.5 }); m3u.addPlaylistItem({ duration: 45 }); m3u.totalDuration().should.eql(59.5); }); }); describe('#domainDurations', function() { it('should total durations of every PlaylistItem respecting discontinuity domains', function() { var m3u = getM3u(); m3u.addPlaylistItem({ duration: 10 }); m3u.addPlaylistItem({ duration: 4.5 }); m3u.addPlaylistItem({ duration: 45 }); m3u.items.PlaylistItem[2].set('discontinuity', true); m3u.addPlaylistItem({ duration: 45 }); m3u.addPlaylistItem({ duration: 30 }); m3u.items.PlaylistItem[4].set('discontinuity', true); m3u.addPlaylistItem({ duration: 26 }); m3u.domainDurations().should.eql([14.5, 90, 56]); }); }); describe('#merge', function() { it('should merge PlaylistItems from two m3us, creating a discontinuity', function() { var m3u1 = getM3u(); m3u1.addPlaylistItem({}); m3u1.addPlaylistItem({}); m3u1.addPlaylistItem({}); var m3u2 = getM3u(); m3u2.addPlaylistItem({}); m3u2.addPlaylistItem({}); var itemWithDiscontinuity = m3u2.items.PlaylistItem[0]; m3u1.merge(m3u2); itemWithDiscontinuity.get('discontinuity').should.be.true; m3u1.items.PlaylistItem.filter(function(item) { return item.get('discontinuity'); }).length.should.eql(1); }); it('should use the largest targetDuration', function() { var m3u1 = getM3u(); m3u1.set('targetDuration', 10); m3u1.addPlaylistItem({}); var m3u2 = getM3u(); m3u2.set('targetDuration', 11); m3u2.addPlaylistItem({}); m3u1.merge(m3u2); m3u1.get('targetDuration').should.eql(11); }); }); describe('#serialize', function(done) { it('should return an object containing items and properties', function(done) { getVariantM3U(function(error, m3u) { var data = m3u.serialize(); data.properties.should.eql(m3u.properties); data.items.IframeStreamItem.length.should.eql(m3u.items.IframeStreamItem.length); data.items.MediaItem.length.should.eql(m3u.items.MediaItem.length); data.items.PlaylistItem.length.should.eql(m3u.items.PlaylistItem.length); data.items.StreamItem.length.should.eql(m3u.items.StreamItem.length); data.items.MediaItem[0].should.eql(m3u.items.MediaItem[0].serialize()); done(); }); }); }); describe('unserialize', function() { it('should return an M3U object with items and properties', function() { var item = new M3U.PlaylistItem({ key: 'uri', value: '/path' }); var data = { properties: { targetDuration: 10 }, items: { PlaylistItem: [ item.serialize() ] } }; var m3u = M3U.unserialize(data); m3u.properties.should.eql(data.properties); item.should.eql(m3u.items.PlaylistItem[0]); }); }); describe('writeVOD', function() { it('should return a string ending with #EXT-X-ENDLIST', function() { var m3u1 = getM3u(); m3u1.set('playlistType', 'VOD'); m3u1.addPlaylistItem({ duration: 1 }); var output = m3u1.toString(); var endStr = '#EXT-X-ENDLIST\n'; output.indexOf(endStr).should.eql(output.length - endStr.length); }); it('stringified output should match input', function(done) { getVariantM3U(function(error, m3u, original) { if (error) { done(error); } m3u.toString().should.eql(original); done(); }); }); }); describe('writeLive', function() { it('should return a string not ending with #EXT-X-ENDLIST', function() { var m3u1 = getM3u(); m3u1.addPlaylistItem({}); var output = m3u1.toString(); output.indexOf('#EXT-X-ENDLIST\n').should.eql(-1); }); }); }); function getM3u() { var m3u = M3U.create(); return m3u; } function getVariantM3U(callback) { var parser = require('../parser').createStream(); fs.readFile(__dirname + '/fixtures/variant.m3u8', function(err, buffer) { if (err) { callback(err); return; } var stream = Readable.from(buffer); stream.pipe(parser); parser.on('m3u', function(m3u) { callback(null, m3u, buffer.toString().replace(/(\r\n)/gm, '\n')); }); }) }