rtmp_video_capturer.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // 获取 video 元素的宽度和高度
  2. var rtmp_videoChannelWidth;
  3. var rtmp_videoChannelHeight;
  4. // 创建 ImageCapture 对象
  5. var rtmp_videoChannelCapture;
  6. var rtmp_usVideoElement;
  7. var rtmp_captureCanvas;
  8. /// 初始化 imageCapture 并返回 video 宽高
  9. /// [video_id] 传入需要捕获的 video 元素的 id
  10. function initRTMPVideoCapture(video_id) {
  11. try {
  12. // 获取video元素
  13. rtmp_usVideoElement = document.getElementById(video_id);
  14. try {
  15. // 获取video流
  16. let stream = rtmp_usVideoElement.captureStream();
  17. let track = stream.getVideoTracks()[0];
  18. // 获取video的宽度和高度
  19. const settings = track.getSettings();
  20. rtmp_videoChannelWidth = settings.width;
  21. rtmp_videoChannelHeight = settings.height;
  22. // 创建ImageCapture对象
  23. rtmp_videoChannelCapture = new ImageCapture(track);
  24. } catch (error) {
  25. rtmp_videoChannelCapture = null;
  26. // 获取video元素的宽度和高度
  27. rtmp_videoChannelWidth = rtmp_usVideoElement.videoWidth;
  28. rtmp_videoChannelHeight = rtmp_usVideoElement.videoHeight;
  29. }
  30. // 初始化canvas
  31. rtmp_captureCanvas = document.createElement("canvas");
  32. rtmp_captureCanvas.width = rtmp_videoChannelWidth;
  33. rtmp_captureCanvas.height = rtmp_videoChannelHeight;
  34. return [rtmp_videoChannelWidth, rtmp_videoChannelHeight];
  35. } catch (error) {
  36. return [0, 0];
  37. }
  38. }
  39. function setRTMPClipSize(width, height) {
  40. rtmp_captureCanvas.width = width;
  41. rtmp_captureCanvas.height = height;
  42. }
  43. /// 捕获视频帧并转换为二进制数组返回
  44. function captureRTMPOneFrame() {
  45. if (rtmp_videoChannelCapture == null) {
  46. const context = rtmp_captureCanvas.getContext("2d");
  47. context.drawImage(
  48. rtmp_usVideoElement,
  49. 0,
  50. 0,
  51. rtmp_videoChannelWidth,
  52. rtmp_videoChannelHeight
  53. );
  54. const dataUrl = rtmp_captureCanvas.toDataURL("image/jpeg");
  55. const binary = atob(dataUrl.split(",")[1]);
  56. const uint8Array = new Uint8Array(binary.length);
  57. for (let i = 0; i < binary.length; i++) {
  58. uint8Array[i] = binary.charCodeAt(i);
  59. }
  60. return Promise.resolve(uint8Array);
  61. } else {
  62. const promise = rtmp_videoChannelCapture.grabFrame().then((imageBitmap) => {
  63. const context = rtmp_captureCanvas.getContext("2d");
  64. context.drawImage(
  65. imageBitmap,
  66. 0,
  67. 0,
  68. rtmp_videoChannelWidth,
  69. rtmp_videoChannelHeight
  70. );
  71. const dataUrl = rtmp_captureCanvas.toDataURL("image/jpeg");
  72. console.log(dataUrl);
  73. const binary = atob(dataUrl.split(",")[1]);
  74. const uint8Array = new Uint8Array(binary.length);
  75. for (let i = 0; i < binary.length; i++) {
  76. uint8Array[i] = binary.charCodeAt(i);
  77. }
  78. return uint8Array;
  79. });
  80. return promise;
  81. }
  82. }
  83. /// 释放 imageCapture 对象
  84. function disposeRTMPVideoCapture() {
  85. rtmp_videoChannelCapture = null;
  86. rtmp_usVideoElement = null;
  87. rtmp_captureCanvas = null;
  88. console.log("rtmp_videoChannelCapture has been disposed");
  89. }