YUVPlayer.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. import {BufferNode, BufferQueue, ImagePool} from './BufferNode.js';
  2. import YUVWebGLCanvas from './WebGLCanvas.js';
  3. let Uniformity = true;
  4. let channelId = 0;
  5. let canvas = null;
  6. let drawer = null;
  7. let preWidth = null;
  8. let preHeight = null;
  9. let drawingStrategy = null;
  10. let frameInterval = null;
  11. let prevCodecType = null;
  12. let resizeCallback = null;
  13. let startTimestamp = 0;
  14. let frameTimestamp = null;
  15. let preTimestamp = 0;
  16. let progressTime = 0;
  17. let curTime = 0;
  18. let imagePool = new ImagePool;
  19. let bufferNode = null;
  20. let fileName = "";
  21. let captureFlag = false;
  22. let isRendering = false;
  23. let defaultInterval = 16.7;
  24. let defaultMaxDelay = 20;
  25. let milisecond = 1e3;
  26. let maxDelay = null;
  27. let videoBufferQueue = null;
  28. let canvasElem = null;
  29. class VideoBufferNode extends BufferNode{
  30. constructor(data, width, height, codecType, frameType, timeStamp){
  31. super();
  32. //console.log(data)
  33. this.buffer = data;
  34. this.width = width;
  35. this.height = height;
  36. this.codecType = codecType;
  37. this.frameType = frameType;
  38. this.timeStamp = timeStamp
  39. }
  40. }
  41. class VideoBufferQueue extends BufferQueue{
  42. constructor() {
  43. super();
  44. this.MAX_LENGTH = 30;
  45. }
  46. enqueue(data, width, height, codecType, frameType, timeStamp) {
  47. //console.log(arguments)
  48. if(this.size >= this.MAX_LENGTH) {
  49. this.clear();
  50. }
  51. let node = new VideoBufferNode(data, width, height, codecType, frameType, timeStamp);
  52. if (this.first === null) {
  53. this.first = node
  54. } else {
  55. let tempNode = this.first;
  56. while (tempNode.next !== null) {
  57. tempNode = tempNode.next
  58. }
  59. tempNode.next = node
  60. }
  61. this.size += 1;
  62. return node
  63. }
  64. }
  65. class Size {
  66. constructor(width, height) {
  67. this.w = width;
  68. this.h = height;
  69. }
  70. toString() {
  71. return "(" + this.w + ", " + this.h + ")"
  72. }
  73. getHalfSize() {
  74. return new Size(this.w >>> 1, this.h >>> 1)
  75. }
  76. length() {
  77. return this.w * this.h
  78. }
  79. }
  80. class YUVPlayer {
  81. constructor(canvas){
  82. drawingStrategy = "YUVWebGL";
  83. prevCodecType = null;
  84. videoBufferQueue = new VideoBufferQueue;
  85. frameInterval = defaultInterval;
  86. isRendering = false
  87. canvasElem = canvas;
  88. }
  89. draw(data, width, height, codecType, frameType, timeStamp) {
  90. if (videoBufferQueue !== null) {
  91. videoBufferQueue.enqueue(data, width, height, codecType, frameType, timeStamp)
  92. }
  93. }
  94. startRendering() {
  95. if (startTimestamp === 0 && Uniformity !== false) {
  96. isRendering = true;
  97. window.requestAnimationFrame(drawingInTime)
  98. }
  99. }
  100. stopRendering() {
  101. isRendering = false;
  102. startTimestamp = 0
  103. }
  104. setFPS(fps) {
  105. if (typeof fps === "undefined") {
  106. frameInterval = defaultInterval;
  107. maxDelay = defaultMaxDelay
  108. } else if (fps === 0) {
  109. frameInterval = defaultInterval;
  110. maxDelay = defaultMaxDelay
  111. } else {
  112. frameInterval = milisecond / fps;
  113. maxDelay = fps * 1
  114. }
  115. }
  116. terminate() {
  117. startTimestamp = 0;
  118. frameTimestamp = null;
  119. if (videoBufferQueue !== null) {
  120. videoBufferQueue.clear();
  121. videoBufferQueue = null
  122. }
  123. drawer = null
  124. }
  125. }
  126. function resize(width, height) {
  127. let size = new Size(width, height);
  128. canvas = canvasElem;
  129. switch (drawingStrategy) {
  130. case"YUVWebGL":
  131. drawer = new YUVWebGLCanvas(canvas, size);
  132. break;
  133. default:
  134. break
  135. }
  136. }
  137. function drawFrame(stepValue) {
  138. bufferNode = videoBufferQueue.dequeue();
  139. if (bufferNode !== null && bufferNode.buffer !== null && (bufferNode.codecType === "mjpeg" || bufferNode.buffer.length > 0)) {
  140. if (typeof preWidth === "undefined" || typeof preHeight === "undefined" || preWidth !== bufferNode.width || preHeight !== bufferNode.height || prevCodecType !== bufferNode.codecType) {
  141. drawingStrategy = bufferNode.codecType === "h264" || bufferNode.codecType === "h265" ? "YUVWebGL" : "ImageWebGL";
  142. resize(bufferNode.width, bufferNode.height);
  143. preWidth = bufferNode.width;
  144. preHeight = bufferNode.height;
  145. prevCodecType = bufferNode.codecType;
  146. if (typeof resizeCallback !== "undefined" && resizeCallback !== null) {
  147. resizeCallback("resize")
  148. }
  149. }
  150. frameTimestamp = bufferNode.timeStamp;
  151. //workerManager.timeStamp(frameTimestamp);
  152. if (typeof drawer !== "undefined") {
  153. drawer.drawCanvas(bufferNode.buffer);
  154. canvas.updatedCanvas = true;
  155. // if (captureFlag) {
  156. // captureFlag = false;
  157. // doCapture(canvas.toDataURL(), fileName)
  158. // }
  159. if (bufferNode.codecType === "mjpeg") {
  160. imagePool.free(bufferNode.buffer)
  161. } else {
  162. delete bufferNode.buffer;
  163. bufferNode.buffer = null
  164. }
  165. bufferNode.previous = null;
  166. bufferNode.next = null;
  167. bufferNode = null;
  168. return true
  169. } else {
  170. console.log("drawer is undefined in StreamDrawer!")
  171. }
  172. } else {
  173. }
  174. return false
  175. }
  176. function drawingInTime(timestamp) {
  177. let stampCheckTime = 200;
  178. if (isRendering === true) {
  179. if (startTimestamp === 0 || timestamp - startTimestamp < stampCheckTime) {
  180. if (startTimestamp === 0) {
  181. startTimestamp = timestamp
  182. }
  183. if (videoBufferQueue !== null) {
  184. window.requestAnimationFrame(drawingInTime)
  185. }
  186. return
  187. }
  188. curTime += timestamp - preTimestamp;
  189. if (curTime > progressTime) {
  190. if(drawFrame()) {
  191. progressTime += frameInterval
  192. }
  193. }
  194. if (curTime > milisecond) {
  195. progressTime = 0;
  196. curTime = 0
  197. }
  198. preTimestamp = timestamp;
  199. window.requestAnimationFrame(drawingInTime)
  200. }
  201. }
  202. function drawImage(data) {
  203. if (typeof preWidth === "undefined" || typeof preHeight === "undefined" || preWidth !== data.width || preHeight !== data.height) {
  204. drawingStrategy = "ImageWebGL";
  205. resize(data.width, data.height);
  206. preWidth = data.width;
  207. preHeight = data.height;
  208. resizeCallback("resize")
  209. }
  210. frameTimestamp = data.time;
  211. if (frameTimestamp !== null) {
  212. //workerManager.timeStamp(frameTimestamp)
  213. }
  214. if (typeof drawer !== "undefined") {
  215. drawer.drawCanvas(data);
  216. if (captureFlag) {
  217. captureFlag = false;
  218. //doCapture(canvas.toDataURL(), fileName)
  219. }
  220. imagePool.free(data);
  221. return true
  222. } else {
  223. console.log("drawer is undefined in StreamDrawer!")
  224. }
  225. return false
  226. }
  227. export default YUVPlayer;