{"version":3,"file":"utils-BfAnalCD.mjs","names":["config"],"sources":["../src/helper/config.ts","../src/helper/logger.ts","../src/type/mix.ts","../src/helper/polyfill.ts","../src/helper/utils.ts"],"sourcesContent":["export default {\n  env: process.env.ENV,\n  mode: process.env.ENV,\n  version: process.env.PKGVERSION,\n}\n","import config from 'src/helper/config'\nimport type EVideo from 'src/player'\nimport type {MixEvideoOptions} from 'src/type/mix'\nconst prefixName = 'YYEVA'\nexport type ConsoleFn = (message?: any, ...optionalParams: any[]) => void\nexport type LogTypes = 'debug' | 'info' | 'warn' | 'error'\nexport type LogParams = {\n  level?: LogTypes\n  channel?: string\n  showtips?: boolean\n}\nexport class Logger {\n  warn: ConsoleFn\n  error: ConsoleFn\n  debug: ConsoleFn\n  info: ConsoleFn\n  log: ConsoleFn\n  op: Required<LogParams> = {\n    level: 'debug',\n    channel: '',\n    showtips: true,\n  }\n  private colors = {\n    debug: '#3498db',\n    info: '#16a085',\n    warn: '#e67e22',\n    error: '#e74c3c',\n  }\n  private levels = {\n    debug: 1,\n    info: 2,\n    warn: 3,\n    error: 4,\n  }\n  private logType(type: LogTypes) {\n    const s = type.toLocaleUpperCase()\n    let rs: any[] = []\n    if (this.op.showtips)\n      rs = [\n        `%c ${this.op.channel || prefixName} %c ${s} `,\n        `background:#2c3e50;color:#fff;padding: 1px;border-radius: 2px 0 0 2px;`,\n        `background:${this.colors[type]};color: #fff;padding: 1px; border-radius: 0 2px 2px 0;`,\n      ]\n    return rs\n  }\n  constructor() {}\n  setup(options?: LogParams) {\n    const {channel, level, showtips} = (self as any).LoggerConfig || {}\n    this.op = {...this.op, ...options}\n    if (typeof showtips === 'boolean') this.op.showtips = showtips\n    const lv = level ? this.levels[level] : this.op.level ? this.levels[this.op.level] : config.mode === 'dev' ? 1 : 2\n    const useChannel = !channel || channel === this.op.channel\n    const silenceFn = (...args: any[]) => {\n      //:TODO 增加上报逻辑\n      // console.log(...args)\n    }\n    this.error = lv <= 4 && useChannel ? console.error.bind(console, ...this.logType('error')) : silenceFn\n    this.warn = lv <= 3 && useChannel ? console.warn.bind(console, ...this.logType('warn')) : silenceFn\n    this.info = lv <= 2 && useChannel ? console.log.bind(console, ...this.logType('info')) : silenceFn\n    this.log = lv <= 2 && useChannel ? console.log.bind(console, ...this.logType('info')) : silenceFn\n    this.debug = lv <= 1 && useChannel ? console.log.bind(console, ...this.logType('debug')) : silenceFn\n  }\n}\n// window.LoggerConfig = {\n//   level: 'warn',\n//   channel: 'LoggerTsx',\n//   showtips: false,\n// }\nexport const logger = new Logger()\n// 全局引用\nexport default logger\n\n// version\nexport const versionTips = (op: MixEvideoOptions, player: EVideo) => {\n  if (op.showPlayerInfo === 'table') {\n    return console.table({\n      Version: config.version,\n      RenderType: op.renderType === 'canvas2d' ? op.renderType : `WebGL.${player.webglVersion}`,\n      FPS: player.fps,\n      DisplayMode: op.mode,\n      LoadType: op.usePrefetch ? ' MSE' : 'src',\n      OffScreenRender: !!op.useOfsRender,\n      UseFrameCache: !!op.useFrameCache,\n      UseVideoDBCache: !!op.useVideoDBCache,\n      AnimationType: player.animationType,\n      //\n    })\n  }\n  // console.log('player', player.renderType)\n  console.log(\n    `%c ${prefixName} ${config.version} %c ${player.renderType.toUpperCase()}${player.webglVersion ? `.${player.webglVersion}` : ''}${self.devicePixelRatio ? ` DPR.${self.devicePixelRatio}` : ''}${` FPS.${player.fps}`}${\n      op.mode ? ` ${op.mode}` : ''\n    }${op.isHevc ? ' H265' : ' H264'}${op.usePrefetch ? ' MSE' : ''}${op.useOfsRender ? ' OfsRender' : ''}${\n      op.useFrameCache ? ` FrameCache` : ''\n    }${op.useVideoDBCache ? ` VideoCache` : ''}${\n      // op.useAccurate && 'requestVideoFrameCallback' in HTMLVideoElement.prototype ? ' Accurate' : ''\n      ` ${player.animationType}`\n    } %c`,\n    'background:#34495e ; padding: 1px; border-radius: 2px 0 0 2px;  color: #fff',\n    'background:#16a085 ; padding: 1px; border-radius: 0 2px 2px 0;  color: #fff',\n    'background:transparent',\n  )\n}\n","// import {LOG_LEVEL} from 'src/helper/log'\nimport type {LogTypes} from 'src/helper/logger'\n\n/**\n * 日志级别\n */\nexport type LoggerLevelType = 'trace' | 'debug' | 'info' | 'log' | 'time' | 'warn' | 'error' | 'off'\n\nexport type AlphaDirection = 'left' | 'right'\nexport type EventCallback = undefined | ((...args: any) => void)\n//AspectFill 竖屏 AspectFit 横屏\nexport type ModeType = 'AspectFill' | 'AspectFit' | 'Fill' | 'vertical' | 'horizontal' | 'contain' | 'cover'\n\nexport enum EPlayError {\n  NotAllowedError = 'NotAllowedError', // 不允许播放 需要交互\n}\n\nexport enum EPlayStep {\n  canplaythrough = 'canplaythrough', // 已经加载到可以播放的情度\n  muted = 'muted', // 设为静音后再次播放\n}\n\nexport interface onErrorEvent {\n  playError: EPlayError\n  playStep: EPlayStep\n  video: HTMLVideoElement\n}\nexport type ResizeCanvasType = 'percent' | 'percentW' | 'percentH' | 'size'\nexport type RenderType = 'webgl' | 'webgpu' | 'canvas2d'\nexport type MixEvideoOptions = VideoEvent & {\n  /**\n   * 全屏模式模式\n   */\n  mode?: ModeType\n  /**\n   * debug 模式显示视频情况\n   * @default false\n   */\n  showVideo?: boolean\n  /**\n   * web worker 模式 ::TODO\n   */\n  useWorker?: boolean\n  /**\n   * 循环播放\n   * @default true\n   */\n  loop?: boolean | number\n  /**\n   * 自动播放\n   * @default true\n   */\n  autoplay?: boolean\n  /**\n   * 停止到某一帧，默认停止到最后一帧\n   * @default undefined\n   */\n  endFrame?: number\n  /**\n   * 播放完毕后是否暂停, 传true的话，清理时，需要外部调用destroy释放资源\n   * @default false\n   */\n  endPause?: boolean\n  /**\n   * 动画容器\n   */\n  container: HTMLElement\n  /**\n   * video http 连接 或 file 对象\n   */\n  videoUrl: string | File\n  /**\n   * 提供给 op传输\n   */\n  videoSource?: string\n  /**\n   * hevc、h265 格式 http 连接 或 file 对象\n   */\n  hevcUrl?: string | File\n  isHevc?: boolean\n  /**\n   * video id\n   * 用来做唯一播放对象处理 不重复注销video标签 适配微信 (目前是支持多video标签)\n   * @default null\n   */\n  videoID?: string\n  /**\n   * 描述文件连接\n   */\n  dataUrl?: string\n  /**\n   * 主要是指 mimeType MIME媒体类型\n   * https://developer.mozilla.org/en-US/docs/Web/API/MediaSource/isTypeSupported\n   */\n  mimeCodec?: string\n  /**\n   * 设置后主动降帧\n   */\n  fps?: number\n  /**\n   * 制定播放帧 ::TODO\n   */\n  offset?: number\n  /**\n   * MSE 预加载模式\n   * @default true\n   */\n  usePrefetch?: boolean\n  /**\n   * 启动静音 适配 chrome 自动播放\n   * @default true\n   */\n  mute?: boolean\n  /**\n   * 使用bitmap 替代 imageElm 离屏模式必须\n   * @default true\n   */\n  useBitmap?: boolean\n  /**\n   * 启用 requestVideoFrameCallback,自动判断是否支持并且降级为 requestAnimationFrame\n   * @default true\n   */\n  useAccurate?: boolean\n  /**\n   * 非 mix模式下 判断左右视频 ::TODO 加入上下模式\n   * @default left\n   */\n  alphaDirection?: AlphaDirection\n  /**\n   * 渲染模式\n   * @default webgl\n   */\n  renderType?: RenderType\n  /**\n   * 兼容vap 启动后 不需要填写 dataUrl\n   * usePrefetch 强制打开\n   * @default false\n   */\n  useMetaData?: boolean\n  /**\n   * 字体全局配置\n   */\n  color?: string\n  style?: string\n  fontStyle?: string | any\n  font?: {\n    overflow: 'zoom' | 'cut' //  适配文本框宽度方式,超出文本框时:  'zoom'缩放  'cut'截取后段文本...\n  }\n  /**\n   * effects\n   * 业务内容 k 为 effectTag\n   * text 可以加入 text\n   */\n  effects?: {\n    [k: string]: any\n    fontColor?: string\n    fontSize?: number\n    fontStyle?: string\n  }\n  /**\n   * useVideoDBCache 使用视频缓存\n   * @default true\n   */\n  useVideoDBCache?: boolean\n  /**\n   * useFrameCache 使用缓存帧 与 帧数\n   * @default 5\n   */\n  useFrameCache?: boolean | number\n  /**\n   * useOfsRender 使用 多canvas 渲染同步\n   * @default false\n   */\n  useOfsRender?: boolean\n  /**\n   * resizeCanvas\n   * 设置 canvas大小\n   * @options percent 为 width 100% height 100%\n   * @options percentW 为 width 100%\n   * @options percentH 为 height 100%\n   * @options size 为 原尺寸\n   * @default percent\n   */\n  resizeCanvas?: ResizeCanvasType\n  /**\n   * @default info\n   */\n  logLevel?: LogTypes\n  /**\n   * showPlayerInfo\n   * @default true\n   */\n  showPlayerInfo?: boolean | 'table'\n  /**\n   * onRequestClickPlay\n   * 微信&安卓端不能自动播放\n   * mute=false 不能自动播放\n   * 需要回调点击事件用户通过 video.play()触发一次\n   */\n  onRequestClickPlay?: (container: HTMLElement, video: HTMLVideoElement) => void\n  // [key: string]: any\n  /**\n   * forceBlob\n   * 强制使用 blob 不受polyfill 影响\n   * @default false\n   */\n  forceBlob?: boolean\n  /**\n   * 播放超时开关\n   * @default false\n   */\n  checkTimeout?: boolean\n}\n\nexport type VideoDataInfoType = {\n  videoW: number\n  videoH: number\n  w: number\n  h: number\n  fps: number\n  isVapx: number\n  rgbFrame: number[]\n  aFrame: number[]\n  mediaTime?: number\n}\nexport type VideoDataSrcType = {\n  w: number\n  h: number\n  srcId: number\n  srcTag: string\n  srcType: string\n  img?: ImageData | HTMLImageElement | ImageBitmap\n  textStr?: string\n  color?: string\n  style?: string\n  fontStyle?: string | any\n}\nexport type VideoDataFrameType = {\n  i: number\n  obj: VideoDataFrameObjType[]\n}\nexport type VideoDataFrameObjType = {\n  frame: number[]\n  srcId: number\n  mFrame: number[]\n}\nexport type VideoDataType = {\n  info: VideoDataInfoType\n  src: VideoDataSrcType[]\n  frame: VideoDataFrameType[]\n}\n\nexport type MetaDataType = {\n  /**\n   * 视频当前帧\n   */\n  presentedFrames: number\n  presentationTime: number\n  expectedDisplayTime: number\n  width: number\n  height: number\n  processingDuration: number\n  /**\n   * 视频当前播放时间\n   */\n  mediaTime: number\n}\n\ntype RemoveField<T, Field> = {\n  [K in keyof T as Exclude<K, Field>]: T[K]\n}\nexport type EVideoPlayerType = {\n  op: RemoveField<MixEvideoOptions, 'container'>\n  className?: string\n  events?: VideoEvent\n}\nexport type VideoEvent = {\n  onStart?: EventCallback\n  onResume?: EventCallback\n  onPause?: EventCallback\n  onStop?: EventCallback\n  onProcess?: EventCallback\n  onEnd?: EventCallback\n  onError?: EventCallback\n  onLoopCount?: EventCallback\n  onGetConfig?: (op: MixEvideoOptions) => void\n}\n\nexport type VideoAnimateType = {\n  /**\n   * 每一帧的动态元素位置信息\n   */\n  datas: VideoAnimateDataType[]\n  /**\n   * 视频的描述信息\n   */\n  descript: VideoAnimateDescriptType\n  /**\n   * 动态元素的遮罩描述信息\n   */\n  effect: VideoAnimateEffectType[]\n}\n\nexport enum EScaleMode {\n  aspectFill = 'aspectFill',\n  aspectFit = 'aspectFit',\n  scaleFill = 'scaleFill',\n}\n\nexport type VideoAnimateEffectType = {\n  effectWidth: number //动态元素宽\n  effectHeight: number //动态元素高\n  effectId: number | string //动态元素索引id\n  effectTag: string //动态元素的tag\n  effectType: 'txt' | 'img' ////动态元素类型\n  // 业务关联\n  img?: ImageData | HTMLImageElement | ImageBitmap\n  text: string\n  fontColor?: string\n  fontSize?: number\n  scaleMode: EScaleMode\n  [key: string]: any\n}\n\nexport type VideoAnimateDescriptType = {\n  width: number //输出视频的宽\n  height: number //输出视频的高\n  isEffect: number //是否为动态元素视频\n  version: number //插件的版本号\n  rgbFrame: number[] //rgb位置信息\n  alphaFrame: number[] //alpha位置信息\n  fps: number\n  hasAudio?: boolean\n}\n\nexport type VideoAnimateDataType = {\n  frameIndex: number\n  data: VideoAnimateDataItemType[]\n  [key: string]: any\n}\n\nexport type VideoAnimateDataItemType = {\n  renderFrame: number[] //在画布上的位置\n  effectId: number | string //标志是哪个动态元素\n  outputFrame: number[] //在视频区域的位置\n  [key: string]: any\n}\n\nexport type WebglVersion = 1 | 2 | null\n","import {logger} from './logger'\n\nconst ua = navigator.userAgent.toLowerCase()\n\nexport const isWeixin = ua.indexOf('micromessenger') > -1\nexport const isBaidu = /baidu/.test(ua)\nexport const isIOS = /iphone|ipad|ipod/i.test(ua)\nexport const isMac = /macintosh/i.test(ua)\nexport const isSafari = /^((?!chrome|android).)*safari/i.test(ua)\nexport const isApple = isIOS || isMac\nexport const isQQbrw = ua.indexOf('mqqbrowser') > -1\nexport const isAndroid = /android|adr/i.test(ua)\n//\nexport const isUCBrowser = ua.indexOf('ucbrowser') > -1 // UC浏览器\nexport const isQuark = ua.indexOf('quark') > -1 // 夸克浏览器\n\nexport const isHarmonyOS  = ua.indexOf('harmonyos') > -1;\n\nexport const getChromeVersion = () => {\n  const s = ua.match(/chrome\\/([\\d\\.]+)/)\n  let v: any = s ? s[1] : '0.0.0'\n  v = v.split('.')[0]\n  v = v ? Number(v) : 0\n  return v\n}\n\nexport const polyfill = {\n  baidu: isBaidu,\n  weixin: isWeixin,\n  apple: isApple,\n  ios: isIOS,\n  android: isAndroid,\n  uc: isUCBrowser,\n  quark: isQuark,\n  mac: isMac,\n  safari: isSafari,\n  harmony: isHarmonyOS\n}\n//\nexport type PolyfillType = typeof polyfill\n//\nexport const clickPlayBtn = (container: HTMLElement, video: HTMLVideoElement) => {\n  const tips: HTMLElement = document.createElement('div')\n  tips.innerText = 'Click To Play'\n  tips.style.textAlign = 'center'\n  tips.style.background = 'rgba(255,255,255,0.7)'\n  tips.style.position = 'absolute'\n  tips.style.zIndex = '99999'\n  tips.style.top = '50%'\n  tips.style.left = '50%'\n  tips.style.padding = '10px'\n  tips.style.transform = 'translate(-50%,-50%)'\n  tips.style.cursor = 'pointer'\n  tips.style['border-radius'] = '5px'\n  container.appendChild(tips)\n  // 避免 video 被注销 每次都重新生命 点击事件\n  tips.onclick = () => {\n    video.play()\n    tips.style.display = 'none'\n  }\n  return tips\n}\n\nexport const isHevc = (video: HTMLVideoElement) => {\n  // https://cconcolato.github.io/media-mime-support/\n  // console.log('video/mp4; codecs=\"hev1.1.6.L93.B0\"', video.canPlayType('video/mp4; codecs=\"hev1.1.6.L93.B0\"'))\n  // console.log('video/mp4; codecs=\"hev1.2.4.L120.B0\"', video.canPlayType('video/mp4; codecs=\"hev1.2.4.L120.B0\"'))\n  return !!(\n    video.canPlayType('video/mp4; codecs=\"hev1.1.6.L93.B0\"') ||\n    video.canPlayType('video/mp4; codecs=\"hvc1.1.6.L93.B0\"') ||\n    video.canPlayType('video/mp4; codecs=\"hev1.2.4.L120.B0\"')\n  )\n}\n// wechat ios polyfill\nconst win: any = window\nwin.yyeva_wx_is_ready = !!win.yyeva_wx_is_ready\nclass WechatPolyfill {\n  private isReady = false\n  get ready() {\n    return win.yyeva_wx_is_ready || this.isReady\n  }\n  set ready(b: boolean) {\n    win.yyeva_wx_is_ready = b\n    this.isReady = b\n  }\n  initVideoIDPosition(list: string[]) {\n    if (!polyfill.weixin || !polyfill.ios) {\n      return\n    }\n    //\n    document.addEventListener('WeixinJSBridgeReady', () => {\n      this.ready = true\n      list.map(v => {\n        const video = document.createElement('video')\n        video.setAttribute('id', v)\n        document.body.appendChild(video)\n        video.style.visibility = 'hidden'\n      })\n    })\n  }\n  wxReady() {\n    logger.debug('[wxReady] resolve', this.ready)\n    return new Promise(resolve => {\n      if (!polyfill.weixin || !polyfill.ios) {\n        resolve(true)\n        return\n      }\n      // === 当异步引用 YYEVA 会引起 WeixinJSBridgeReady 失效 需要手动设置 wxIsReady 为 true\n      if (this.ready) {\n        resolve(true)\n        logger.debug('[wxReady] resolve', this.ready)\n        return\n      }\n      const timer = setInterval(() => {\n        logger.debug('[wxReady] setInterval', this.ready)\n        if (this.ready === true) {\n          clearInterval(timer)\n          resolve(true)\n        }\n      }, 300)\n      // === 同时引用时 触发,异步无法触发该方法\n      document.addEventListener('WeixinJSBridgeReady', () => {\n        logger.debug('[wxReady] WeixinJSBridgeReady', this.ready)\n        this.ready = true\n        timer && clearInterval(timer)\n        resolve(true)\n      })\n    })\n  }\n}\nexport const wechatPolyfill = new WechatPolyfill()\n","import {logger} from 'src/helper/logger'\nimport {getChromeVersion, isAndroid} from './polyfill'\n\n/**\n * 判断链接是否 dataUrl (base64)\n * @param url\n * @returns boolean\n */\nexport const isDataUrl = (url: string | HTMLInputElement) => {\n  if (url instanceof HTMLInputElement) return false\n  const regex =\n    /^\\s*data:([a-z]+\\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\\-._~:@\\/?%\\s]*?)\\s*$/i\n  return regex.test(url)\n}\n// const currentVideoId = Date.now()\n// export const getVIdeoId = url => {\n//   // if (polyfill.weixin) return `e-video-wx-${currentVideoId}`\n//   // // if (polyfill.quark) return `quark_${Math.round(Math.random() * 1000)}_${url}`\n//   // else return url\n//   return url\n// }\n\nexport function isOffscreenCanvasSupported() {\n  /**\n+ Chrome browser version 4 to Chrome browser version 57 doesn't supports HTML5 OffscreenCanvas. Chrome browser version 58 to 70 does not support but can be enabled.\n+ Mozilla Firefox browser version 2 to Mozilla Firefox browser version 43 doesn't supports HTML5 OffscreenCanvas property. Mozilla Firefox browser version 57 to 63 partially supports HTML5 OffscreenCanvas property and partial support for Firefox refers to supporting an older version for the web browser.\n+ Internet Explorer browser version 6 to Internet Explorer browser version 11 doesn't supports HTML5 OffscreenCanvas property.\n+ Safari browser version 3.1 to Safari browser version 12 doesn't supports supports HTML5 OffscreenCanvas.\n+ Microsoft Edge browser version 12 to Microsoft Edge browser version 18 doesn't supports HTML5 OffscreenCanvas property.\n+ Opera browser version 10.1 to Opera browser version 44 doesn't supports HTML5 OffscreenCanvas. Opera browser version 45 to Opera browser version 53 does not support but can be enabled.\n   */\n  if (isAndroid && getChromeVersion() <= 70) {\n    return false\n  }\n  return typeof OffscreenCanvas !== 'undefined' && self.OffscreenCanvas\n}\n\n// Use a fake element\n//https://phuoc.ng/collection/html-dom/measure-the-width-of-given-text-of-given-font/\nexport function getTextByMaxWidth(text: string, font: string, maxWidth: number) {\n  // Create an element\n  const ele = document.createElement('div')\n\n  // Set styles\n  ele.style.position = 'absolute'\n  ele.style.visibility = 'hidden'\n  ele.style.whiteSpace = 'nowrap'\n  ele.style.left = '-9999px'\n\n  // Set font and text\n  ele.style.font = font\n  ele.innerText = text\n\n  // Append to the body\n  document.body.appendChild(ele)\n\n  let str = text\n  // Get the width\n  let width = window.getComputedStyle(ele).width\n  logger.debug('getTextByMaxWidth width=', width)\n  if (Number.parseInt(width, 10) > maxWidth) {\n    let len = text.length\n    while (true) {\n      str = text.substring(0, len - 1) + '...'\n      ele.innerText = str\n      width = window.getComputedStyle(ele).width\n      logger.debug('getTextByMaxWidth.. width=', width, str)\n      if (Number.parseInt(width, 10) <= maxWidth) {\n        break\n      }\n      len = len - 1\n    }\n  }\n\n  // Remove the element\n  document.body.removeChild(ele)\n\n  return str\n}\n\nexport function detectAudio(videoElement) {\n  return new Promise(resolve => {\n    const checkAudio = () => {\n      // Firefox\n      if (typeof videoElement.mozHasAudio !== 'undefined') {\n        resolve(videoElement.mozHasAudio)\n        return\n      }\n\n      // Webkit browsers\n      if (typeof videoElement.webkitAudioDecodedByteCount !== 'undefined') {\n        resolve(videoElement.webkitAudioDecodedByteCount > 0)\n        return\n      }\n\n      // Standard method\n      if (videoElement.audioTracks) {\n        resolve(videoElement.audioTracks.length > 0)\n        return\n      }\n\n      // 最后的兼容方案\n      resolve(false)\n    }\n\n    if (videoElement.readyState >= 1) {\n      checkAudio()\n    } else {\n      videoElement.addEventListener('loadedmetadata', checkAudio, {once: true})\n    }\n  })\n}\n"],"mappings":"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"}