# web-rtmp
> Web版的RTMP推流SDK。 接收摄像头、麦克风、屏幕共享MediaStreamTrack, 视频编码为H264、音频编码为AAC, 并通过http协议以Flv打包格式进行推流


## 快速开始

```
npm install @byted/web-rtmp

import { Bridge } from "@byted/web-rtmp"

if(!Bridge.isSupported()) return

const rtmp = new Bridge()

await rtmp.ready()

rtmp.addTrack(videoMediaStreamTrack)

rtmp.addTrack(audioMediaStreamTrack)

rtmp.publish(url)

```

## API


### 静态方法

#### isSupported

```typescript
// 探测 webtransport 推流方式是否支持
static isSupported: () => boolean
```


### 实例方法

#### ready

```typescript
/**
 * 异步初始化逻辑，需要执行成功后添加音视频track、开始推流
 **/
abstract ready: () => Promise<void>
```

### setEncodeCapacity

```typescript
/**
 *设置编码配置，支持gop大小、音频采样率、音频channel数设置。publish()之前调用
 **/
abstract setEncodeCapacity: (cfg: EncodeCapacityConfig) => void

type EncodeCapacityConfig = {
    gopSize?: number, // 默认值 90
    sampleRate?: number, // 默认值44100, 支持范围[22050, 44100, 48000]
    channel?: 1 | 2, // 默认值2
}

```


#### addTrack

```typescript
/**
 * 添加采集的音视频track, 摄像头、麦克风、屏幕共享
 **/
abstract addTrack: (track: MediaStreamTrack) => void
```

#### replaceTrack

```typescript

import { StreamTrackType } from "@byted/web-rtmp"

/**
 * 替换音视频track, 摄像头、麦克风、屏幕共享
 **/
abstract replaceTrack: (
        kind: StreamTrackType,
        track: MediaStreamTrack | null
    ) => void
```

#### getStats
```typescript

import { RTMPStats } from "@byted/web-rtmp"

/**
 * 获取推流状态
 **/
abstract getStats: () => Promise<RTMPStats>

type RTMPStats = {
    video: {
        sendBitrate: number  // 推流码率 / bps
        framesPerSecond: number // 推流帧率
        framesEncoded: number // 从推流开始一共编码帧数
        keyFramesEncoded: number // 从推流开始编码关键帧数
        sendSpeed: number // 上行发送速度 /bps
        codec: string  // 视频编码格式
        frameWidth: number  // 视频编码宽度
        frameHeight: number // 视频编码高度
        gopSize: number // gop大小
    }
    audio: {
        sendBitrate: number  // 推流码率 / bps
        framesEncoded: number  // 从推流开始一共编码帧数
        codec: string // 音频编码格式
        channels: number  // 音频channel数量
        sampleRate: number // 音频采样率
    }
}

```


#### adjustBitrate

```typescript
import { StreamTrackType } from "@byted/web-rtmp"

/**
 * 调整音视频推流码率
 **/
abstract adjustBitrate: (kind: StreamTrackType, bitrate: number) => void
```

#### publish

```typescript
/**
 * 开始推流，确保已经调用 addTrack()
 **/
abstract publish: (url: string) => void
```

#### destroy

```typescript
/**
 * 停止推流并销毁内部状态
 **/
abstract destroy: () => void
```


## 事件

```typescript

import { 
    RTMPEventsTypes,
    RTMPErrorCode,
    RTMPError
}, Bridge from "@byted/web-rtmp"

const rtmp = new Bridge()

rtmp.on(RTMPEventsTypes.OnError, (e: RTMPError) => {})


```

|事件类型|回调签名| 说明 | 
| ------ | -------- | --- |
| RTMPEventsTypes.OnError | (e: RTMPError) => void | 错误分类见下面RTMPErrorCode |
| RTMPEventsTypes.OnFirstFramePushed | () => void | 视频首帧数据推送后 |


## RTMPErrorCode

```typescript

interface RTMPError extends Error {
    code: RTMPErrorCode
    message: string
    ext: Record<string, unknown> | undefined
}

```

| code | 说明 | 
| ------ | -------- |
| RTMPErrorCode.RTMP_INIT_FAIL  | Bridge实例初始化失败 |
| RTMPErrorCode.AUDIO_ENCODER_INIT_FAIL | 音频编码器初始化失败 |
| RTMPErrorCode.AUDIO_ENCODE_FILA  | 音频编码出错 |
| RTMPErrorCode.VIDEO_ENCODE_CONFIGURE_FAIL | 视频更新编码配置出错 |
| RTMPErrorCode.VIDEO_ENCODE_FAIL | 视频编码出错 |
| RTMPErrorCode.WTP_OPEN_FAIL | 推流连接建立失败 |
| RTMPErrorCode.WTP_CONNECT_FAIL | 推流连接断开 |
| RTMPErrorCode.WORKER_ERROR | 推流实例内部worker出错 |



