当前位置:   article > 正文

(Javascript)AI数字人mp4转canvas播放并去除背景绿幕

(Javascript)AI数字人mp4转canvas播放并去除背景绿幕

1、需求介绍

H5页面嵌入AI数字人播报,但生成的数字人是mp4格式且有绿幕背景,需要转成canvas并去除背景;

2、效果:

去除前:

去除后:

3、代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>Document</title>
  8. <style>
  9. * {
  10. margin: 0;
  11. padding: 0;
  12. }
  13. </style>
  14. </head>
  15. <body>
  16. <button onclick="playOrPause()">播放/暂停</button>
  17. <button onclick="muted()">静音</button>
  18. <div style="height: 400px; width:300px; ">
  19. <video id="video" controls style="width: 100%; height: 100%; object-fit: contain" autoplay webkit-playsinline="true"
  20. src='123.mp4'></video>
  21. </div>
  22. <script>
  23. var VideoToCanvas = (function (window, document) {
  24. function VideoToCanvas(videoElement) {
  25. if (!videoElement) { return; }
  26. var canvas = document.createElement('canvas');
  27. canvas.width = videoElement.offsetWidth;
  28. canvas.height = videoElement.offsetHeight;
  29. ctx = canvas.getContext('2d');
  30. var newVideo = videoElement.cloneNode(false);
  31. newVideo.addEventListener('play', function () {
  32. computeFrame();
  33. }, false);
  34. function computeFrame() {
  35. if (newVideo.paused || newVideo.ende) {
  36. return;
  37. }
  38. ctx.drawImage(newVideo, 0, 0, canvas.width, canvas.height);
  39. // 获取到绘制的canvas的所有像素rgba值组成的数组
  40. let frame = ctx.getImageData(0, 0, canvas.width, canvas.height);
  41. // 共有多少像素点
  42. const pointLens = frame.data.length / 4;
  43. for (let i = 0; i < pointLens; i++) {
  44. let r = frame.data[i * 4];
  45. let g = frame.data[i * 4 + 1];
  46. let b = frame.data[i * 4 + 2];
  47. // 判断如果rgb值在这个范围内则是绿幕背景,设置alpha值为0
  48. // 同理不同颜色的背景调整rgb的判断范围即可
  49. if (r < 100 && g > 120 && b < 200) {
  50. frame.data[i * 4 + 3] = 0;
  51. }
  52. }
  53. // 重新绘制到canvas中显示
  54. ctx.putImageData(frame, 0, 0);
  55. // 递归调用
  56. setTimeout(computeFrame, 0);
  57. }
  58. videoElement.parentNode.replaceChild(canvas, video);
  59. this.play = function () {
  60. newVideo.play();
  61. };
  62. this.pause = function () {
  63. newVideo.pause();
  64. };
  65. this.playPause = function () {
  66. if (newVideo.paused) {
  67. this.play();
  68. } else {
  69. this.pause();
  70. }
  71. };
  72. this.muted = function () {
  73. newVideo.muted = !newVideo.muted;
  74. }
  75. this.change = function (src) {
  76. if (!src) { return; }
  77. newVideo.src = src;
  78. computeFrame();
  79. };
  80. }
  81. return VideoToCanvas;
  82. })(window, document);
  83. var video = document.getElementById('video');
  84. var videoCanvas = new VideoToCanvas(video);
  85. function playOrPause() {
  86. videoCanvas.playPause();
  87. }
  88. function muted() {
  89. videoCanvas.muted();
  90. }
  91. </script>

4、可能会出现的报错

(1)视频路径跨域问题:

解决:

1、原生HTML在vscode中安装Live Server插件然后右键index.html,选择“open with live server”:

2、vue项目vue.config.js中开启代理;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/716635
推荐阅读
相关标签
  

闽ICP备14008679号