接入流程概览
要做出开箱体验里的效果,只需要三块:
- 设备端负责送音视频流:拿着
license上线,并持续发送音视频 - 业务服务端负责授权:按目标
peer_id返回这次连接的token - 客户端负责播放:拿
peer_id + token连上设备,并把画面和声音播出来
先准备这 3 个关键输入
| 输入 | 用来干什么 |
|---|---|
license | 给设备用的身份凭证,格式是 <peer_id>,<device_secret_key>。设备端靠它启动并上线。 |
peer_id | 这台设备的连接标识,例如 AABBCCDDEEFF。客户端和服务端都围绕它工作。 |
token 接口 | Android 客户端连设备前,先向你的业务服务端拿一枚短时有效的连接凭证。 |
1. 服务端返回 Token
客户端先发起授权请求:
http
GET /connect-token?peer_id=device://AABBCCDDEEFF
Authorization: Bearer <user_access_token>服务端校验该用户是否可以连接目标设备:
go
if !canConnectDevice(userID, peerID) {
return http403("forbidden")
}校验通过后,签发短时 Token:
go
func issueConnectToken(userID string, peerID string) string {
now := time.Now().Unix()
payload := map[string]any{
"sub": userID,
"scope": "connect:" + peerID,
"iss": accessID,
"iat": now,
"exp": now + 300,
"nonce": randomNonce(),
}
payloadB64 := base64url(jsonMarshal(payload))
deviceSig := hmacSHA256(deviceSecretKey, payloadB64)
appSig := hmacSHA256(secretKey, payloadB64+"."+deviceSig)
return "v1." + payloadB64 + "." + appSig
}最后通过 HTTP Response 返回给客户端:
json
{
"peer_id": "device://AABBCCDDEEFF",
"token": "v1.xxxxxx.yyyyyy",
"expires_in": 300
}2. 设备端上线并送流
初始化 SDK,上线:
c
TiRtcInit();
TiRtcSetOpt(TIRTC_OPT_SERVICE_ENTRY, service_entry, (uint32_t)strlen(service_entry));
// 准备回调,用于监听事件,以便响应
static const TIRTCCALLBACKS callbacks = {
.on_event = on_event,
.on_conn_accepted = on_conn_accepted,
};
// 上线,并等待客户端连接
TiRtcStart(license, &callbacks);组装 H264 视频帧,并发送:
c
TIRTCFRAMEINFO vfi;
memset(&vfi, 0, sizeof(vfi));
vfi.stream_id = 0;
vfi.media = TIRTC_VIDEO_H264;
vfi.flags = is_key_frame ? TIRTC_FRAME_FLAG_KEY_FRAME : 0;
vfi.ts = video_timestamp_ms;
vfi.length = video_len;
TiRtcSendMedia(hconn, &vfi, video_data);组装 G711A 音频帧,并发送:
c
TIRTCFRAMEINFO afi;
memset(&afi, 0, sizeof(afi));
afi.stream_id = 1;
afi.media = TIRTC_AUDIO_ALAW;
afi.flags = TIRTC_AUDIOSAMPLE_16K16B1C;
afi.ts = audio_timestamp_ms;
afi.length = audio_len;
TiRtcSendMedia(hconn, &afi, audio_data);3. 客户端连接并播放
以 Android 客户端为例,先准备音视频播放需要的资源:
kotlin
val audioOutput = TiRtcAudioOutput()
val videoOutput = TiRtcVideoOutput().apply {
val remoteVideoContainer = findViewById<FrameLayout>(R.id.remote_video_container)
attach(remoteVideoContainer)
}连接,开始播放:
kotlin
TiRtcConn().apply {
attachVideoOutput(videoStreamId = 0, videoOutput = videoOutput)
attachAudioOutput(audioStreamId = 1, audioOutput = audioOutput)
connect(peerId, token)
}下一步
- 想先看成品体验:看开箱体验
- 想接服务端签发:看获取连接 Token
- 想接设备端:看Nano SDK 接入指南
- 想接 Android 客户端:看Android 接入指南