HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/buyercall/node_modules/vue-audio-visual/src/components/AvBase.js
import * as vue from 'vue'
/**
 * Mixin component with base and common properties and functions.
 */

/**
 * Base properties common for the audio-visual components
 */
const props = {
  /**
   * prop: 'audio-src'
   * Audio element src attribute. When provided creates audio element
   */
  audioSrc: {
    type: String,
    default: null
  },
  /**
   * prop: 'audio-sink-device-id'
   * Audio sink device id. When provided sets audio output device.
   */
  audioSinkDeviceId: {
    type: String,
    default: null
  },
  /**
   * prop: 'ref-link'
   * Refrence to Audio element. When provided, then local audio element
   * is not created and use refrence to the element. Component will
   * search only for its parent refs.
   */
  refLink: {
    type: String,
    default: null
  },
  /**
   * prop: 'audio-controls'
   * Audio element controls attribute. When provided should
   * display audio element with controls
   */
  audioControls: {
    type: Boolean,
    default: true
  },
  /**
   * prop: 'cors-anonym'
   * CORS requests for this element will not have the credentials flag set.
   * Set crossOrigin property of audio element to 'anonymous'.
   * Default: null
   */
  corsAnonym: {
    type: Boolean,
    default: false
  },
  /**
   * prop: 'audio-class'
   * Audio element css class name.
   */
  audioClass: {
    type: String,
    default: null
  },
  /**
   * prop: 'canv-width'
   * Canvas element width. Default 300
   */
  canvWidth: {
    type: Number,
    default: 300
  },
  /**
   * prop: 'canv-height'
   * Canvas element height. Default 80
   */
  canvHeight: {
    type: Number,
    default: 80
  },
  /**
   * prop: 'canv-class'
   * Canvas element css class name.
   */
  canvClass: {
    type: String,
    default: null
  },
  /**
   * prop: 'canv-top'
   * Canvas element position on top relatively to audio element.
   * Default: false
   */
  canvTop: {
    type: Boolean,
    default: false
  },
  /**
   * prop: 'canv-fill-color'
   * Canvas fill background color. Can be string RGB color or canvas gradients array.
   * Default is transperent.
   */
  canvFillColor: {
    type: [String, Array],
    default: null
  }
}

const methods = {
  /**
   * Create audio and canvas elements and insert in the HTML template.
   * Using document.createElement to avoid Vue virtual DOM re-rendering
   * which can lead to infinit loops.
   */
  createHTMLElements: function () {
    const canv = document.createElement('canvas')
    const canvDiv = document.createElement('div')
    let audioDiv = null
    let audio = null

    if (this.refLink) {
      audio = this.$parent.$refs[this.refLink]
    } else {
      audio = document.createElement('audio')
      audioDiv = document.createElement('div')
      audio.setAttribute('src', this.audioSrc)
      if (this.audioControls) audio.setAttribute('controls', true)
      if (this.audioClass) audio.setAttribute('class', this.audioClass)
      if (this.corsAnonym) audio.crossOrigin = 'anonymous'
      audioDiv.appendChild(audio)
      this.$el.appendChild(audioDiv)
    }

    if (this.canvClass) canv.setAttribute('class', this.canvClass)
    if (this.canvWidth) canv.setAttribute('width', this.canvWidth)
    if (this.canvHeight) canv.setAttribute('height', this.canvHeight)
    canvDiv.appendChild(canv)

    if (this.canvTop) {
      this.$el.insertBefore(canvDiv, audioDiv)
    } else {
      this.$el.appendChild(canvDiv)
    }
    this.ctxWrapper = canv
    this.ctx = canv.getContext('2d')

    this.audio = audio
    this.audio.load()
  },

  /**
   * Set audio context analyser.
   */
  async setAnalyser () {
    this.audioCtx = this.audioCtx || new AudioContext()
    this.analyser = this.analyser || this.audioCtx.createAnalyser()
    const src = this.audioCtx.createMediaElementSource(this.audio)
    const destination = this.audioCtx.createMediaStreamDestination()

    src.connect(this.analyser)
    this.analyser.fftSize = this.fftSize
    this.analyser.connect(destination)

    const audio = new Audio()
    audio.srcObject = destination.stream
    if (this.audioSinkDeviceId) {
      await audio.setSinkId(this.audioSinkDeviceId)
    }
    audio.play()
  },

  /**
   * Canvas gradient. Vertical, from top down
   */
  fillGradient: function (colorsArray) {
    const w = this.canvWidth
    const h = this.canvHeight
    const gradient = this.ctx.createLinearGradient(w / 2, 0, w / 2, h)
    let offset = 0
    colorsArray.forEach(color => {
      gradient.addColorStop(offset, color)
      offset += (1 / colorsArray.length)
    })
    return gradient
  },

  /**
   * Return the inner audio element.
   */
  getAudioElement: function () {
    return this.audio
  }
}

// A fix for webpack warnings across vue2 & vue3
const h = vue['h'[0]]

export default {
  props,
  expose: [
    'getAudioElement'
  ],
  render (hv2) {
    if (h) {
      // Vue3 render
      return h('div')
    }
    // Vue2 render
    return hv2('div')
  },
  mounted () {
    this.createHTMLElements()

    this.audio.onclick = () => {
      if (!this.audioCtx) this.setAnalyser()
    }

    this.audio.onplay = () => {
      this.$emit('playing')
      if (!this.audioCtx) this.setAnalyser()
      this.mainLoop()
      if (this.audioCtx) { // not defined for waveform
        this.audioCtx.resume()
      }
    }

    this.audio.onpause = () => {
      this.$emit('paused')
      if (this.audioCtx) {
        this.audioCtx.suspend()
        cancelAnimationFrame(this.animId)
      }
    }

    this.audio.onended = () => {
      this.$emit('ended')
    }
  },

  beforeDestroy () {
    if (this.audioCtx) {
      this.audioCtx.suspend()
    }
    cancelAnimationFrame(this.animId)
  },
  methods
}