147 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <div class="AiTransSpeech" v-if="!noSpeech">
 | |
|     <button title="语音播报" @click="getSpeech">
 | |
|       <div>
 | |
|         <div class="iconfont" :class="{playing:loading}"></div>
 | |
|       </div>
 | |
|       <div>{{ text }}</div>
 | |
|     </button>
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| export default {
 | |
|   name: "AiTransSpeech",
 | |
|   props: {
 | |
|     src: String,
 | |
|     content: String
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       audioContext: null,
 | |
|       speech: "",
 | |
|       loading: false,
 | |
|       text: "开始"
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     speechString() {
 | |
|       return this.content ? this.content.replace(/<\/?.+?\/?>/g, "") : ""
 | |
|     },
 | |
|     noSpeech() {
 | |
|       return !this.src && !this.content
 | |
|     }
 | |
|   },
 | |
|   methods: {
 | |
|     getSpeech() {
 | |
|       if (!this.noSpeech) {
 | |
|         if (this.audioContext) {
 | |
|           if (this.loading) {
 | |
|             this.loading = false
 | |
|             this.audioContext.pause()
 | |
|           } else {
 | |
|             this.loading = true
 | |
|             this.audioContext.play()
 | |
|           }
 | |
|         } else if (this.content) {
 | |
|           this.loading = true
 | |
|           if (!this.speech) {
 | |
|             this.$instance.post("/app/msc/transToSpeech" + `?fileName=demo&words=${this.speechString}`).then(res => {
 | |
|               if (res && res.data) {
 | |
|                 let url = res.data.join("")
 | |
|                 this.speech = url.substring(0, url.indexOf(";"))
 | |
|                 this.playAudio()
 | |
|               }
 | |
|             }).catch(() => this.loading = false)
 | |
|           } else {
 | |
|             this.playAudio()
 | |
|           }
 | |
|         } else if (this.src) {
 | |
|           this.loading = true
 | |
|           this.speech = this.src
 | |
|           this.playAudio()
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     playAudio() {
 | |
|       let _ = this
 | |
|       this.audioContext = uni.createInnerAudioContext();
 | |
|       this.audioContext.src = this.speech;
 | |
|       this.audioContext.play()
 | |
|       this.audioContext.onPlay(() => {
 | |
|         _.text = "暂停"
 | |
|       });
 | |
|       this.audioContext.onPause(() => {
 | |
|         _.loading = false
 | |
|         _.text = "开始"
 | |
|       });
 | |
|       this.audioContext.onEnded(() => {
 | |
|         _.loading = false
 | |
|         _.text = "开始"
 | |
|       });
 | |
|       this.audioContext.onError((res) => {
 | |
|         console.error(res.errMsg);
 | |
|         _.text = "开始"
 | |
|       });
 | |
|     },
 | |
|   },
 | |
|   destroyed() {
 | |
|     if (this.audioContext) {
 | |
|       this.audioContext.pause()
 | |
|       this.audioContext.destroy()
 | |
|     }
 | |
|   }
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
| .AiTransSpeech {
 | |
|   display: flex;
 | |
|   align-items: center;
 | |
|   justify-content: center;
 | |
| 
 | |
|   button {
 | |
|     position: fixed;
 | |
|     right: 80px;
 | |
|     bottom: 150px;
 | |
|     width: 104px;
 | |
|     height: 104px;
 | |
|     background: linear-gradient(130deg, rgba(70, 192, 253, 1) 0%, rgba(37, 158, 249, 1) 57%, rgba(39, 148, 248, 1) 100%);
 | |
|     border-radius: 50%;
 | |
|     font-size: 24px;
 | |
|     display: flex;
 | |
|     flex-direction: column;
 | |
|     align-items: center;
 | |
|     justify-content: center;
 | |
|     color: #fff !important;
 | |
|     z-index: 10000;
 | |
| 
 | |
|     & > div {
 | |
|       width: 48px;
 | |
|       white-space: nowrap;
 | |
|       line-height: normal;
 | |
| 
 | |
|       .iconfont {
 | |
|         width: 48px;
 | |
|         font-size: 48px;
 | |
|         line-height: 48px;
 | |
|         overflow: hidden;
 | |
| 
 | |
|         &.playing {
 | |
|           animation: playingSpeech .5s infinite;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   @keyframes playingSpeech {
 | |
|     from {
 | |
|       width: 30px
 | |
|     }
 | |
|     to {
 | |
|       width: 100%
 | |
|     }
 | |
|   }
 | |
| }
 | |
| </style>
 |