Skip to content

Commit b06813b

Browse files
committed
chore(ci): blog sync
1 parent b372d98 commit b06813b

File tree

2 files changed

+10
-10
lines changed

2 files changed

+10
-10
lines changed

data/blog/liulanqidiaoyongmaikefengquanxianshixianyuyinshurugongneng.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
tags: ["WebAPI"]
66
---
77

8-
### 前言
8+
## 前言
99
今天收到一个需求:在一个聊天室场景中,除了用户除了打字输入,还要求能语音输入,实现这个需求我使用到了浏览器的相关的API、阿里云的语音转换API。
1010
![image](https://github.com/coderInwind/inwindBlog/assets/91716457/a1fccca7-bbdb-4656-903a-0e876312e8ee)
1111

12-
### 采集音频
12+
## 采集音频
1313
首先我们得采集到用户说的话,实现这个得使用到两个浏览器的API,第一个是<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia" target="_blank">MediaDevices.getUserMedia()</a> `MediaDevices.getUserMedia()`会提示用户给予使用媒体输入的许可,媒体输入会产生一个[MediaStream](https://developer.mozilla.org/zh-CN/docs/Web/API/MediaStream),里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D 转换器等等),也可能是其他轨道类型。
1414

1515
通俗的来讲,就是可以拉取获取用户媒体权限的弹框,在用户通用后获取一个流。值得注意的是:在实现的过程中这个弹框的触发在各个浏览器中是不同的,在苹果的safari浏览器中获取权限框被用户拒绝后依旧能再次触发,但在某些安卓浏览器中权限框被拒绝后就会维持拒绝状态不会被触发;第二,获取权限和用户语音输入的时机最好错开,作者要实现的交互是按住进行语音输入,松开发送,但某些安卓浏览器在触发获取权限弹窗时会将`touchend`事件的图层覆盖掉,使之不能触发。需要注意的是这个API想要使用有诸多限制,首先只能在https协议下使用,其次使用的设备要有相关的媒体硬件,最后就是需要授权了。
@@ -51,7 +51,7 @@ speechState.recordInstance.onstop = () => {
5151
```
5252

5353

54-
### 转化音频
54+
## 转化音频
5555
这一步我们选用了阿里云的语音转化接口,但作者在写的时候没有弄清楚阿里云接口所接收的格式,所以卡了很久:
5656
```
5757
// 上传语音
@@ -88,11 +88,11 @@ wav是一种无损的音频文件格式,WAV符合 PIFF(Resource Interchange Fi
8888

8989
简单的来说,PCM 就是比 WAV 少一个文件头,因此你可以将他们互相转化。
9090

91-
### 发送音频
91+
## 发送音频
9292
其实到这里我们的功能差不多已经实现,接下来就是通过`WebSocket`发送,我就不多赘述了。
9393

9494

95-
### 总结
95+
## 总结
9696
这个需求完成的过程中的三个重点分别是:不同浏览器获取权限的适配、语音流的获取处理、不同语音格式的区分和转化。
9797

9898

data/blog/shiyongWebScoketshixianliaotianshi.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
tags: ["WebAPI","JavaScript"]
66
---
77

8-
### 前言
8+
## 前言
99
下来一个需求,要求实现类型一个聊天室的功能,我们使用到了`websocket`进行双向通讯实现。
1010
* 什么是websocket
1111
mdn做出如下解释:[WebSockets](https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket) 是一种先进的技术。它可以在用户的浏览器和服务器之间打开交互式通信会话。使用此 API,你可以向服务器发送消息并接收事件驱动的响应,而无需通过轮询服务器的方式以获得响应。
@@ -14,7 +14,7 @@ websocket与http协议相同点是他们都是基于TCP的协议,不同的是
1414
1. websocket是双向通信协议,而http是单向的
1515
2. 在建立连接的过程中,websocket会利用http请求进行握手,会经历四步: 客户端发送握手请 --> 服务端响应握手请求--> 客户端验证请求 --> 建立连接。而http需要经历三握四挥。
1616

17-
### websocket 实现聊天室
17+
## websocket 实现聊天室
1818

1919
首先我们需要建立websocket连接,值得注意的是如果你想在请求头上携带token,websocket是不支持自定义请求头名的,你可以放到第二个参数里,后端通过请求头`sec-websocket-protocol`获取,或者你可以直接凭借到请求的url上:
2020
```
@@ -33,13 +33,13 @@ chatState.chatInstance.onmessage = (res) => {
3333
```
3434
这样就完成了一个简单的websocket连接。
3535

36-
### 心跳
36+
## 心跳
3737
websocket并在不收发信息的情况下并不能一直维持连接,所以我们需要做心跳来维持websocket的连接,心跳这个名字我觉得形容的很恰当,心不跳自然就断开了,做心跳要和服务端约定好,我这里传一个`[PING]`,服务端就会返回一个`[PONG]`,我们在收到服务器消息的时候写一个定时器,过30s后我们再次发送,这样就能通过心跳维持WS的连接了。
3838

39-
### 聊天信息的流式输出
39+
## 聊天信息的流式输出
4040
因为在聊天的时候可能出现一些长文本,为了优化用户体验,我们需要实现一个流式输出的功能,我跟后端约定聊天的回复会一个字或几个字的传回来,但他们前后必须是有`[BEGIN]``[DONE]`消息的,所以在接收到相关的消息是我们将字符一个个拼接起来就能实现流式效果了。
4141

42-
### 语音的流式播放
42+
## 语音的流式播放
4343
同样的,长文本的语音播放太慢了,所以实现了一个语音的流式播放(真折磨),这里我同样使用到了websocket,后端将TTS合成的二进制数据,然后一段段的传回来,这里我用到了一个库`pcm-player`
4444
```
4545
const initPlayer = (index) => {

0 commit comments

Comments
 (0)