# 开发指南

# 客户端

uni直播可在uni-app或者uni-app x中快速集成,同时也支持使用第三方推流工具和拉流工具使用,详见

# uni-app

以下介绍在uni-app中如何实现推流和拉流,详细的示例代码请参考

# 推流

仅支持 App 端与微信小程序端

uni-app 使用 live-pusher 组件进行推流。

<template>
	<live-pusher
		id='livePusher'
		ref="livePusher"
		class="livePusher"
		:url="url"
		mode="SD"
		:muted="true"
		:enable-camera="true"
		:auto-focus="true"
		:beauty="1"
		whiteness="2"
		aspect="9:16"
		@statechange="statechange"
		@netstatus="netstatus"
		@error = "error"
	></live-pusher>
</template>

<script>
	export default {
		data() {
			return {
				url: ""
			}
		},
		onReady() {
			// 注意:需要在onReady中 或 onLoad 延时
			this.context = uni.createLivePusherContext("livePusher", this);
		},
		methods: {
			statechange(e) {
				console.log("statechange:" + JSON.stringify(e));
			},
			netstatus(e) {
				console.log("netstatus:" + JSON.stringify(e));
			},
			error(e) {
				console.log("error:" + JSON.stringify(e));
			},
			start: function () {
				this.context.start({
					success: (a) => {
						console.log("livePusher.start:" + JSON.stringify(a));
					}
				});
			},
			close: function() {
				this.context.close({
					success: (a) => {
						console.log("livePusher.close:" + JSON.stringify(a));
					}
				});
			}
		}
	}
</script>

# 拉流

微信小程序端使用live-player组件进行直播拉流;web/app端,使用video组件进行直播拉流。

在web拉流时需注意

  1. 拉流地址为rtmp协议时,在web端不支持播放,需要使用 Flash 播放器或转码为其他格式。
  2. 拉流地址视频格式为m3u8时,在web端video组件不支持播放,需要使用三方库hls.js播放。
  3. 拉流地址视频格式为flv时,在web端video组件不支持播放,需要使用三方库flv.js播放。
<template>
	<live-player
		src="rtmp://pull.example.com/live/streamName"
		autoplay
		@statechange="statechange"
		@error="error"
		style="width: 300px; height: 225px;"
	/>
</template>

<script>
    export default {
        methods:{
            statechange(e){
                console.log('live-player code:', e.detail.code)
            },
            error(e){
                console.error('live-player error:', e.detail.errMsg)
            }
        }
    }
</script>

# uni-app x

在 uni-app x 中推拉流, 需要 HBuilderX 4.81 及以上版本。

# 推流

仅支持 App 端与微信小程序端

uni-app x 使用 live-pusher 组件进行推流。

<template>
	<live-pusher :url="url" mode="FHD" :enable-camera="true" :enable-mic="true" @statechange="handleStateChange"
		@error="handleError" @netstatus="handleNetstatus" id="livePusher" ref="pusher"
		class="live-pusher"></live-pusher>
	<view class="info-wrap">
		<text class="info-item">状态: {{state}}</text>
		<text class="info-item">音频码率: {{audioBitrate}}</text>
		<text class="info-item">网络速度: {{netSpeed}}</text>
		<text class="info-item">视频帧率: {{videoFPS}}</text>
		<text class="info-item">视频码率: {{videoBitrate}}</text>
		<text class="info-item">关键帧率间隔: {{videoGOP}}</text>
	</view>
	<view class="btn-wrap">
		<button @click="start">开始推流</button>
		<button @click="stop">停止推流</button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				url: '',
				state: 'unknow',
				audioBitrate: 0,
				netSpeed: 0,
				videoBitrate: 0,
				videoFPS: 0,
				videoGOP: 0,
				context: null as LivePlayerContext | null
			}
		},
		methods: {
			createContext() {
				if (this.context == null) {
					this.context = uni.createLivePusherContext('livePusher')!
				}
			},
			handleStateChange(e : UniLivePusherStatechangeEvent) {
				this.state = e.detail.message
				console.log('handleStateChange', JSON.stringify(e.detail))
			},

			handleError(e : UniLivePusherErrorEvent) {
				this.state = e.detail.errMsg
				console.log('handleError', JSON.stringify(e.detail))

			},
			handleNetstatus(e : UniLivePusherNetstatusEvent) {
				this.audioBitrate = e.detail.audioBitrate
				this.netSpeed = e.detail.netSpeed
				this.videoBitrate = e.detail.videoBitrate
				this.videoFPS = e.detail.videoFPS
				this.videoGOP = e.detail.videoGOP
				this.videoHeight = e.detail.videoHeight
				this.videoWidth = e.detail.videoWidth
				console.log('handleNetstatus', JSON.stringify((e.detail)))
			},
			start() {
				this.createContext()
				this.context!.start({
					success(info ?: UTSJSONObject) {
						console.log("推流成功", JSON.stringify(info))
					},
					fail(info ?: UTSJSONObject) {
						console.log("推流失败", JSON.stringify(info))
					},
					complete() {
						console.log("推流完成")
					}
				} as LivePusherOptions)
			},
			// 停止推流
			stop() {
				this.createContext()
				this.context!.stop({
					success(info ?: UTSJSONObject) {
						console.log("关闭成功")
					},
					fail(info ?: UTSJSONObject) {
						console.log("关闭失败")
					},
					complete() {
						console.log("关闭完成")
					}
				} as LivePusherOptions)
			},
		}
	}
