这里以vue为例啦
第一次外挂字幕需求,mark一下~
一、主要函数,将文本转化为易用的数组
1、获取srt内容(本次srt是get获取的)

	async getSrt(url,index){
      let srtText = await fileApi.getStr(url)
      if(srtText.success){
        let srtItem = this.createSrtArr(srtText.data)
        //对应的多种语言的srt字幕的map,序号为key,值为转化的srt字幕分时数组
        this.srtMap[index] = srtItem
      }
    }

2、将字符串转化为方便使用的数组

	createSrtArr(srt){
      let arr = srt.split(/\n\n|\r\r|\r\n\r\n/)
      let result = []
      arr.forEach(item => {
        let srtObj = {}
        let containArr = item.split(/\n/)

        if(containArr[1]){
          //此处正则用于取出00:00:00,213 --> 00:00:00,213这种结构,防止可能存在于此行的x,y坐标对后续处理造成影响
          var reg = /^(\d{2}):(\d{2}):(\d{2})[\.,](\d{1,3}) --\> (\d{2}):(\d{2}):(\d{2})[\.,](\d{1,3})/g
          let regResult = reg.exec(containArr[1])
          if(regResult){
            let timeSplit = regResult[0].split(' --> ')
            srtObj.from = this.getSeconds(timeSplit[0])
            srtObj.to = this.getSeconds(timeSplit[1])
            //这里的两个replace主要是将srt中可能携带的font标签转化为易用的span,当时遇到了如果是font标签的话没办法继承父元素的字体大小的问题,题外话:本次字母字体大小采用了媒体查询进行设置
            srtObj.htmlText = containArr.slice(2).join(`<br/>`).replace(/\<font/g,'<span').replace(/\<\/font/g,'</span')
            result.push(srtObj)
          }
        }
      })
      return result
    },
	//将srt中的字符串时间转化为所需要的格式,这里转化成了秒数
    getSeconds(val){
      let arr = val.split(/\,|\./)
      let sec = 0
      let a = arr[0].split(':')
      sec = Number(a[0])*60*60+Number(a[1])*60+Number(a[2])+arr[1]/1000
      return sec
    }

二、监听当前播放的时间,二分法找到对应的进行显示
1、watch

watch:{
  currentTime(){
 	 //根据字幕切换选择所需要的字幕数组
     let arr = this.srtMap[this.subtitleIndex]
     //赋值给subtitleText,此值用v-html进行了绑定,绑定到了对应的字幕显示区域
     this.subtitleText = this.getSubtitle(this.currentTime,arr)
   }
 },

2、二分查找

	getSubtitle(currentTime,arr){
      let low = 0,high = arr.length
      let mid,htmlText
      while(low <= high){
        mid = parseInt((low+high)/2)
        if(arr[mid].from <= currentTime && arr[mid].to >= currentTime){
          htmlText = arr[mid].htmlText
          break
        }
        if(arr[mid].from > currentTime){
          high = mid - 1
        }
        if(arr[mid].to < currentTime){
          low = mid + 1
        }
      }
      return htmlText
    }

这里查找时间对应的字幕感觉二分查找,是否能够继续优化,如果有更好的策略,欢迎指导~

Logo

前往低代码交流专区

更多推荐