jsmpeg.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*! jsmpeg v1.0 | (c) Dominic Szablewski | MIT license */
  2. // This sets up the JSMpeg "Namespace". The object is empty apart from the Now()
  3. // utility function and the automatic CreateVideoElements() after DOMReady.
  4. var JSMpeg = {
  5. // The Player sets up the connections between source, demuxer, decoders,
  6. // renderer and audio output. It ties everything together, is responsible
  7. // of scheduling decoding and provides some convenience methods for
  8. // external users.
  9. Player: null,
  10. // A Video Element wraps the Player, shows HTML controls to start/pause
  11. // the video and handles Audio unlocking on iOS. VideoElements can be
  12. // created directly in HTML using the <div class="jsmpeg"/> tag.
  13. VideoElement: null,
  14. // The BitBuffer wraps a Uint8Array and allows reading an arbitrary number
  15. // of bits at a time. On writing, the BitBuffer either expands its
  16. // internal buffer (for static files) or deletes old data (for streaming).
  17. BitBuffer: null,
  18. // A Source provides raw data from HTTP, a WebSocket connection or any
  19. // other mean. Sources must support the following API:
  20. // .connect(destinationNode)
  21. // .write(buffer)
  22. // .start() - start reading
  23. // .resume(headroom) - continue reading; headroom to play pos in seconds
  24. // .established - boolean, true after connection is established
  25. // .completed - boolean, true if the source is completely loaded
  26. // .progress - float 0-1
  27. Source: {},
  28. // A Demuxer may sit between a Source and a Decoder. It separates the
  29. // incoming raw data into Video, Audio and other Streams. API:
  30. // .connect(streamId, destinationNode)
  31. // .write(buffer)
  32. // .currentTime – float, in seconds
  33. // .startTime - float, in seconds
  34. Demuxer: {},
  35. // A Decoder accepts an incoming Stream of raw Audio or Video data, buffers
  36. // it and upon `.decode()` decodes a single frame of data. Video decoders
  37. // call `destinationNode.render(Y, Cr, CB)` with the decoded pixel data;
  38. // Audio decoders call `destinationNode.play(left, right)` with the decoded
  39. // PCM data. API:
  40. // .connect(destinationNode)
  41. // .write(pts, buffer)
  42. // .decode()
  43. // .seek(time)
  44. // .currentTime - float, in seconds
  45. // .startTime - float, in seconds
  46. Decoder: {},
  47. // A Renderer accepts raw YCrCb data in 3 separate buffers via the render()
  48. // method. Renderers typically convert the data into the RGBA color space
  49. // and draw it on a Canvas, but other output - such as writing PNGs - would
  50. // be conceivable. API:
  51. // .render(y, cr, cb) - pixel data as Uint8Arrays
  52. // .enabled - wether the renderer does anything upon receiving data
  53. Renderer: {},
  54. // Audio Outputs accept raw Stero PCM data in 2 separate buffers via the
  55. // play() method. Outputs typically play the audio on the user's device.
  56. // API:
  57. // .play(sampleRate, left, right) - rate in herz; PCM data as Uint8Arrays
  58. // .stop()
  59. // .enqueuedTime - float, in seconds
  60. // .enabled - wether the output does anything upon receiving data
  61. AudioOutput: {},
  62. Now: function() {
  63. return window.performance
  64. ? window.performance.now() / 1000
  65. : Date.now() / 1000;
  66. },
  67. CreateVideoElements: function() {
  68. var elements = document.querySelectorAll('.jsmpeg');
  69. for (var i = 0; i < elements.length; i++) {
  70. new JSMpeg.VideoElement(elements[i]);
  71. }
  72. },
  73. Fill: function(array, value) {
  74. if (array.fill) {
  75. array.fill(value);
  76. }
  77. else {
  78. for (var i = 0; i < array.length; i++) {
  79. array[i] = value;
  80. }
  81. }
  82. },
  83. Base64ToArrayBuffer: function(base64) {
  84. var binary = window.atob(base64);
  85. var length = binary.length;
  86. var bytes = new Uint8Array(length);
  87. for (var i = 0; i < length; i++) {
  88. bytes[i] = binary.charCodeAt(i);
  89. }
  90. return bytes.buffer;
  91. },
  92. // The build process may append `JSMpeg.WASM_BINARY_INLINED = base64data;`
  93. // to the minified source.
  94. // If this property is present, jsmpeg will use the inlined binary data
  95. // instead of trying to load a jsmpeg.wasm file via Ajax.
  96. WASM_BINARY_INLINED: null
  97. };
  98. // Automatically create players for all found <div class="jsmpeg"/> elements.
  99. if (document.readyState === 'complete') {
  100. JSMpeg.CreateVideoElements();
  101. }
  102. else {
  103. document.addEventListener('DOMContentLoaded', JSMpeg.CreateVideoElements);
  104. }