</script>

<style>
	.btn-wrap {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 50px;
		display: flex;
		flex-direction: row;
		padding: 0 20px;
	}

	.info-wrap {
		position: fixed;
		left: 0;
		right: 0;
		top: 50px;
		padding: 0 20px;
	}
</style>

# 拉流

app端和小程序都使用live-player组件进行直播拉流,web端使用video组件进行直播拉流。

在web拉流时需注意

  1. 拉流地址为rtmp协议时,在web端不支持播放,请使用其他格式。
  2. 拉流地址视频格式为m3u8时,在web端video组件不支持播放,需要使用三方库hls.js播放。
  3. 拉流地址视频格式为flv时,在web端video组件不支持播放,需要使用三方库flv.js播放。

<template>
	<live-player 
        :style="{'width' : '100%','height': '40%'}" 
        ref="liveref"
        :src="url"
        @fullscreenchange="fullscreenCallBack"
        @statechange="statechangeCallBack"
        @error="errorCallBack"
        id="livePlayer"></live-player>
	<button @click="play">播放</button>
	<button @click="pause">暂停</button>
	<button @click="stop">停止</button>
</template>

<script>
  export default {
    data() {
      return {
        url: 'rtmp://rtmp-pull.pcwant.com/6835813bf946a46b27902e06/test',
		context: null as LivePlayerContext | null
      }
    },
    methods: {
	    createContext() {
		    if (this.context == null) {
			    this.context = uni.createLivePlayerContext('livePlayer')!
		    }
	    },
	    play() {
		    this.createContext()
		    this.context!.play({
			    success(info?: UTSJSONObject) {
                    console.log("播放成功")
                },
                fail(info?: UTSJSONObject) {
                    console.log("播放失败")
                },
                complete() {
                    console.log("播放完成")
                }
            } as LivePlayerOptions)
        },
	    pause() {
		    this.createContext()
		    this.context!.pause({
			    success(info?: UTSJSONObject) {
                    console.log("暂停成功")
                },
                fail(info?: UTSJSONObject) {
                    console.log("暂停失败")
                },
                complete() {
                    console.log("暂停完成")
                }
            } as LivePlayerOptions)
	    },
	    stop() {
		    this.createContext()
		    this.context!.stop({
			    success(info?: UTSJSONObject) {
                    console.log("关闭成功")
                },
                fail(info?: UTSJSONObject) {
                    console.log("关闭失败")
                },
                complete() {
                    console.log("关闭完成")
                }
            } as LivePlayerOptions)
	    },
        fullscreenCallBack() {
            console.log("fullscreenCallBack");
        },
        statechangeCallBack(event: LivePlayerStatechangeEvent) {
            console.log("statechangeCallBack", event.detail.code)
        },
        errorCallBack(event: LivePlayerErrorEvent) {
            console.log("error", event)
        },
    }
  }
</script>

# 云函数

uni直播除了通过uniCloud控制台操作外,还可以在云函数中通过API创建推拉流。

# 启用uni-cloud-live扩展库

uni直播是单独的扩展库,开发者需手动将uni-cloud-live扩展库添加到云函数或云对象的依赖中。

