返回

Flask实现Web应用(三)

这篇博文应该是这个应用的最后一个部分,主要是实现调用本地麦克风录音的前后端。

前端页面的实现

在这个页面中,需要实现录音功能,而录音功能在参考了网上的相关资料之后,决定采用recorder.js的现行库(因为如果要造轮子的话需要自己去了解语音采样等过程),这是库的链接

对于我这种前端小白本来是没看懂要怎么使用的,后来才发现在其项目目录下有dist/recorder.js文件,如果你使用是Flask框架只需要在static文件夹中导入recorder.js以及recorder.js.map两个文件并采用如下方法引入

<script type="text/javascript" src="{{ url_for('static', filename='recorder.js') }}"></script>

通过recorder我决定设置录音相关的六个按钮分别是开始、暂停、继续、结束、上传、播放。于是就有了以下的HTML代码

<body style="background-size: 100%; background-image:url({{ url_for('static', filename='cool-2.png') }})">
    <div id="items">
        <div>
            <p>麦克风录制</p>
            <input type="button" value="开始录制" id="record_btn" class="item_btn_left">
            <input type="button" value="暂停录制" id="stop_btn" class="item_btn_left">
            <input type="button" value="继续录制" id="resume_btn" class="item_btn">
            <br>
            <input type="button" value="结束录制" id="end_btn" class="item_btn_left">
            <input type="button" value="播放录音" id="play_btn" class="item_btn_left">
            <input type="button" value="上传录音" id="submit_btn" class="item_btn">
        </div>
        <div>
            <p>识别文本</p>
            <input type="text" id="res_text" disabled="disabled">
            <input type="button" value="返回主页" onclick="back()" id="back_btn">
        </div>
    </div>
</body>

前端CSS样式

没有什么CSS基础又想让界面好看一点的我,在这个页面的按钮样式上参考了其他大佬的所写的CSS代码样式,并修改了其大小和变化时间长短,所以这里并没有太多可以讲述的东西。直接附上相关链接以及我修改后的CSS代码

.item_btn {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 50px;
    width: 100px;
}
.item_btn_left {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 50px;
    width: 100px;
    float: left;
    margin-right: 55px;
}
#back_btn {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 50px;
    width: 100px;
    left: 75%;
    margin-top: 100px;
}
#back_btn, .item_btn, .item_btn_left {
    border: 0;
    border-radius: 10px;
    background: #2ec4b6;
    text-transform: uppercase;
    color: white;
    font-size: 16px;
    font-weight: bold;
    padding: 15px 30px;
    outline: none;
    position: relative;
    transition: border-radius 1.5s;
    -webkit-transition: border-radius 1.5s;
}
#back_btn:hover, .item_btn:hover, .item_btn_left:hover {
    border-bottom-right-radius: 50px;
    border-top-left-radius: 50px;
    border-bottom-left-radius: 10px;
    border-top-right-radius: 10px;
}

通过以上的CSS可以实现如下的鼠标悬停效果

按钮悬停效果
按钮悬停效果

前端功能实现

实现基础的录音功能

参阅recorder.jsAPI可以发现这个库提供基础的录音功能,且实现较为简单。以下为使用API的jQuery代码,用来实现相关的功能。这里需要注意的是当使用了jQuery中的on函数来绑定相关的事件时,就不需要在HTML元素中使用属性onclick来绑定相关函数了,这个问题一度折磨了我许久,最后还是感谢好友的修改。

<script>
	window.onload = function() {
    let recorder;
    $("#record_btn").on('click', function (e) {
        console.log("开始录制");
        recorder = new Recorder({
            sampleBits: 16,
            sampleRate: 16000,
            numChannels: 1
        });
        recorder.start().then(
        () => {// 开始录音
        },
        (error) => {// 出错了
            console.log(`${error.name} : ${error.message}`);
        });
    });
    $("#stop_btn").on('click', function () {
        console.log("暂停录制");
        recorder.pause();
    });
    $("#resume_btn").on('click', function () {
        console.log("继续录制");
        recorder.resume();
    });
    $("#end_btn").on('click', function () {
        console.log("结束录制");
        recorder.stop();
    });
    $("#play_btn").on('click', function () {
        console.log("播放");
        recorder.play();
    });
</script>

实现录音上传的功能

要实现录音上传首先我们要先获取录音文件,recorder.js库提供了相应的API(getWAVBlob)得到录音文件的.wav形式的文件。

要上传这个文件就需要通过AJAX技术来上传,此时需要创建一个FormData来提交这个文件,通过append函数来接收这个文件,并将其命名为audio.wav。最后创建一个AJAX对象来上传这个文件。

在这个AJAX对象中,我们需要将提交方法设置为POST,并指定一个url来作为提交的目的。在这里有一个参数processData默认值为true,表示在上传文件时,jQuery会对数据进行序列化处理,在使用true为参数值时,产生了提交文件的错误,所以这里建议将参数设置为false

最后通过recorder.js的API将录音文件删除,以便下一次调用。JS代码如下

$("#submit_btn").on('click', function () {
	let wav_blob = recorder.getWAVBlob();
	let formData = new FormData();
	formData.append('file', wav_blob, 'audio.wav');  {# 添加文件到表单中 #}
    	$.ajax({
            type: "POST",
            url: "/micro_upload",   
            data: formData,
            cache: false,
            processData: false,
            contentType: false,
            success: function (data) {
            	if (data.msg === 'success') {
                	recorder.destroy().then(function () {
                    	recorder = null;
                    });
                }
                else {
                	console.log(data.msg);
                    recorder.destroy().then(function () {
                    	recorder = null;
                    });
                }
            }
      })
 })

后端接收

在后端接收中,我们需要将上述对应的url利用装饰器映射到相应的接收函数中,在这个函数中可以参考之前的接收文件函数,提交的文件将保存在Flask中的request.file中。

利用secure_filename函数对文件名进行保留,最后保存至相应的工程目录中。相关代码如下

@app.route('/micro_upload', methods=['post'])
def micro_upload():
    audio_input = request.files['file']
    filename = secure_filename(audio_input.filename)
    audio_input.save(os.path.join(app.config['UPLOAD_PATH'], filename))
    return

页面实现效果

页面效果
页面效果

小结

至此,此应用的框架基本完成,最后的识别部分需要等到算法实现后再行融合。

你要相信流星划过会带给我们幸运,就像现实告诉你我要心存感激
Built with Hugo
Theme Stack designed by Jimmy