g711-web-stream-player 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AbelShine
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,273 @@
1
+ # g711-web-stream-player
2
+
3
+ Clean and smooth G.711 audio playback for the Web.
4
+
5
+ 一个面向浏览器的轻量级 TypeScript G.711 流式音频库。它可以从 HTTP-FLV 流中提取 PCMA(A-law)或 PCMU(μ-law)音频,解码并通过 Web Audio API 播放,同时利用预缓冲、环形缓冲、插值升采样、噪声门和语音滤波改善实时音频的底噪与卡顿。
6
+
7
+ 核心库不依赖任何前端框架,并提供 Vue 2、Vue 3 和 React 适配入口。
8
+
9
+ ## 特性
10
+
11
+ - G.711 A-law(PCMA)与 μ-law(PCMU)解码
12
+ - HTTP-FLV 流式读取及音频 Tag 增量解析
13
+ - 环形缓冲与可配置预缓冲,吸收网络抖动
14
+ - Catmull-Rom 三次插值升采样,适配浏览器输出采样率
15
+ - RMS 噪声门,压低无语音时的持续底噪
16
+ - 高通滤波切除低频嗡声,高频搁架滤波补偿语音清晰度
17
+ - 框架无关的 TypeScript API
18
+ - Vue 2 / Vue 3 Composition API 适配
19
+ - React Hook 适配
20
+ - ESM、CommonJS 与完整类型声明
21
+
22
+ ## 安装
23
+
24
+ 当前可以直接从 GitHub 安装:
25
+
26
+ ```bash
27
+ npm install github:AbelShine/g711-web-stream-player
28
+ ```
29
+
30
+ 发布到 npm 后可使用:
31
+
32
+ ```bash
33
+ npm install g711-web-stream-player
34
+ ```
35
+
36
+ 只使用核心 API 时不需要安装框架依赖。使用框架适配入口时,再安装对应依赖:
37
+
38
+ ```bash
39
+ # Vue 3 或 Vue 2.7
40
+ npm install vue vue-demi
41
+
42
+ # React
43
+ npm install react
44
+ ```
45
+
46
+ Vue 2.6 还需要 Composition API:
47
+
48
+ ```bash
49
+ npm install vue@2.6 @vue/composition-api vue-demi
50
+ ```
51
+
52
+ 并在应用入口安装插件:
53
+
54
+ ```ts
55
+ import Vue from 'vue'
56
+ import VueCompositionAPI from '@vue/composition-api'
57
+
58
+ Vue.use(VueCompositionAPI)
59
+ ```
60
+
61
+ ## 快速开始
62
+
63
+ 浏览器通常只允许在用户点击或触摸后启动音频。建议在播放按钮的事件处理函数中调用 `start()` 或 `resume()`。
64
+
65
+ ### 原生 JavaScript / TypeScript
66
+
67
+ ```ts
68
+ import { FlvAudioStreamer } from 'g711-web-stream-player'
69
+
70
+ const audio = new FlvAudioStreamer({
71
+ player: {
72
+ // 播放前积累 120ms 音频,用少量延迟换取更稳定的播放。
73
+ prebufferMs: 120,
74
+ // -42dBFS 左右关闭噪声门;设为 0 可关闭噪声门。
75
+ noiseGateThreshold: 0.008,
76
+ highpassHz: 180,
77
+ volume: 0.8,
78
+ },
79
+ })
80
+
81
+ document.querySelector('#play')?.addEventListener('click', () => {
82
+ // 实时流会持续读取,因此不要在点击处理器中 await。
83
+ void audio.start('https://example.com/live.flv', {
84
+ onCodecDetected(codec) {
85
+ console.log('检测到音频编码:', codec)
86
+ },
87
+ onError(error) {
88
+ console.error('音频流错误:', error)
89
+ },
90
+ })
91
+ })
92
+
93
+ document.querySelector('#stop')?.addEventListener('click', () => audio.stop())
94
+
95
+ // 页面不再使用播放器时释放 AudioContext。
96
+ window.addEventListener('beforeunload', () => audio.destroy())
97
+ ```
98
+
99
+ ### Vue 3
100
+
101
+ ```vue
102
+ <script setup lang="ts">
103
+ import { useG711Stream } from 'g711-web-stream-player/vue'
104
+
105
+ const { isStreaming, codec, error, start, stop, setMuted, setVolume } = useG711Stream({
106
+ player: { prebufferMs: 120 },
107
+ })
108
+
109
+ function play() {
110
+ void start('https://example.com/live.flv')
111
+ }
112
+ </script>
113
+
114
+ <template>
115
+ <button @click="play">播放</button>
116
+ <button @click="stop">停止</button>
117
+ <button @click="setMuted(true)">静音</button>
118
+ <input type="range" min="0" max="1" step="0.1" @input="setVolume(Number(($event.target as HTMLInputElement).value))" />
119
+ <span v-if="isStreaming">播放中:{{ codec || '检测中' }}</span>
120
+ <span v-if="error">{{ error.message }}</span>
121
+ </template>
122
+ ```
123
+
124
+ ### Vue 2
125
+
126
+ Vue 2.7 可以直接在 `setup()` 中使用;Vue 2.6 请先按照安装章节配置 `@vue/composition-api`。
127
+
128
+ ```ts
129
+ import { defineComponent } from 'vue-demi'
130
+ import { useG711Stream } from 'g711-web-stream-player/vue'
131
+
132
+ export default defineComponent({
133
+ setup() {
134
+ const stream = useG711Stream({
135
+ player: { prebufferMs: 160 },
136
+ })
137
+
138
+ const play = () => {
139
+ void stream.start('https://example.com/live.flv')
140
+ }
141
+
142
+ return { ...stream, play }
143
+ },
144
+ })
145
+ ```
146
+
147
+ Vue 适配器会在组件卸载时自动销毁播放器和网络请求。
148
+
149
+ ### React
150
+
151
+ ```tsx
152
+ import { useG711Stream } from 'g711-web-stream-player/react'
153
+
154
+ export function AudioControls() {
155
+ const { isStreaming, codec, error, start, stop, setMuted } = useG711Stream({
156
+ player: { prebufferMs: 120 },
157
+ })
158
+
159
+ return (
160
+ <section>
161
+ <button onClick={() => void start('https://example.com/live.flv')}>播放</button>
162
+ <button onClick={stop}>停止</button>
163
+ <button onClick={() => setMuted(true)}>静音</button>
164
+ <p>{isStreaming ? `播放中:${codec ?? '检测中'}` : '已停止'}</p>
165
+ {error && <p role="alert">{error.message}</p>}
166
+ </section>
167
+ )
168
+ }
169
+ ```
170
+
171
+ React Hook 会在组件卸载时自动销毁播放器和网络请求。
172
+
173
+ ## 播放原始 G.711 数据包
174
+
175
+ 如果项目已经通过 WebSocket、WebRTC 数据通道或其他方式拿到了原始 G.711 包,可以绕过 FLV 解析器:
176
+
177
+ ```ts
178
+ import { G711AudioPlayer } from 'g711-web-stream-player'
179
+
180
+ const player = new G711AudioPlayer({ prebufferMs: 100 })
181
+
182
+ playButton.addEventListener('click', () => {
183
+ player.init()
184
+ })
185
+
186
+ socket.addEventListener('message', (event) => {
187
+ player.pushChunk(new Uint8Array(event.data), 'pcma')
188
+ })
189
+ ```
190
+
191
+ 仅需要解码时也可以直接调用:
192
+
193
+ ```ts
194
+ import { decodeG711Chunk, decodeG711ToFloat32 } from 'g711-web-stream-player'
195
+
196
+ const pcm16 = decodeG711Chunk(packet, 'pcmu')
197
+ const webAudioSamples = decodeG711ToFloat32(packet, 'pcmu')
198
+ ```
199
+
200
+ ## 核心配置
201
+
202
+ `G711AudioPlayer` 或 `FlvAudioStreamer` 的 `player` 字段支持以下常用选项:
203
+
204
+ | 选项 | 默认值 | 说明 |
205
+ | --- | ---: | --- |
206
+ | `inputSampleRate` | `8000` | 输入 G.711 采样率 |
207
+ | `prebufferMs` | `120` | 首次播放及欠载后的预缓冲时长;网络差时可调至 160–300ms |
208
+ | `bufferDurationMs` | `4000` | 环形缓冲最大容量 |
209
+ | `overflowDropMs` | `150` | 缓冲溢出时丢弃的旧音频时长 |
210
+ | `processorBufferSize` | `2048` | Web Audio 处理块大小 |
211
+ | `cubicInterpolation` | `true` | 是否使用三次插值升采样 |
212
+ | `noiseGateThreshold` | `0.008` | RMS 噪声门阈值;`0` 表示关闭 |
213
+ | `noiseGateFloor` | `0.18` | 噪声门关闭时保留的增益 |
214
+ | `noiseGateRelease` | `0.35` | 噪声门关闭速度 |
215
+ | `highpassHz` | `180` | 高通截止频率;`0` 表示关闭 |
216
+ | `highshelfHz` | `2600` | 高频补偿起始频率;`0` 表示关闭 |
217
+ | `highshelfGainDb` | `2` | 高频补偿增益 |
218
+ | `volume` | `1` | 初始音量,范围 0–1 |
219
+ | `muted` | `false` | 是否初始静音 |
220
+
221
+ ### 调优建议
222
+
223
+ - 仍然偶发卡顿:优先增大 `prebufferMs`,代价是播放延迟增加。
224
+ - 人声开头被截断:降低 `noiseGateThreshold` 或把它设为 `0`。
225
+ - 环境低频声过重:适当提高 `highpassHz`,但过高会让人声变薄。
226
+ - 音频延迟不断增大:减小 `bufferDurationMs` 或增大 `overflowDropMs`。
227
+
228
+ ## FLV 输入要求
229
+
230
+ - FLV Audio Tag 的 `SoundFormat` 必须为 `7`(G.711 A-law)或 `8`(G.711 μ-law)。
231
+ - HTTP-FLV 地址必须允许浏览器跨域访问(CORS)。
232
+ - 如果接口需要 Cookie,请通过 `extractor.requestInit.credentials` 配置。
233
+ - HTTPS 页面不能直接请求 HTTP 流,否则会被浏览器的混合内容策略阻止。
234
+
235
+ 带认证信息的示例:
236
+
237
+ ```ts
238
+ const audio = new FlvAudioStreamer({
239
+ extractor: {
240
+ requestInit: {
241
+ credentials: 'include',
242
+ headers: { Authorization: 'Bearer ...' },
243
+ },
244
+ },
245
+ })
246
+ ```
247
+
248
+ 请勿在公开代码、日志或 Issue 中提交真实令牌和内网流地址。
249
+
250
+ ## 开发
251
+
252
+ ```bash
253
+ git clone https://github.com/AbelShine/g711-web-stream-player.git
254
+ cd g711-web-stream-player
255
+ npm install
256
+ npm run check
257
+ ```
258
+
259
+ 构建产物位于 `dist/`:
260
+
261
+ - `index`:框架无关核心 API
262
+ - `vue`:Vue 2 / Vue 3 Composition API 适配器
263
+ - `react`:React Hook 适配器
264
+
265
+ ## 浏览器兼容性
266
+
267
+ 需要浏览器支持 Fetch、ReadableStream 和 Web Audio API。移动端浏览器通常要求用户手势触发播放。
268
+
269
+ 当前播放器使用兼容性较好的 `ScriptProcessorNode`。它已被 Web Audio 标准标记为 deprecated,但在主流浏览器仍有广泛支持;后续版本计划提供 AudioWorklet 后端。
270
+
271
+ ## License
272
+
273
+ [MIT](LICENSE)