操作步骤:

  1. 右键需要添加的云函数或云对象
  2. 点击-管理公共模块或扩展库依赖
  3. 勾选uni-cloud-live扩展库

# 生成推拉流地址

uni-cloud-live 扩展库主要的功能就是生成推流地址和拉流地址,生成的地址可以直接在客户端使用。

生成推拉流地址时无需提前创建直播流,生成地址时会自动创建。


module.exports = (event, context) => {
    const liveName = 'testStreamName'
    const liveManager = uniCloud.getLiveManager()
    // 生成推流地址
    const pushUrl = liveManager.stream.generatePushUrl(liveName, 'rtmp-push.example.com')
    // 生成拉流地址
    const pullUrl = liveManager.stream.generatePullUrl(liveName, 'rtmp-pull.example.com')
    return {
        pushUrl: pushUrl[liveName],
        pullUrl: pullUrl[liveName]
    }
}

# API

# 获取uni直播对象实例

API: uniCloud.getLiveManager()

# 创建直播流

APIliveManager.stream.create(name)

参数说明

参数 类型 默认值 必填 说明
name string - 直播流名称

返回值

参数 类型 默认值 必填 说明
name string - - 直播流名称

示例

const liveManager = uniCloud.getLiveManager()

// 创建直播流 live_2025
await liveMangaer.stream.create('live_2025')

# 获取直播流列表

API: liveManager.stream.list(params: Params)

Params参数说明

参数 类型 默认值 必填 说明
prefix string - 直播流名称前缀
offset number 0 偏移量
limit number 100 查询最大数量
startedAt number - 开始时间戳;毫秒级别
endedAt number - 结束时间戳;毫秒级别

返回值

参数 类型 默认值 必填 说明
list StreamList [] 直播流列表
page number 0 当前页面数
total number 0 直播流数量
pageSize number 0 每页最大查询数

StreamList

参数 类型 默认值 必填 说明
name string - 直播流名称
forbidden boolean - 直播流是否封禁
status string - 直播流状态;online 在线,offline 离线
lastStartAt number 0 最近一次推流时间;unix毫秒时间戳
createdAt number 0 创建时间;unix毫秒时间戳

# 获取直播流详情

API: liveManager.stream.detail(name: string)

参数说明

参数 类型 默认值 必填 说明
name string - 直播流名称

返回值

参数 类型 默认值 必填 说明
name string - 直播流名称
forbidden boolean false 直播流是否封禁
localAddr string - 本地流媒体服务地址
remoteAddr string - 推流客户端地址
lastStartAt number - 最近一次推流时间;unix毫秒时间戳
lastStartDomain string - 最近一次推流域名
status string - 直播流状态;online 在线,offline 离线

# 删除直播流

API: liveManager.stream.delete(name: string)

参数说明

参数 类型 默认值 必填 说明
name string - 直播流名称

返回值

参数 类型 默认值 必填 说明
errMsg string - 成功提示

# 封禁直播流

API: liveManager.stream.forbidden(name: string)

参数说明

参数 类型 默认值 必填 说明
name string - 直播流名称

返回值

参数 类型 默认值 必填 说明
errMsg string - 成功提示

# 解封直播流

API: liveManager.stream.release(name: string)

参数说明

参数 类型 默认值 必填 说明
name string - 直播流名称

返回值

参数 类型 默认值 必填 说明
errMsg string - 成功提示

# 断开所有用户连接

API: liveManager.stream.stop(name: string)

参数说明

参数 类型 默认值 必填 说明
name string - 直播流名称

返回值

参数 类型 默认值 必填 说明
errMsg string - 成功提示

# 生成推流地址

API: liveManager.stream.generatePushUrl(name: string | string[], domain: string)

参数说明

参数 类型 默认值 必填 说明
name string string[] - 直播流名称
domain string - 已绑定的推流域名

返回值

参数 类型 默认值 必填 说明
[name] string - 直播流名称

注意

如域名开启了时间戳鉴权,生成的连接会带上鉴权信息。

示例

const liveManager = uniCloud.getLiveManager()

const result = await liveManager.generatePushUrl('live_test', 'rtmp-push.test.com')

/**
 * result
 * {
 *    "live_test": "rtmp://rtmp-push.test.com/xxxxx/live_test"
 * }
 */

# 生成拉流地址

