最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Vue實(shí)現(xiàn)文字轉(zhuǎn)語(yǔ)音播放功能的示例代碼

 更新時(shí)間:2025年12月04日 08:18:20   作者:IT界Tony哥  
這篇文章主要為大家詳細(xì)介紹了如何基于Vue實(shí)現(xiàn)文字轉(zhuǎn)語(yǔ)音播放應(yīng)用,具有美觀的界面和完整的交互功能,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

我將為您創(chuàng)建一個(gè)完整的Vue文字轉(zhuǎn)語(yǔ)音播放應(yīng)用,具有美觀的界面和完整的交互功能。

設(shè)計(jì)思路

  • 使用Web Speech API的SpeechSynthesis功能
  • 創(chuàng)建直觀的控制界面,包含播放/暫停、停止、語(yǔ)速和音調(diào)調(diào)節(jié)
  • 添加語(yǔ)音選擇功能
  • 設(shè)計(jì)響應(yīng)式布局,適配不同設(shè)備

實(shí)現(xiàn)代碼

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue文字轉(zhuǎn)語(yǔ)音播放器</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <link rel="stylesheet"  rel="external nofollow" >
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        body {
            background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }
        
        .container {
            width: 100%;
            max-width: 800px;
            background-color: rgba(255, 255, 255, 0.95);
            border-radius: 20px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
            overflow: hidden;
        }
        
        .header {
            background: linear-gradient(to right, #4a00e0, #8e2de2);
            color: white;
            padding: 25px;
            text-align: center;
        }
        
        .header h1 {
            font-size: 2.2rem;
            margin-bottom: 10px;
        }
        
        .header p {
            opacity: 0.9;
            font-size: 1.1rem;
        }
        
        .content {
            padding: 30px;
        }
        
        .text-input {
            margin-bottom: 25px;
        }
        
        .text-input label {
            display: block;
            margin-bottom: 10px;
            font-weight: 600;
            color: #333;
            font-size: 1.1rem;
        }
        
        textarea {
            width: 100%;
            min-height: 150px;
            padding: 15px;
            border: 2px solid #e0e0e0;
            border-radius: 10px;
            font-size: 1rem;
            resize: vertical;
            transition: border 0.3s;
        }
        
        textarea:focus {
            outline: none;
            border-color: #6a11cb;
        }
        
        .controls {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin-bottom: 25px;
        }
        
        .control-group {
            flex: 1;
            min-width: 200px;
        }
        
        .control-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #333;
        }
        
        .slider-container {
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        input[type="range"] {
            flex: 1;
            height: 8px;
            -webkit-appearance: none;
            background: #e0e0e0;
            border-radius: 5px;
            outline: none;
        }
        
        input[type="range"]::-webkit-slider-thumb {
            -webkit-appearance: none;
            width: 20px;
            height: 20px;
            background: #6a11cb;
            border-radius: 50%;
            cursor: pointer;
        }
        
        .value-display {
            min-width: 40px;
            text-align: center;
            font-weight: 600;
            color: #6a11cb;
        }
        
        .voice-selector {
            margin-bottom: 25px;
        }
        
        .voice-selector label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #333;
        }
        
        select {
            width: 100%;
            padding: 12px 15px;
            border: 2px solid #e0e0e0;
            border-radius: 10px;
            font-size: 1rem;
            background-color: white;
            cursor: pointer;
        }
        
        .buttons {
            display: flex;
            justify-content: center;
            gap: 15px;
            flex-wrap: wrap;
        }
        
        button {
            padding: 12px 25px;
            border: none;
            border-radius: 50px;
            font-size: 1rem;
            font-weight: 600;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 8px;
            transition: all 0.3s;
        }
        
        .play-btn {
            background: linear-gradient(to right, #00b09b, #96c93d);
            color: white;
            padding: 12px 30px;
        }
        
        .pause-btn {
            background: linear-gradient(to right, #f46b45, #eea849);
            color: white;
        }
        
        .stop-btn {
            background: linear-gradient(to right, #ff416c, #ff4b2b);
            color: white;
        }
        
        button:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
        }
        
        button:active {
            transform: translateY(0);
        }
        
        button:disabled {
            background: #cccccc;
            cursor: not-allowed;
            transform: none;
            box-shadow: none;
        }
        
        .status {
            text-align: center;
            margin-top: 20px;
            padding: 15px;
            border-radius: 10px;
            font-weight: 600;
        }
        
        .status.ready {
            background-color: #e8f5e9;
            color: #2e7d32;
        }
        
        .status.speaking {
            background-color: #e3f2fd;
            color: #1565c0;
        }
        
        .status.paused {
            background-color: #fff3e0;
            color: #ef6c00;
        }
        
        .footer {
            text-align: center;
            padding: 20px;
            color: #777;
            font-size: 0.9rem;
            border-top: 1px solid #eee;
        }
        
        @media (max-width: 600px) {
            .header h1 {
                font-size: 1.8rem;
            }
            
            .content {
                padding: 20px;
            }
            
            button {
                padding: 10px 20px;
                font-size: 0.9rem;
            }
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="container">
            <div class="header">
                <h1><i class="fas fa-volume-up"></i> 文字轉(zhuǎn)語(yǔ)音播放器</h1>
                <p>輸入文字,選擇語(yǔ)音,然后播放</p>
            </div>
            
            <div class="content">
                <div class="text-input">
                    <label for="text-to-speak"><i class="fas fa-font"></i> 輸入要轉(zhuǎn)換的文字:</label>
                    <textarea 
                        id="text-to-speak" 
                        v-model="text" 
                        placeholder="在這里輸入您想要轉(zhuǎn)換為語(yǔ)音的文字..."
                    ></textarea>
                </div>
                
                <div class="controls">
                    <div class="control-group">
                        <label for="rate"><i class="fas fa-tachometer-alt"></i> 語(yǔ)速:</label>
                        <div class="slider-container">
                            <input 
                                type="range" 
                                id="rate" 
                                min="0.5" 
                                max="2" 
                                step="0.1" 
                                v-model="rate"
                            >
                            <span class="value-display">{{ rate }}x</span>
                        </div>
                    </div>
                    
                    <div class="control-group">
                        <label for="pitch"><i class="fas fa-waveform"></i> 音調(diào):</label>
                        <div class="slider-container">
                            <input 
                                type="range" 
                                id="pitch" 
                                min="0.5" 
                                max="2" 
                                step="0.1" 
                                v-model="pitch"
                            >
                            <span class="value-display">{{ pitch }}</span>
                        </div>
                    </div>
                </div>
                
                <div class="voice-selector">
                    <label for="voice-select"><i class="fas fa-microphone"></i> 選擇語(yǔ)音:</label>
                    <select id="voice-select" v-model="selectedVoice">
                        <option v-for="voice in voices" :value="voice.name">
                            {{ voice.name }} ({{ voice.lang }})
                        </option>
                    </select>
                </div>
                
                <div class="buttons">
                    <button class="play-btn" @click="speak" :disabled="isSpeaking || !text">
                        <i class="fas fa-play"></i> {{ isPaused ? '繼續(xù)' : '播放' }}
                    </button>
                    <button class="pause-btn" @click="pause" :disabled="!isSpeaking || isPaused">
                        <i class="fas fa-pause"></i> 暫停
                    </button>
                    <button class="stop-btn" @click="stop" :disabled="!isSpeaking && !isPaused">
                        <i class="fas fa-stop"></i> 停止
                    </button>
                </div>
                
                <div class="status" :class="statusClass">
                    <i :class="statusIcon"></i> {{ statusText }}
                </div>
            </div>
            
            <div class="footer">
                <p>使用Web Speech API實(shí)現(xiàn) | Vue 3文字轉(zhuǎn)語(yǔ)音應(yīng)用</p>
            </div>
        </div>
    </div>

    <script>
        const { createApp, ref, onMounted, computed, watch } = Vue;
        
        createApp({
            setup() {
                const text = ref('歡迎使用Vue文字轉(zhuǎn)語(yǔ)音播放器!這是一個(gè)演示應(yīng)用,您可以輸入任何文字并轉(zhuǎn)換為語(yǔ)音播放。');
                const rate = ref(1);
                const pitch = ref(1);
                const voices = ref([]);
                const selectedVoice = ref('');
                const isSpeaking = ref(false);
                const isPaused = ref(false);
                const synth = window.speechSynthesis;
                
                // 計(jì)算狀態(tài)顯示
                const statusText = computed(() => {
                    if (isSpeaking.value && !isPaused.value) return '正在播放語(yǔ)音...';
                    if (isPaused.value) return '語(yǔ)音已暫停';
                    if (!text.value) return '請(qǐng)輸入要轉(zhuǎn)換的文字';
                    return '準(zhǔn)備就緒,點(diǎn)擊播放按鈕開(kāi)始';
                });
                
                const statusClass = computed(() => {
                    if (isSpeaking.value && !isPaused.value) return 'speaking';
                    if (isPaused.value) return 'paused';
                    return 'ready';
                });
                
                const statusIcon = computed(() => {
                    if (isSpeaking.value && !isPaused.value) return 'fas fa-play-circle';
                    if (isPaused.value) return 'fas fa-pause-circle';
                    return 'fas fa-check-circle';
                });
                
                // 獲取可用的語(yǔ)音列表
                const loadVoices = () => {
                    const availableVoices = synth.getVoices();
                    voices.value = availableVoices;
                    
                    // 默認(rèn)選擇中文語(yǔ)音
                    if (availableVoices.length > 0) {
                        const chineseVoice = availableVoices.find(voice => 
                            voice.lang.includes('zh') || voice.lang.includes('CN')
                        );
                        selectedVoice.value = chineseVoice ? chineseVoice.name : availableVoices[0].name;
                    }
                };
                
                // 初始化語(yǔ)音
                onMounted(() => {
                    // 某些瀏覽器需要延遲加載語(yǔ)音列表
                    if (synth.onvoiceschanged !== undefined) {
                        synth.onvoiceschanged = loadVoices;
                    }
                    loadVoices();
                });
                
                // 播放語(yǔ)音
                const speak = () => {
                    if (isPaused.value) {
                        // 如果已暫停,恢復(fù)播放
                        synth.resume();
                        isPaused.value = false;
                        return;
                    }
                    
                    if (isSpeaking.value) {
                        // 如果正在播放,先停止
                        synth.cancel();
                    }
                    
                    if (!text.value) return;
                    
                    const utterance = new SpeechSynthesisUtterance(text.value);
                    utterance.rate = rate.value;
                    utterance.pitch = pitch.value;
                    
                    // 設(shè)置選定的語(yǔ)音
                    const voice = voices.value.find(v => v.name === selectedVoice.value);
                    if (voice) {
                        utterance.voice = voice;
                    }
                    
                    utterance.onstart = () => {
                        isSpeaking.value = true;
                        isPaused.value = false;
                    };
                    
                    utterance.onend = () => {
                        isSpeaking.value = false;
                        isPaused.value = false;
                    };
                    
                    utterance.onerror = () => {
                        isSpeaking.value = false;
                        isPaused.value = false;
                    };
                    
                    synth.speak(utterance);
                };
                
                // 暫停語(yǔ)音
                const pause = () => {
                    if (isSpeaking.value && !isPaused.value) {
                        synth.pause();
                        isPaused.value = true;
                    }
                };
                
                // 停止語(yǔ)音
                const stop = () => {
                    synth.cancel();
                    isSpeaking.value = false;
                    isPaused.value = false;
                };
                
                return {
                    text,
                    rate,
                    pitch,
                    voices,
                    selectedVoice,
                    isSpeaking,
                    isPaused,
                    statusText,
                    statusClass,
                    statusIcon,
                    speak,
                    pause,
                    stop
                };
            }
        }).mount('#app');
    </script>
</body>
</html>

功能說(shuō)明

這個(gè)Vue文字轉(zhuǎn)語(yǔ)音應(yīng)用具有以下功能:

1.文本輸入:用戶可以輸入或粘貼需要轉(zhuǎn)換為語(yǔ)音的文字

2.語(yǔ)音調(diào)節(jié)

  • 語(yǔ)速控制(0.5x - 2x)
  • 音調(diào)控制(0.5 - 2)

3.語(yǔ)音選擇:從瀏覽器支持的語(yǔ)音列表中選擇喜歡的語(yǔ)音

4.播放控制:播放/暫停/停止功能

5.狀態(tài)顯示:實(shí)時(shí)顯示當(dāng)前播放狀態(tài)

6.響應(yīng)式設(shè)計(jì):適配各種屏幕尺寸

使用說(shuō)明

  • 在文本框中輸入或粘貼您想要轉(zhuǎn)換為語(yǔ)音的文字
  • 根據(jù)需要調(diào)整語(yǔ)速和音調(diào)
  • 從下拉菜單中選擇喜歡的語(yǔ)音(支持中文)
  • 點(diǎn)擊播放按鈕開(kāi)始語(yǔ)音轉(zhuǎn)換
  • 使用暫停和停止按鈕控制播放過(guò)程

這個(gè)應(yīng)用使用了現(xiàn)代瀏覽器的Web Speech API,在Chrome、Edge等主流瀏覽器中都能良好運(yùn)行。

到此這篇關(guān)于基于Vue實(shí)現(xiàn)文字轉(zhuǎn)語(yǔ)音播放功能的示例代碼的文章就介紹到這了,更多相關(guān)Vue文字轉(zhuǎn)語(yǔ)音播放內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue自定義指令拖拽功能示例

    Vue自定義指令拖拽功能示例

    本文給大家分享vue自定義指令拖拽功能及自定義鍵盤(pán)信息,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下
    2017-02-02
  • vue使用drag與drop實(shí)現(xiàn)拖拽的示例代碼

    vue使用drag與drop實(shí)現(xiàn)拖拽的示例代碼

    本篇文章主要介紹了vue使用drag與drop實(shí)現(xiàn)拖拽的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • Vue使用zTree插件封裝樹(shù)組件操作示例

    Vue使用zTree插件封裝樹(shù)組件操作示例

    這篇文章主要介紹了Vue使用zTree插件封裝樹(shù)組件操作,結(jié)合實(shí)例形式分析了vue.js整合zTree插件實(shí)現(xiàn)樹(shù)組件與使用相關(guān)操作技巧,需要的朋友可以參考下
    2019-04-04
  • vuex中g(shù)etters的基本用法解讀

    vuex中g(shù)etters的基本用法解讀

    這篇文章主要介紹了vuex中g(shù)etters的基本用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Vue3使用Swiper實(shí)現(xiàn)輪播圖示例詳解

    Vue3使用Swiper實(shí)現(xiàn)輪播圖示例詳解

    這篇文章主要為大家介紹了Vue3使用Swiper實(shí)現(xiàn)輪播圖示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • vue如何動(dòng)態(tài)配置ip與端口

    vue如何動(dòng)態(tài)配置ip與端口

    這篇文章主要介紹了vue如何動(dòng)態(tài)配置ip與端口,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Vue3實(shí)現(xiàn)通過(guò)axios來(lái)讀取本地json文件

    Vue3實(shí)現(xiàn)通過(guò)axios來(lái)讀取本地json文件

    這篇文章主要介紹了Vue3實(shí)現(xiàn)通過(guò)axios來(lái)讀取本地json文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • uniapp仿微信聊天界面效果實(shí)例(vue3組合式版本)

    uniapp仿微信聊天界面效果實(shí)例(vue3組合式版本)

    這篇文章主要介紹了uniapp仿微信聊天界面的相關(guān)資料,這里提及了一個(gè)時(shí)間工具包timeMethod.js,該工具包可能提供了一系列時(shí)間處理的功能,如格式化日期、計(jì)算時(shí)間差等,以便在消息格式中正確展示時(shí)間信息,使用此類(lèi)工具包可以大大提高開(kāi)發(fā)效率,需要的朋友可以參考下
    2024-10-10
  • Vue實(shí)現(xiàn)計(jì)數(shù)器案例

    Vue實(shí)現(xiàn)計(jì)數(shù)器案例

    這篇文章主要為大家詳細(xì)介紹了Vue計(jì)數(shù)器案例的實(shí)現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • vue導(dǎo)出excel的兩種實(shí)現(xiàn)方式代碼

    vue導(dǎo)出excel的兩種實(shí)現(xiàn)方式代碼

    這篇文章主要給大家介紹了關(guān)于vue導(dǎo)出excel的兩種實(shí)現(xiàn)方式,在項(xiàng)目中我們可能會(huì)碰到導(dǎo)出Excel文件的需求,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-08-08

最新評(píng)論

南阳市| 新绛县| 榆林市| 平塘县| 永仁县| 罗平县| 叶城县| 雷波县| 开化县| 泊头市| 汝州市| 志丹县| 宜丰县| 台北市| 卓资县| 高安市| 大邑县| 临汾市| 老河口市| 陇西县| 宁海县| 甘谷县| 林口县| 崇州市| 隆回县| 平度市| 萍乡市| 崇左市| 威海市| 岳阳县| 慈溪市| 民和| 江源县| 临沭县| 铁力市| 罗城| 陵川县| 石门县| 滨海县| 石泉县| 湖南省|