利用Web Speech API快速实现语音识别
·
组织多国语言
var langs = [
['Afrikaans', ['af-ZA']],
['Bahasa Indonesia', ['id-ID']],
['Bahasa Melayu', ['ms-MY']],
['Català', ['ca-ES']],
['Čeština', ['cs-CZ']],
['Deutsch', ['de-DE']],
['English', ['en-AU', 'Australia'],
['en-CA', 'Canada'],
['en-IN', 'India'],
['en-NZ', 'New Zealand'],
['en-ZA', 'South Africa'],
['en-GB', 'United Kingdom'],
['en-US', 'United States']
],
['Español', ['es-AR', 'Argentina'],
['es-BO', 'Bolivia'],
['es-CL', 'Chile'],
['es-CO', 'Colombia'],
['es-CR', 'Costa Rica'],
['es-EC', 'Ecuador'],
['es-SV', 'El Salvador'],
['es-ES', 'España'],
['es-US', 'Estados Unidos'],
['es-GT', 'Guatemala'],
['es-HN', 'Honduras'],
['es-MX', 'México'],
['es-NI', 'Nicaragua'],
['es-PA', 'Panamá'],
['es-PY', 'Paraguay'],
['es-PE', 'Perú'],
['es-PR', 'Puerto Rico'],
['es-DO', 'República Dominicana'],
['es-UY', 'Uruguay'],
['es-VE', 'Venezuela']
],
['Euskara', ['eu-ES']],
['Français', ['fr-FR']],
['Galego', ['gl-ES']],
['Hrvatski', ['hr_HR']],
['IsiZulu', ['zu-ZA']],
['Íslenska', ['is-IS']],
['Italiano', ['it-IT', 'Italia'],
['it-CH', 'Svizzera']
],
['Magyar', ['hu-HU']],
['Nederlands', ['nl-NL']],
['Norsk bokmål', ['nb-NO']],
['Polski', ['pl-PL']],
['Português', ['pt-BR', 'Brasil'],
['pt-PT', 'Portugal']
],
['Română', ['ro-RO']],
['Slovenčina', ['sk-SK']],
['Suomi', ['fi-FI']],
['Svenska', ['sv-SE']],
['Türkçe', ['tr-TR']],
['български', ['bg-BG']],
['Pусский', ['ru-RU']],
['Српски', ['sr-RS']],
['한국어', ['ko-KR']],
['中文', ['cmn-Hans-CN', '普通话 (中国大陆)'],
['cmn-Hans-HK', '普通话 (香港)'],
['cmn-Hant-TW', '中文 (台灣)'],
['yue-Hant-HK', '粵語 (香港)']
],
['日本語', ['ja-JP']],
['Lingua latīna', ['la']]
];
上代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<title>语音功能</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<div id="app">
<el-button type="success" @click='startRecognition'>开始识别</el-button>
<el-button type="success" @click='stopRecognition'>结束识别</el-button>
<el-button type="success" @click='clearTable'>清空列表</el-button>
<el-button type="success" @click='showDialog'>开始发言</el-button>
<el-cascader v-model='langSource' :options="options" :show-all-levels="false"></el-cascader>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="message" label="语音内容" width="180">
</el-table-column>
</el-table>
<el-dialog title="发言" :visible.sync="centerDialogVisible" width="50%" center>
<div style="padding-left: 20px;padding-right: 20px;">
<div class="block">
<span>输入发言内容</span>
<el-input style='margin-top: 10px;margin-bottom: 10px;' v-model="input" placeholder="请输入内容"></el-input>
</div>
<div>
<span>Rate</span>
<el-slider v-model="rate" :format-tooltip="formatRate"></el-slider>
</div>
<div>
<span>Pitch</span>
<el-slider v-model="pitch" :format-tooltip="formatPitch"></el-slider>
</div>
<div style='margin-top: 20px;margin-bottom: 10px;'>
<span style='margin-bottom: 10px;'>选择声音</span>
<el-select style='width: 400px;' v-model='voice' placeholder="请选择">
<el-option v-for="item in voices" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="centerDialogVisible = false">关 闭</el-button>
<el-button type="primary" @click="speak">发 言</el-button>
</span>
</el-dialog>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
input: 'Hello Vue!',
newRecognition: {},
langSource: 'cmn-Hans-CN',
rate: 50,
pitch: 50,
voice: '',
voices: [],
options: [{
value: 'en',
label: 'English',
children: [{
value: 'en-AU',
label: 'Australia'
}, {
value: 'en-CA',
label: 'Canada'
}, {
value: 'en-IN',
label: 'India'
}, {
value: 'en-NZ',
label: 'New Zealand'
}, {
value: 'en-ZA',
label: 'South Africa'
}, {
value: 'en-GB',
label: 'United Kingdom'
}, {
value: 'en-US',
label: 'United States'
}]
}, {
value: 'ko-KR',
label: '한국어'
}, {
value: 'zh-cn',
label: '中文',
children: [{
value: 'cmn-Hans-CN',
label: '普通话 (中国大陆)'
}, {
value: 'cmn-Hans-HK',
label: '普通话 (香港)'
}, {
value: 'cmn-Hant-TW',
label: '中文 (台灣)'
}, {
value: 'yue-Hant-HK',
label: '粵語 (香港)'
}]
}, {
value: 'ja-JP',
label: '日本語'
}],
tableData: [],
centerDialogVisible: false,
synth: {},
voiceData: []
},
watch: {
langSource(val){
this.newRecognition.lang = val;
this.newRecognition.stop();
}
},
created() {
this.newRecognition = new webkitSpeechRecognition();
this.newRecognition.continuous = true;
this.newRecognition.onresult = this.printResults;
this.newRecognition.lang = this.langSource;
this.newRecognition.onsoundstart = function(e) {
console.log("开始收听了");
console.log(e);
};
this.newRecognition.onspeechstart = (e) => {
console.log("开始讲话了");
console.log(e);
};
this.newRecognition.onspeechend = (e) => {
console.log("讲话完毕");
console.log(e);
};
this.newRecognition.onerror = (e) => {
console.log("发生异常");
console.log(e);
};
this.synth = window.speechSynthesis;
this.synth.onvoiceschanged = this.populateVoiceList;
},
methods: {
populateVoiceList: function() {
this.voiceData = this.synth.getVoices().sort(function(a, b) {
const aname = a.name.toUpperCase(),
bname = b.name.toUpperCase();
if (aname < bname) return -1;
else if (aname == bname) return 0;
else return +1;
});
this.voice = this.voiceData[0].lang;
for (i = 0; i < this.voiceData.length; i++) {
this.voices.push({
value: this.voiceData[i].lang,
label: this.voiceData[i].name
});
}
},
speak: function() {
if (this.synth.speaking) {
console.error('speechSynthesis.speaking');
return;
}
if (this.input !== '') {
var utterThis = new SpeechSynthesisUtterance(this.input);
utterThis.onend = function(event) {
console.log('SpeechSynthesisUtterance.onend');
}
utterThis.onerror = function(event) {
console.error('SpeechSynthesisUtterance.onerror');
}
for (i = 0; i < this.voiceData.length; i++) {
if (this.voiceData[i].lang === this.voice) {
utterThis.voice = this.voiceData[i];
break;
}
}
utterThis.pitch = this.formatRate(this.rate);
utterThis.rate = this.formatPitch(this.pitch);
this.synth.speak(utterThis);
}
},
formatRate(val) {
return (val * 1.5 / 100 + 0.5).toFixed(1);
},
formatPitch(val) {
return (val * 2 / 100).toFixed(1);
},
clearTable() {
this.tableData = [];
},
showDialog() {
this.centerDialogVisible = true;
},
startRecognition: function() {
this.newRecognition.start();
},
stopRecognition: function() {
this.newRecognition.stop();
},
printResults: function(event) {
let rst = [];
for (let i = 0; i < event.results.length; i++) {
rst.push({
message: event.results[i][0].transcript
})
}
this.tableData = rst;
}
}
})
</script>
</body>
</html>
更多推荐


所有评论(0)