API: liveManager.stream.generatePullUrl(name: string | string[], domain: string)

参数说明

参数 类型 默认值 必填 说明
name string string[] - 直播流名称
domain string - 已绑定的拉流域名

返回值

参数 类型 默认值 必填 说明
[name] string - 直播流名称

注意

如域名开启了时间戳鉴权,生成的连接会带上鉴权信息。

示例

const liveManager = uniCloud.getLiveManager()

const result = await liveManager.generatePullUrl('live_test', 'rtmp-pull.test.com')

/**
 * result
 * {
 *    "live_test": "rtmp://rtmp-pull.test.com/xxxxx/live_test"
 * }
 */

# 获取推流域名详情

API: liveManager.domain.getPushDomainDetail(domain: string)

参数说明

参数 类型 默认值 必填 说明
domain string - 已绑定的拉流域名

返回值

参数 类型 默认值 必填 说明
domain string - 域名
cname string - CNAME域名
type string - 域名类型
auth PushDomainAuth - 防盗链配置参数
enable boolean - 域名是否启用
certId string - SSL证书id
createdAt number - 创建时间;毫秒时间戳
lastModifiedAt number - 最后更新时间;毫秒时间戳

PushDomainAuth

参数 类型 默认值 必填 说明
primaryKey string - 主密钥
secondaryKey string - 副密钥
expireSeconds number - 防盗链过期时间秒数

# 获取拉流域名详情

API: liveManager.domain.getPullDomainDetail(domain: string)

参数说明

参数 类型 默认值 必填 说明
domain string - 已绑定的拉流域名

返回值

参数 类型 默认值 必填 说明
domain string - 域名
cname string - CNAME域名
type string - 域名类型
auth PullDomainAuth - 防盗链配置参数
enable boolean - 域名是否启用
certId string - SSL证书id
createdAt number - 创建时间;毫秒时间戳
lastModifiedAt number - 最后更新时间;毫秒时间戳

PullDomainAuth

参数 类型 默认值 必填 说明
primaryKey string - 主密钥
secondaryKey string - 副密钥
expireSeconds number - 防盗链过期时间秒数

# 上传域名SSL证书

API: liveManager.domain.uploadCertificate(params: Params)

Params参数说明

参数 类型 默认值 必填 说明
certId string - 证书ID;须保持唯一
domain string - 证书绑定的域名
cert string - 证书内容
key string - 证书私钥

返回值

参数 类型 默认值 必填 说明
errMsg string - 成功提示

# 获取域名SSL证书列表

API: liveManager.domain.listCertificates(params: Params)

Params参数说明

参数 类型 默认值 必填 说明
domain string - 域名

返回值

参数 类型 默认值 必填 说明
data Cert[] - 证书列表数据
errMsg string - 成功提示

Cert

参数 类型 默认值 必填 说明
certId string - 证书ID
domain string - 域名
cert string - 证书内容
key string - 证书私钥
effectiveTime string - 证书生效时间
expirationTime string - 证书过期时间

# 删除域名SSL证书

API: liveManager.domain.deleteCertificate(params: Params)

Params参数说明

参数 类型 默认值 必填 说明
certId string - 证书ID;须保持唯一
domain string - 证书绑定的域名

返回值

参数 类型 默认值 必填 说明
errMsg string - 成功提示

# 更新域名SSL证书

API: liveManager.domain.updateCertificate(params: Params)

Params参数说明

参数 类型 默认值 必填 说明
certId string - 证书ID;须保持唯一
domain string - 证书绑定的域名
cert string - 证书内容
key string - 证书私钥

返回值

参数 类型 默认值 必填 说明
errMsg string - 成功提示

# 更新推流域名证书

API: liveManager.domain.updatePushDomainCertificate(params: Params)

Params参数说明

参数 类型 默认值 必填 说明
certId string - 证书ID;上传SSL证书填写的证书ID
domain string - 推流域名

返回值

参数 类型 默认值 必填 说明
certId string - 更新后的certId

# 更新拉流域名证书

API: liveManager.domain.updatePullDomainCertificate(params: Params)

Params参数说明

参数 类型 默认值 必填 说明
certId string - 证书ID;上传SSL证书填写的证书ID
domain string - 拉流域名

返回值

参数 类型 默认值 必填 说明
certId string - 更新后的certId