source-updater.test.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import SourceUpdater from '../src/source-updater';
  2. import QUnit from 'qunit';
  3. import videojs from 'video.js';
  4. import { useFakeMediaSource } from './test-helpers';
  5. QUnit.module('Source Updater', {
  6. beforeEach() {
  7. this.mse = useFakeMediaSource();
  8. this.mediaSource = new videojs.MediaSource();
  9. },
  10. afterEach() {
  11. this.mse.restore();
  12. }
  13. });
  14. QUnit.test('waits for sourceopen to create a source buffer', function(assert) {
  15. new SourceUpdater(this.mediaSource, 'video/mp2t'); // eslint-disable-line no-new
  16. assert.equal(this.mediaSource.sourceBuffers.length, 0,
  17. 'waited to create the source buffer');
  18. this.mediaSource.trigger('sourceopen');
  19. assert.equal(this.mediaSource.sourceBuffers.length, 1, 'created one source buffer');
  20. assert.equal(this.mediaSource.sourceBuffers[0].mimeType_, 'video/mp2t',
  21. 'assigned the correct MIME type');
  22. });
  23. QUnit.test('runs a callback when the source buffer is created', function(assert) {
  24. let updater = new SourceUpdater(this.mediaSource, 'video/mp2t');
  25. let sourceBuffer;
  26. updater.appendBuffer(new Uint8Array([0, 1, 2]));
  27. this.mediaSource.trigger('sourceopen');
  28. sourceBuffer = this.mediaSource.sourceBuffers[0];
  29. assert.equal(sourceBuffer.updates_.length, 1, 'called the source buffer once');
  30. assert.deepEqual(sourceBuffer.updates_[0].append, new Uint8Array([0, 1, 2]),
  31. 'appended the bytes');
  32. });
  33. QUnit.test('runs the completion callback when updateend fires', function(assert) {
  34. let updater = new SourceUpdater(this.mediaSource, 'video/mp2t');
  35. let updateends = 0;
  36. let sourceBuffer;
  37. this.mediaSource.trigger('sourceopen');
  38. sourceBuffer = this.mediaSource.sourceBuffers[0];
  39. updater.appendBuffer(new Uint8Array([0, 1, 2]), function() {
  40. updateends++;
  41. });
  42. updater.appendBuffer(new Uint8Array([2, 3, 4]), function() {
  43. throw new Error('Wrong completion callback invoked!');
  44. });
  45. assert.equal(updateends, 0, 'no completions yet');
  46. sourceBuffer.trigger('updateend');
  47. assert.equal(updateends, 1, 'ran the completion callback');
  48. });
  49. QUnit.test('runs the next callback after updateend fires', function(assert) {
  50. let updater = new SourceUpdater(this.mediaSource, 'video/mp2t');
  51. let sourceBuffer;
  52. updater.appendBuffer(new Uint8Array([0, 1, 2]));
  53. this.mediaSource.trigger('sourceopen');
  54. sourceBuffer = this.mediaSource.sourceBuffers[0];
  55. updater.appendBuffer(new Uint8Array([2, 3, 4]));
  56. assert.equal(sourceBuffer.updates_.length, 1, 'delayed the update');
  57. sourceBuffer.trigger('updateend');
  58. assert.equal(sourceBuffer.updates_.length, 2, 'updated twice');
  59. assert.deepEqual(sourceBuffer.updates_[1].append, new Uint8Array([2, 3, 4]),
  60. 'appended the bytes');
  61. });
  62. QUnit.test('runs only one callback at a time', function(assert) {
  63. let updater = new SourceUpdater(this.mediaSource, 'video/mp2t');
  64. let sourceBuffer;
  65. updater.appendBuffer(new Uint8Array([0]));
  66. updater.appendBuffer(new Uint8Array([1]));
  67. this.mediaSource.trigger('sourceopen');
  68. sourceBuffer = this.mediaSource.sourceBuffers[0];
  69. updater.appendBuffer(new Uint8Array([2]));
  70. assert.equal(sourceBuffer.updates_.length, 1, 'queued some updates');
  71. assert.deepEqual(sourceBuffer.updates_[0].append, new Uint8Array([0]),
  72. 'ran the first update');
  73. sourceBuffer.trigger('updateend');
  74. assert.equal(sourceBuffer.updates_.length, 2, 'queued some updates');
  75. assert.deepEqual(sourceBuffer.updates_[1].append, new Uint8Array([1]),
  76. 'ran the second update');
  77. updater.appendBuffer(new Uint8Array([3]));
  78. sourceBuffer.trigger('updateend');
  79. assert.equal(sourceBuffer.updates_.length, 3, 'queued the updates');
  80. assert.deepEqual(sourceBuffer.updates_[2].append, new Uint8Array([2]),
  81. 'ran the third update');
  82. sourceBuffer.trigger('updateend');
  83. assert.equal(sourceBuffer.updates_.length, 4, 'finished the updates');
  84. assert.deepEqual(sourceBuffer.updates_[3].append, new Uint8Array([3]),
  85. 'ran the fourth update');
  86. });
  87. QUnit.test('runs updates immediately if possible', function(assert) {
  88. let updater = new SourceUpdater(this.mediaSource, 'video/mp2t');
  89. let sourceBuffer;
  90. this.mediaSource.trigger('sourceopen');
  91. sourceBuffer = this.mediaSource.sourceBuffers[0];
  92. updater.appendBuffer(new Uint8Array([0]));
  93. assert.equal(sourceBuffer.updates_.length, 1, 'ran an update');
  94. assert.deepEqual(sourceBuffer.updates_[0].append, new Uint8Array([0]),
  95. 'appended the bytes');
  96. });
  97. QUnit.test('supports abort', function(assert) {
  98. let updater = new SourceUpdater(this.mediaSource, 'video/mp2t');
  99. let sourceBuffer;
  100. updater.abort();
  101. this.mediaSource.trigger('sourceopen');
  102. assert.equal(updater.callbacks_.length,
  103. 0,
  104. 'abort not queued before source buffers are appended to');
  105. updater.appendBuffer(new Uint8Array([0]));
  106. updater.abort();
  107. sourceBuffer = this.mediaSource.sourceBuffers[0];
  108. sourceBuffer.trigger('updateend');
  109. assert.ok(sourceBuffer.updates_[1].abort, 'aborted the source buffer');
  110. });
  111. QUnit.test('supports buffered', function(assert) {
  112. let updater = new SourceUpdater(this.mediaSource, 'video/mp2t');
  113. assert.equal(updater.buffered().length, 0, 'buffered is empty');
  114. this.mediaSource.trigger('sourceopen');
  115. assert.ok(updater.buffered(), 'buffered is defined');
  116. });
  117. QUnit.test('supports removeBuffer', function(assert) {
  118. let updater = new SourceUpdater(this.mediaSource, 'video/mp2t');
  119. let sourceBuffer;
  120. this.mediaSource.trigger('sourceopen');
  121. sourceBuffer = this.mediaSource.sourceBuffers[0];
  122. updater.remove(1, 14);
  123. assert.equal(sourceBuffer.updates_.length,
  124. 0,
  125. 'remove not queued before sourceBuffers are appended to');
  126. updater.appendBuffer(new Uint8Array([0]));
  127. updater.remove(1, 14);
  128. sourceBuffer.trigger('updateend');
  129. assert.equal(sourceBuffer.updates_.length, 2, 'ran an update');
  130. assert.deepEqual(sourceBuffer.updates_[1].remove, [1, 14], 'removed the time range');
  131. });
  132. QUnit.test('supports timestampOffset', function(assert) {
  133. let updater = new SourceUpdater(this.mediaSource, 'video/mp2t');
  134. let sourceBuffer;
  135. this.mediaSource.trigger('sourceopen');
  136. sourceBuffer = this.mediaSource.sourceBuffers[0];
  137. assert.equal(updater.timestampOffset(), 0, 'intialized to zero');
  138. updater.timestampOffset(21);
  139. assert.equal(updater.timestampOffset(), 21, 'reflects changes immediately');
  140. assert.equal(sourceBuffer.timestampOffset, 21, 'applied the update');
  141. updater.appendBuffer(new Uint8Array(2));
  142. updater.timestampOffset(14);
  143. assert.equal(updater.timestampOffset(), 14, 'reflects changes immediately');
  144. assert.equal(sourceBuffer.timestampOffset, 21, 'queues application after updates');
  145. sourceBuffer.trigger('updateend');
  146. assert.equal(sourceBuffer.timestampOffset, 14, 'applied the update');
  147. });