|  | @@ -49,6 +49,7 @@ import Plyr from "plyr";
 | 
	
		
			
				|  |  |  import { Vue3Lottie } from "vue3-lottie";
 | 
	
		
			
				|  |  |  import audioBga from "./images/audioBga.json";
 | 
	
		
			
				|  |  |  import videobg from "./images/videobg.png";
 | 
	
		
			
				|  |  | +import audioVisualDraw from "./audioVisualDraw"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  export default defineComponent({
 | 
	
		
			
				|  |  |    name: 'creation-detail',
 | 
	
	
		
			
				|  | @@ -101,6 +102,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |      })
 | 
	
		
			
				|  |  |      const staffDom= ref<HTMLIFrameElement>()
 | 
	
		
			
				|  |  |      const {playStaff, pauseStaff, updateProgressStaff} = staffMoveInstance()
 | 
	
		
			
				|  |  | +    let isInitAudioVisualDraw =false
 | 
	
		
			
				|  |  |      // 点赞
 | 
	
		
			
				|  |  |      const onStarChange = async () => {
 | 
	
		
			
				|  |  |        await checkLogin();
 | 
	
	
		
			
				|  | @@ -171,20 +173,6 @@ export default defineComponent({
 | 
	
		
			
				|  |  |          fullscreen: { enabled: false },
 | 
	
		
			
				|  |  |        });
 | 
	
		
			
				|  |  |        const player = state._plrl
 | 
	
		
			
				|  |  | -        // 创建音波数据
 | 
	
		
			
				|  |  | -      if(state.playType === "Audio"){
 | 
	
		
			
				|  |  | -        const audioDom = document.querySelector("#audioMediaSrc") as HTMLAudioElement
 | 
	
		
			
				|  |  | -        const canvasDom = document.querySelector("#audioVisualizer") as HTMLCanvasElement
 | 
	
		
			
				|  |  | -        const { pauseVisualDraw, playVisualDraw } = audioVisualDraw(audioDom, canvasDom)
 | 
	
		
			
				|  |  | -        player.on('play', () => {
 | 
	
		
			
				|  |  | -          lottieDom.value.play()
 | 
	
		
			
				|  |  | -          playVisualDraw()
 | 
	
		
			
				|  |  | -        });
 | 
	
		
			
				|  |  | -        player.on('pause', () => {
 | 
	
		
			
				|  |  | -          lottieDom.value.pause()
 | 
	
		
			
				|  |  | -          pauseVisualDraw()
 | 
	
		
			
				|  |  | -        });
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  |        // 在微信中运行的时候,微信没有开放自动加载资源的权限,所以要等播放之后才显示播放控制器
 | 
	
		
			
				|  |  |        player.on('loadedmetadata', () => {
 | 
	
		
			
				|  |  |          plyrState.loaded = true
 | 
	
	
		
			
				|  | @@ -221,112 +209,27 @@ export default defineComponent({
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      //点击改变播放状态
 | 
	
		
			
				|  |  |      function handlerClickPlay(){
 | 
	
		
			
				|  |  | -      if (state._plrl.playing) {
 | 
	
		
			
				|  |  | -        state._plrl.pause();
 | 
	
		
			
				|  |  | -      } else {
 | 
	
		
			
				|  |  | -        state._plrl.play();
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    /**
 | 
	
		
			
				|  |  | -     * 音频可视化
 | 
	
		
			
				|  |  | -     * @param audioDom
 | 
	
		
			
				|  |  | -     * @param canvasDom
 | 
	
		
			
				|  |  | -     * @param fftSize  2的幂数,最小为32
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    function audioVisualDraw(audioDom: HTMLAudioElement, canvasDom: HTMLCanvasElement, fftSize = 128) {
 | 
	
		
			
				|  |  | -      type propsType = { canvWidth: number; canvHeight: number; canvFillColor: string; lineColor: string; lineGap: number }
 | 
	
		
			
				|  |  | -      // canvas
 | 
	
		
			
				|  |  | -      const canvasCtx = canvasDom.getContext("2d")!
 | 
	
		
			
				|  |  | -      const { width, height } = canvasDom.getBoundingClientRect()
 | 
	
		
			
				|  |  | -      canvasDom.width = width
 | 
	
		
			
				|  |  | -      canvasDom.height = height
 | 
	
		
			
				|  |  | -      // audio
 | 
	
		
			
				|  |  | -      let audioCtx : AudioContext | null = null
 | 
	
		
			
				|  |  | -      let analyser : AnalyserNode | null = null
 | 
	
		
			
				|  |  | -      let source : MediaElementAudioSourceNode | null = null
 | 
	
		
			
				|  |  | -      const dataArray = new Uint8Array(fftSize / 2)
 | 
	
		
			
				|  |  | -      const draw = (data: Uint8Array, ctx: CanvasRenderingContext2D, { lineGap, canvWidth, canvHeight, canvFillColor, lineColor }: propsType) => {
 | 
	
		
			
				|  |  | -        if (!ctx) return
 | 
	
		
			
				|  |  | -        const w = canvWidth
 | 
	
		
			
				|  |  | -        const h = canvHeight
 | 
	
		
			
				|  |  | -        fillCanvasBackground(ctx, w, h, canvFillColor)
 | 
	
		
			
				|  |  | -          // 可视化
 | 
	
		
			
				|  |  | -        const dataLen = data.length
 | 
	
		
			
				|  |  | -        let step = (w / 2 - lineGap * dataLen) / dataLen
 | 
	
		
			
				|  |  | -        step < 1 && (step = 1)
 | 
	
		
			
				|  |  | -        const midX = w / 2
 | 
	
		
			
				|  |  | -        const midY = h / 2
 | 
	
		
			
				|  |  | -        let xLeft = midX
 | 
	
		
			
				|  |  | -        for (let i = 0; i < dataLen; i++) {
 | 
	
		
			
				|  |  | -          const value = data[i]
 | 
	
		
			
				|  |  | -          const percent = value / 255 // 最大值为255
 | 
	
		
			
				|  |  | -          const barHeight = percent * midY
 | 
	
		
			
				|  |  | -          canvasCtx.fillStyle = lineColor
 | 
	
		
			
				|  |  | -          // 中间加间隙
 | 
	
		
			
				|  |  | -          if (i === 0) {
 | 
	
		
			
				|  |  | -            xLeft -= lineGap / 2
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -          canvasCtx.fillRect(xLeft - step, midY - barHeight, step, barHeight)
 | 
	
		
			
				|  |  | -          canvasCtx.fillRect(xLeft - step, midY, step, barHeight)
 | 
	
		
			
				|  |  | -          xLeft -= step + lineGap
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        let xRight = midX
 | 
	
		
			
				|  |  | -        for (let i = 0; i < dataLen; i++) {
 | 
	
		
			
				|  |  | -          const value = data[i]
 | 
	
		
			
				|  |  | -          const percent = value / 255 // 最大值为255
 | 
	
		
			
				|  |  | -          const barHeight = percent * midY
 | 
	
		
			
				|  |  | -          canvasCtx.fillStyle = lineColor
 | 
	
		
			
				|  |  | -          if (i === 0) {
 | 
	
		
			
				|  |  | -            xRight += lineGap / 2
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -          canvasCtx.fillRect(xRight, midY - barHeight, step, barHeight)
 | 
	
		
			
				|  |  | -          canvasCtx.fillRect(xRight, midY, step, barHeight)
 | 
	
		
			
				|  |  | -          xRight += step + lineGap
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      const fillCanvasBackground = (ctx: CanvasRenderingContext2D, w: number, h: number, colors: string) => {
 | 
	
		
			
				|  |  | -        ctx.clearRect(0, 0, w, h)
 | 
	
		
			
				|  |  | -        ctx.fillStyle = colors
 | 
	
		
			
				|  |  | -        ctx.fillRect(0, 0, w, h)
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      const requestAnimationFrameFun = () => {
 | 
	
		
			
				|  |  | -        requestAnimationFrame(() => {
 | 
	
		
			
				|  |  | -          analyser?.getByteFrequencyData(dataArray)
 | 
	
		
			
				|  |  | -          draw(dataArray, canvasCtx, {
 | 
	
		
			
				|  |  | -            lineGap: 2,
 | 
	
		
			
				|  |  | -            canvWidth: width,
 | 
	
		
			
				|  |  | -            canvHeight: height,
 | 
	
		
			
				|  |  | -            canvFillColor: "transparent",
 | 
	
		
			
				|  |  | -            lineColor: "rgba(255, 255, 255, 0.7)"
 | 
	
		
			
				|  |  | -          })
 | 
	
		
			
				|  |  | -          if (!isPause) {
 | 
	
		
			
				|  |  | -            requestAnimationFrameFun()
 | 
	
		
			
				|  |  | -          }
 | 
	
		
			
				|  |  | -        })
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      let isPause = true
 | 
	
		
			
				|  |  | -      const playVisualDraw = () => {
 | 
	
		
			
				|  |  | -        if (!audioCtx) {
 | 
	
		
			
				|  |  | -          audioCtx = new AudioContext()
 | 
	
		
			
				|  |  | -          source = audioCtx.createMediaElementSource(audioDom)
 | 
	
		
			
				|  |  | -          analyser = audioCtx.createAnalyser()
 | 
	
		
			
				|  |  | -          analyser.fftSize = fftSize
 | 
	
		
			
				|  |  | -          source?.connect(analyser)
 | 
	
		
			
				|  |  | -          analyser.connect(audioCtx.destination)
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        //audioCtx.resume()  // 重新更新状态   加了暂停和恢复音频音质发生了变化  所以这里取消了
 | 
	
		
			
				|  |  | -        isPause = false
 | 
	
		
			
				|  |  | -        requestAnimationFrameFun()
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      const pauseVisualDraw = () => {
 | 
	
		
			
				|  |  | -        isPause = true
 | 
	
		
			
				|  |  | -        //audioCtx?.suspend()  // 暂停   加了暂停和恢复音频音质发生了变化  所以这里取消了
 | 
	
		
			
				|  |  | -        // source?.disconnect()
 | 
	
		
			
				|  |  | -        // analyser?.disconnect()
 | 
	
		
			
				|  |  | +      const player = state._plrl;
 | 
	
		
			
				|  |  | +      // 由于ios低版本必须在用户操作之后才能初始化 createMediaElementSource 所以必须在用户操作之后初始化
 | 
	
		
			
				|  |  | +      if(!isInitAudioVisualDraw && state.playType === "Audio"){
 | 
	
		
			
				|  |  | +        isInitAudioVisualDraw = true
 | 
	
		
			
				|  |  | +        // 创建音波数据
 | 
	
		
			
				|  |  | +        const audioDom = document.querySelector("#audioMediaSrc") as HTMLAudioElement
 | 
	
		
			
				|  |  | +        const canvasDom = document.querySelector("#audioVisualizer") as HTMLCanvasElement
 | 
	
		
			
				|  |  | +        const { pauseVisualDraw, playVisualDraw } = audioVisualDraw(audioDom, canvasDom)
 | 
	
		
			
				|  |  | +        player.on('play', () => {
 | 
	
		
			
				|  |  | +          lottieDom.value.play()
 | 
	
		
			
				|  |  | +          playVisualDraw()
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        player.on('pause', () => {
 | 
	
		
			
				|  |  | +          lottieDom.value.pause()
 | 
	
		
			
				|  |  | +          pauseVisualDraw()
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  | -      return {
 | 
	
		
			
				|  |  | -        playVisualDraw,
 | 
	
		
			
				|  |  | -        pauseVisualDraw
 | 
	
		
			
				|  |  | +      if (player.playing) {
 | 
	
		
			
				|  |  | +        player.pause();
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        player.play();
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      function handlerLandscapeScreen(event:any){
 | 
	
	
		
			
				|  | @@ -430,8 +333,8 @@ export default defineComponent({
 | 
	
		
			
				|  |  |      });
 | 
	
		
			
				|  |  |      // 初始化五线谱
 | 
	
		
			
				|  |  |      function initStaff(){
 | 
	
		
			
				|  |  | -      const src = `${vaildMusicScoreUrl()}/instrument/#/simple-detail?id=${state.musicDetail.musicSheetId}&musicRenderType=${staffState.musicRenderType}&part-index=${staffState.partIndex}`;
 | 
	
		
			
				|  |  | -      //const src = `https://dev.kt.colexiu.com/instrument/#/simple-detail?id=${state.musicDetail.musicSheetId}&musicRenderType=${staffState.musicRenderType}&part-index=${staffState.partIndex}`;
 | 
	
		
			
				|  |  | +      //const src = `${vaildMusicScoreUrl()}/instrument/#/simple-detail?id=${state.musicDetail.musicSheetId}&musicRenderType=${staffState.musicRenderType}&part-index=${staffState.partIndex}`;
 | 
	
		
			
				|  |  | +      const src = `https://dev.kt.colexiu.com/instrument/#/simple-detail?id=${state.musicDetail.musicSheetId}&musicRenderType=${staffState.musicRenderType}&part-index=${staffState.partIndex}`;
 | 
	
		
			
				|  |  |        staffState.staffSrc = src
 | 
	
		
			
				|  |  |        window.addEventListener('message', (event) => {
 | 
	
		
			
				|  |  |          const { api, height } = event.data;
 | 
	
	
		
			
				|  | @@ -518,6 +421,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |        state.playType = '';
 | 
	
		
			
				|  |  |        state.params.page = 1;
 | 
	
		
			
				|  |  |        state.list = [];
 | 
	
		
			
				|  |  | +      isInitAudioVisualDraw = false
 | 
	
		
			
				|  |  |        if(state._plrl){
 | 
	
		
			
				|  |  |          state._plrl.destroy()
 | 
	
		
			
				|  |  |        }
 |