{"version":3,"file":"canvas2d-CjmPWzfI.cjs","names":["isOffscreenCanvasSupported","RenderCache","VideoEntity"],"sources":["../src/player/render/canvas2d/control.ts","../src/player/render/canvas2d/index.ts"],"sourcesContent":["import {isOffscreenCanvasSupported} from 'src/helper/utils'\nexport class Canvas2dControl {\n  createCanvas(): HTMLCanvasElement | OffscreenCanvas {\n    return isOffscreenCanvasSupported() && !!self.createImageBitmap\n      ? new OffscreenCanvas(300, 300)\n      : document.createElement('canvas')\n  }\n  removeCanvas(ofs: HTMLCanvasElement | OffscreenCanvas) {\n    if (ofs instanceof HTMLCanvasElement) {\n      ofs.remove()\n    } else {\n      ofs = undefined as any\n    }\n  }\n  get2dContext(ofs: HTMLCanvasElement | OffscreenCanvas) {\n    return ofs.getContext('2d', {\n      willReadFrequently: true,\n    }) as CanvasRenderingContext2D\n  }\n}\n","import {logger} from 'src/helper/logger'\nimport {Canvas2dControl} from 'src/player/render/canvas2d/control'\nimport RenderCache from 'src/player/render/common/renderCache'\nimport VideoEntity from 'src/player/render/common/videoEntity'\nimport type {MixEvideoOptions, ResizeCanvasType, VideoAnimateDataItemType} from 'src/type/mix'\n//\nexport default class Render2D extends Canvas2dControl {\n  public isPlay = false\n  // public webgl: any = {version: 'canvas2d'}\n  public renderType = 'canvas2d'\n  public videoEntity: VideoEntity\n  public renderCache: RenderCache\n  //\n  private video: HTMLVideoElement | undefined\n  private ofs: HTMLCanvasElement | OffscreenCanvas\n  private ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D\n  //\n  private canvas?: HTMLCanvasElement\n  private context: CanvasRenderingContext2D | null | undefined\n  private op: MixEvideoOptions\n  // private frameCache: any = {}\n  //\n  private alphaCanvas: HTMLCanvasElement | OffscreenCanvas\n  private alphaCtx: CanvasRenderingContext2D\n\n  private canvasKey: HTMLCanvasElement | OffscreenCanvas\n  private ctxKey: CanvasRenderingContext2D\n\n  //\n  drawEffect: {[key: string]: any}\n  constructor(op: MixEvideoOptions) {\n    super()\n    logger.debug('[Render In Canvas]')\n    this.op = op\n    //\n    this.ofs = this.createCanvas()\n    this.ctx = this.get2dContext(this.ofs)\n    //\n    this.renderCache = new RenderCache(this.ofs, this.op)\n    this.videoEntity = new VideoEntity(op)\n    //\n    this.alphaCanvas = this.createCanvas()\n    this.alphaCtx = this.get2dContext(this.alphaCanvas)\n    //\n    //\n    this.drawEffect = {}\n\n    this.canvasKey = this.createCanvas()\n    this.ctxKey = this.get2dContext(this.canvasKey)\n  }\n  private setSizeCanvas(canvas: HTMLCanvasElement, resizeCanvas: ResizeCanvasType) {\n    switch (resizeCanvas) {\n      case 'percent':\n        canvas.style.width = '100%'\n        canvas.style.height = '100%'\n        break\n      case 'percentH':\n        canvas.style.height = '100%'\n        break\n      case 'percentW':\n        canvas.style.width = '100%'\n        break\n      default:\n        break\n    }\n  }\n  /**\n      sx\t裁剪框右上角的x坐标\n      sy\t裁剪框右上角的y坐标\n      sw\t裁剪框的宽度\n      sh\t裁剪框的高度\n   */\n  private getScale() {\n    const scaleX = 1\n    const scaleY = 1\n    //\n    let [sx, sy, sw, sh, dx, dy, dw, dh]: number[] = []\n\n    const ofs = this.canvas\n    const vw = ofs.width\n    const vh = ofs.height\n    const cw = ofs.clientWidth\n    const ch = ofs.clientHeight\n    const cRate = ofs.clientWidth / ofs.clientHeight\n    const vRate = ofs.width / ofs.height\n    //\n    dx = 0\n    dy = 0\n    dw = vw\n    dh = vh\n    sx = 0\n    sy = 0\n    sw = vw\n    sh = vh\n    // const scale = Math.min(cw / vw, ch / vh)\n    // console.log('scale', scale)\n    //\n    // switch (this.op.mode) {\n    //   case 'AspectFill':\n    //   case 'vertical': //fit vertical | AspectFill 竖屏\n    //     // if (vRate >= cRate) {\n    //     sw = vh * cRate\n    //     sh = vh\n    //     sx = (vw - sw) / 2\n    //     sy = 0\n    //     // } else {\n    //     //   sh = vw / cRate\n    //     //   sw = vw\n    //     //   sx = 0\n    //     //   sy = (vw - sh) / 2\n    //     // }\n    //     break\n    //   case 'AspectFit':\n    //   case 'horizontal': //fit horizontal | AspectFit 横屏\n    //     // scaleX = 1\n    //     // scaleY = canvasAspect / videoAspect\n\n    //     break\n    //   case 'contain':\n    //     // scaleY = 1\n    //     // scaleX = videoAspect / canvasAspect\n    //     // if (scaleX > 1) {\n    //     //   scaleY = 1 / scaleX\n    //     //   scaleX = 1\n    //     // }\n    //     break\n    //   case 'Fill':\n    //   case 'cover':\n    //     // scaleY = 1\n    //     // scaleX = videoAspect / canvasAspect\n    //     // if (scaleX < 1) {\n    //     //   scaleY = 1 / scaleX\n    //     //   scaleX = 1\n    //     // }\n    //     break\n    //   default:\n    //     break\n    // }\n    if (this.op.mode) {\n      sw = vh * cRate\n      sh = vh\n      sx = (vw - sw) / 2\n      sy = 0\n    }\n\n    return [sx, sy, sw, sh, dx, dy, dw, dh]\n  }\n  // setPlay(isPlayer: boolean) {\n  //   this.isPlay = isPlayer\n  // }\n  public videoSeekedEvent() {\n    logger.debug('[canvas2d][videoSeekedEvent]')\n    return this.renderCache.mCache.videoSeekedEvent()\n  }\n  async setup(video?: HTMLVideoElement) {\n    if (!video) throw new Error('video must support!')\n    //\n    await this.renderCache.setup()\n    //\n    this.video = video\n    //\n    if (!this.op.fps) {\n      this.op.fps = 10\n    }\n    await this.videoEntity.setup()\n    // console.log('fps', this.op.fps)\n    //\n    const canvas = document.createElement('canvas')\n    this.op.container.appendChild(canvas)\n    canvas.width = video.videoWidth / 2\n    canvas.height = video.videoHeight\n    this.context = canvas.getContext('2d')\n    this.canvas = canvas\n    //\n    this.ofs.width = video.videoWidth\n    this.ofs.height = video.videoHeight\n\n    this.canvasKey.width = canvas.width\n    this.canvasKey.height = canvas.height\n    //\n    const descript = this.videoEntity?.config?.descript\n    const effect = this.videoEntity?.config?.effect\n    if (descript) {\n      const [x, y, w, h] = descript.rgbFrame\n      canvas.width = w\n      canvas.height = h\n      this.ofs.width = descript.width\n      this.ofs.height = descript.height\n    }\n    if (effect) {\n      for (const k in effect) {\n        const r = effect[k]\n        if (r.img) {\n          this.drawEffect[r.effectId] = r\n        }\n      }\n    }\n    this.setSizeCanvas(canvas, this.op.resizeCanvas)\n  }\n  destroy() {\n    this.clear()\n    this.videoEntity.destroy()\n    if (this.canvas) {\n      this.canvas.remove()\n      delete this.canvas\n      this.canvas = null\n    }\n    this.removeCanvas(this.ofs)\n    this.removeCanvas(this.alphaCanvas)\n    this.removeCanvas(this.canvasKey)\n    this.drawEffect = undefined\n  }\n  clear() {\n    if (typeof this.video !== 'undefined' && this.context)\n      this.context.clearRect(0, 0, this.video?.videoWidth, this.video?.videoHeight)\n  }\n  render(frame = 0) {\n    const {width: w, height: h} = this.canvas\n    //\n    const [sx, sy, sw, sh, dx, dy, dw, dh] = this.getScale()\n    // console.log('scale', sx, sy, sw, sh, dx, dy, dw, dh, w, h)\n    // cache获取帧动画直接渲染 不用处理坐标\n    //***取消canvas2d的缓存功能\n    // this.drawWithCache(frame)\n    const descript = this.videoEntity?.config?.descript\n    if (descript) {\n      this.renderMix(frame)\n    } else {\n      this.renderLR(frame)\n    }\n    this.context.clearRect(dx, dy, dw, dh)\n    this.context.drawImage(this.ofs, sx, sy, sw, sh, dx, dy, dw, dh)\n    //***取消canvas2d的缓存功能\n    // this.saveFrameCache(frame)\n  }\n  /* private getimgDataByBitmap(bitmap, w, h) {\n    const canvas = document.createElement('canvas')\n    canvas.getContext('2d').drawImage(bitmap, 0, 0, w, h)\n    return canvas.getContext('2d').getImageData(0, 0, w, h)\n  } */\n  drawWithCache(frame) {\n    if (this.op.useFrameCache) {\n      const [sx, sy, sw, sh, dx, dy, dw, dh] = this.getScale()\n      const frameItem = this.renderCache.getCache(frame)\n      console.log('[canvas2d frameItem]', frame, frameItem)\n      if (frameItem && frameItem !== 'skip') {\n        // this.context.clearRect(0, 0, w, h)\n        // this.context.drawImage(frameItem, 0, 0, w, h, 0, 0, w, h)\n        this.context.clearRect(dx, dy, dw, dh)\n        this.context.drawImage(frameItem, sx, sy, sw, sh, dx, dy, dw, dh)\n        return true\n      }\n    }\n  }\n  saveFrameCache(frame) {\n    if (this.op.useFrameCache) {\n      this.renderCache.setCache(frame)\n    }\n  }\n  renderKey(frame = 0) {\n    const frameData = this.videoEntity.getFrame(frame)\n    const frameItem = frameData ? frameData[this.videoEntity.data] : undefined\n    // let posArr: any = []\n    // const {width: vW, height: vH} = descript\n    // console.log('effect', frameItem)\n    if (frameItem) {\n      frameItem.forEach((o: VideoAnimateDataItemType) => {\n        // const [rgbX, rgbY] = descript.rgbFrame\n        const [x, y, w, h] = o[this.videoEntity.renderFrame]\n        const [mX, mY, mW, mH] = o[this.videoEntity.outputFrame]\n        const effectId = o[this.videoEntity.effectId]\n        const isTextType = this.videoEntity.isTextTypeById(effectId)\n\n        // logger.debug(\n        //   'renderKey: ',\n        //   mX,\n        //   mY,\n        //   mW,\n        //   mH,\n        //   x,\n        //   y,\n        //   w,\n        //   h,\n        //   ', effectId=' + effectId + ',frame=' + frame + ',scale=' + w / mW,\n        //   ',isTextType=' + isTextType\n        // )\n        const r = this.drawEffect[effectId] || {}\n\n        if (r.img && w > 0 && h > 0 && mH > 0 && mW > 0) {\n          this.ctxKey.clearRect(0, 0, w, h)\n          this.ctxKey.drawImage(r.img, 0, 0, w, h)\n          let imageData = this.ctxKey.getImageData(0, 0, w, h)\n          // text key合并alphaData会显示黑色背景，暂时不合并alphaData，能满足绝大部分的需求，后续再进一步优化text key的渲染\n          if (!isTextType) {\n            const alphaData = this.ctx.getImageData(mX, mY, mW, mH)\n            imageData = this.mixImageData(imageData, alphaData, w / mW)\n          }\n\n          this.ctxKey.clearRect(0, 0, w, h)\n          this.ctxKey.putImageData(imageData, 0, 0)\n\n          this.ctx.drawImage(this.canvasKey, 0, 0, w, h, x, y, w, h)\n        }\n      })\n    }\n  }\n  renderMix(frame = 0) {\n    const descript = this.videoEntity.config?.descript\n    if (!this.ctx || !this.isPlay || typeof this.video === 'undefined' || !descript) return\n    // console.log(info)\n    const [x, y, w, h] = descript.rgbFrame\n    const [ax, ay, aw, ah] = descript.alphaFrame\n    this.ctx.clearRect(ax, ay, w, h) //清空alpha图层\n    //\n    // console.log(' descript.alphaFrame', descript.alphaFrame)\n    const vw = this.video.videoWidth\n    const vh = this.video.videoHeight\n    this.ctx.drawImage(this.video, 0, 0, vw, vh, 0, 0, vw, vh)\n    //合并alpha图层\n    let colorImageData = this.ctx.getImageData(x, y, w, h)\n    const alpathImageData = this.ctx.getImageData(ax, ay, aw, ah)\n    colorImageData = this.mixImageData(colorImageData, alpathImageData, w / aw)\n    // console.log('renderMix scale=', w / aw, 'frame=' + frame)\n    this.ctx.clearRect(0, 0, w, h)\n    this.ctx.putImageData(colorImageData, 0, 0, 0, 0, w, h)\n    // this.ctx.clearRect(ax, ay, w, h) //清空alpha图层\n    // this.ctx.putImageData(alpathImageData, 0, 0, 0, 0, w, h)\n    // 渲染 key list\n    this.renderKey(frame)\n    //\n    // this.ctx.clearRect(ax, ay, w, h) //清空alpha图层\n  }\n\n  mixImageData(colorImageData, alpathImageData, scale = 1) {\n    if (Math.abs(scale - 1) > 0.001) alpathImageData = this.scaleImageData(alpathImageData, scale)\n    const len = Math.min(colorImageData?.data.length, alpathImageData?.data.length)\n    for (let i = 3; i < len; i += 4) {\n      const opacity = alpathImageData.data[i - 1]\n      colorImageData.data[i] = opacity\n      if (opacity > 0) {\n        colorImageData.data[i - 1] = Math.min(255, Math.ceil((colorImageData.data[i - 1] * 255) / opacity))\n        colorImageData.data[i - 2] = Math.min(255, Math.ceil((colorImageData.data[i - 2] * 255) / opacity))\n        colorImageData.data[i - 3] = Math.min(255, Math.ceil((colorImageData.data[i - 3] * 255) / opacity))\n      }\n    }\n    return colorImageData\n  }\n  // scaleImageData(imageData, scale) {\n  //   const ctx = this.alphaCtx\n  //   const scaled = ctx.createImageData(imageData.width * scale, imageData.height * scale)\n  //   const subLine = ctx.createImageData(scale, 1).data\n  //   for (let row = 0; row < imageData.height; row++) {\n  //     for (let col = 0; col < imageData.width; col++) {\n  //       const sourcePixel = imageData.data.subarray(\n  //         (row * imageData.width + col) * 4,\n  //         (row * imageData.width + col) * 4 + 4,\n  //       )\n  //       for (let x = 0; x < scale; x++) subLine.set(sourcePixel, x * 4)\n  //       for (let y = 0; y < scale; y++) {\n  //         const destRow = row * scale + y\n  //         const destCol = col * scale\n  //         scaled.data.set(subLine, (destRow * scaled.width + destCol) * 4)\n  //       }\n  //     }\n  //   }\n\n  //   return scaled\n  // }\n  scaleImageData(imageData, scale) {\n    if (scale == 1) {\n      return imageData\n    }\n\n    const ctx = this.alphaCtx\n    const scaleWidth = Math.floor(imageData.width * scale)\n    const scaleHeight = Math.floor(imageData.height * scale)\n    const scaled = ctx.createImageData(scaleWidth, scaleHeight)\n    const imageDataWidth = imageData.width\n    const imageDataHeight = imageData.height\n\n    for (let row = 0; row < imageDataHeight; row++) {\n      for (let col = 0; col < imageDataWidth; col++) {\n        // const sourcePixel = [\n        //   imageData.data[(row * imageData.width + col) * 4 + 0],\n        //   imageData.data[(row * imageData.width + col) * 4 + 1],\n        //   imageData.data[(row * imageData.width + col) * 4 + 2],\n        //   imageData.data[(row * imageData.width + col) * 4 + 3],\n        // ]\n        const sourceIndex = (row * imageData.width + col) * 4\n        const sourcePixel = imageData.data.subarray(sourceIndex, sourceIndex + 4)\n        for (let y = 0; y < scale; y++) {\n          const destRow = Math.floor(row * scale) + y\n          for (let x = 0; x < scale; x++) {\n            const destCol = Math.floor(col * scale) + x\n            // for (let i = 0; i < 4; i++) {\n            // scaled.data[(destRow * scaleWidth + destCol) * 4 + i] = sourcePixel[i]\n            // }\n            const destIndex = (destRow * scaleWidth + destCol) * 4\n            scaled.data.set(sourcePixel, destIndex)\n          }\n        }\n      }\n    }\n\n    return scaled\n  }\n  renderLR(frame = 0) {\n    if (!this.ctx || !this.isPlay || typeof this.video === 'undefined') return\n    const vw = this.video.videoWidth\n    const vh = this.video.videoHeight\n    const stageWidth = vw / 2\n    const stageHeight = vh\n    this.ctx.drawImage(this.video, 0, 0, vw, vh, 0, 0, vw, vh)\n    // 渲染 key list\n    // this.renderKey(frame)// descript为空时 没有 key\n    //\n    if (this.op.alphaDirection === 'left') {\n      const colorImageData = this.ctx.getImageData(stageWidth, 0, stageWidth, stageHeight)\n      const alpathImageData = this.ctx.getImageData(0, 0, stageWidth, stageHeight)\n      this.mixImageData(colorImageData, alpathImageData)\n      this.ctx.putImageData(colorImageData, 0, 0, 0, 0, stageWidth, stageHeight)\n    } else {\n      const alpathImageData = this.ctx.getImageData(stageWidth, 0, stageWidth, stageHeight)\n      const colorImageData = this.ctx.getImageData(0, 0, stageWidth, stageHeight)\n      this.mixImageData(colorImageData, alpathImageData)\n      this.ctx.putImageData(colorImageData, 0, 0, 0, 0, stageWidth, stageHeight)\n      // this.ctx.clearRect(ax, ay, w, h) //清空alpha图层 这个一般用不到\n    }\n  }\n}\n"],"mappings":"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"}