web和uniapp接入腾讯云直播_uni-app 怎么引入腾讯云直播sdk
准备工作:首选需要一个通过ICP备案的域名,如minglina.com。开通腾讯云云直播服务。
一、添加推流域名、播放域名
使用云直播服务,至少需要2个域名,一个作为推流域名,一个作为播放域名,且推流和播放不能使用相同的域名。但可以通过二级域名来进行区分,不局限于是否两个子域名,例如可以使用 push.minglina.com
作为推流域名,将 play.minglina.com
作为播放域名。
参考域名管理。
二、生成推流、播放地址
1.生成推流地址
云直播控制台提供地址生成器功能,支持通过填写地址拼接信息,辅助用户快速生成推流/播放地址。其中直播地址主要由域名(domain)、应用名称(AppName)、流名称(StreamName)以及鉴权 Key 组成。
域名管理,选择推流域名->推流配置,获取推流的鉴权key。
参考直播推流 。
2.生成播放地址
域名管理,选择播放域名->访问控制,获取播放的鉴权key。
参考 推流url 。
3.代码生成推流、播放地址:
import cn.hutool.core.date.DateUtil;import com.ynfy.buss.live.entity.vo.LiveVO;import com.ynfy.buss.live.service.ILiveService;import com.ynfy.common.utils.LiveUtil;import lombok.extern.slf4j.Slf4j;import org.jeecg.common.exception.JeecgBootException;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;/** * @Description: 直播服务 * @Author: jeecg-boot * @Date: 2025-06-11 * @Version: V1.0 */@Slf4j@Servicepublic class LiveServiceImpl implements ILiveService { /** * 是否开启直播功能 */ @Value(\"${tencent.cloud.live.enable}\") public Boolean liveEnable; /** * 推流域名 */ @Value(\"${tencent.cloud.live.pushDomain}\") public String pushDomain; /** * 播放域名 */ @Value(\"${tencent.cloud.live.playDomain}\") public String playDomain; /** * app名称 */ @Value(\"${tencent.cloud.live.appName}\") public String appName; /** * 推流鉴权key */ @Value(\"${tencent.cloud.live.pushKey}\") public String pushKey; /** * 播放鉴权key */ @Value(\"${tencent.cloud.live.playKey}\") public String playKey; /** * 获取推流、播放 URL * * @param streamName */ @Override public LiveVO getPushPlayUrl(String streamName, String endTime) { if (!liveEnable) { throw new JeecgBootException(\"直播功能暂未开放\"); } try { //获取推流鉴权信息 String pushAuthInfo = LiveUtil.getSafeUrl(pushKey, streamName, DateUtil.parseDateTime(endTime).getTime() / 1000); //获取播放鉴权信息 String playAuthInfo = LiveUtil.getSafeUrl(playKey, streamName, DateUtil.parseDateTime(endTime).getTime() / 1000); //推流地址 String rtmpPushUrl = new StringBuilder().append(\"rtmp://\").append(pushDomain).append(\"/\") .append(appName).append(\"/\").append(streamName).append(\"?\").append(pushAuthInfo).toString(); String webRTCPushUrl = new StringBuilder().append(\"webrtc://\").append(pushDomain).append(\"/\") .append(appName).append(\"/\").append(streamName).append(\"?\").append(pushAuthInfo).toString(); //播放地址 String rtmpPlayUrl = new StringBuilder().append(\"rtmp://\").append(playDomain).append(\"/\") .append(appName).append(\"/\").append(streamName).append(\"?\").append(playAuthInfo).toString(); String webRTCPlayUrl = new StringBuilder().append(\"webrtc://\").append(playDomain).append(\"/\") .append(appName).append(\"/\").append(streamName).append(\"?\").append(playAuthInfo).toString(); String hlsPlayUrl = new StringBuilder().append(\"http://\").append(playDomain).append(\"/\") .append(appName).append(\"/\").append(streamName).append(\".m3u8?\").append(playAuthInfo).toString(); LiveVO live = new LiveVO(); live.setRtmpPushUrl(rtmpPushUrl); live.setWebrtcPushUrl(webRTCPushUrl); live.setRtmpPlayUrl(rtmpPlayUrl); live.setWebrtcPlayUrl(webRTCPlayUrl); live.setHlsPlayUrl(hlsPlayUrl); return live; } catch (Exception e) { e.printStackTrace(); log.error(\"获取推流 URL出错:{}\", e.getMessage()); throw new JeecgBootException(\"获取推流、播放 URL出错\"); } }}
生成权限信息工具类:
import java.security.MessageDigest;/** * 腾讯云直播工具类 */public class LiveUtil { public static void main(String[] args) { System.out.println(getSafeUrl(\"txrtmp\", \"11212122\", 1469762325L)); } private static final char[] DIGITS_LOWER = {\'0\', \'1\', \'2\', \'3\', \'4\', \'5\', \'6\', \'7\', \'8\', \'9\', \'a\', \'b\', \'c\', \'d\', \'e\', \'f\'}; /* * KEY+ streamName + txTime */ public static String getSafeUrl(String key, String streamName, long txTime) { String input = new StringBuilder(). append(key). append(streamName). append(Long.toHexString(txTime).toUpperCase()).toString(); String txSecret = null; try { MessageDigest messageDigest = MessageDigest.getInstance(\"MD5\"); txSecret = byteArrayToHexString( messageDigest.digest(input.getBytes(\"UTF-8\"))); } catch (Exception e) { e.printStackTrace(); } return txSecret == null ? \"\" : new StringBuilder(). append(\"txSecret=\"). append(txSecret). append(\"&\"). append(\"txTime=\"). append(Long.toHexString(txTime).toUpperCase()). toString(); } private static String byteArrayToHexString(byte[] data) { char[] out = new char[data.length << 1]; for (int i = 0, j = 0; i >> 4]; out[j++] = DIGITS_LOWER[0x0F & data[i]]; } return new String(out); }}
三、前端页面推流
1.首选需调用上述接口生成推流和播放地址。
2.推流
web推流
云直播提供了推流 SDK TXLivePusher
用于 Web 推流。 index.html页面的body 部分引入TXLivePusher js脚本。
需要获取摄像头使用权限。推流页面代码:
开始直播 停止直播 import {ref} from \"vue\";import {useMessage} from \"@/hooks/web/useMessage\"; const record = ref(); //传入你的数据const local_video = ref();const livePusher = ref();const {createMessage} = useMessage();const liveIng = ref(false); onMounted(() => {//初始化播放器 initLivePusher() }); //初始化播放器function initLivePusher() { livePusher.value = new TXLivePusher(); livePusher.value.setRenderView(\'local_video\'); livePusher.value.videoView.muted = true; // // 设置视频质量 livePusher.value.setVideoQuality(\'720p\'); // // 设置音频质量 livePusher.value.setAudioQuality(\'standard\'); // // 自定义设置帧率 livePusher.value.setProperty(\'setVideoFPS\', 25);}//开始直播function startLive() { // 采集完摄像头和麦克风之后自动推流 Promise.all([livePusher.value.startCamera(), livePusher.value.startMicrophone()]) .then(function () { livePusher.value.startPush(record.value.webrtcPushUrl); }); observerLive()}//停止直播function stopLive() { livePusher.value.stopPush(); // 关闭摄像头 livePusher.value.stopCamera(); // 关闭麦克风 livePusher.value.stopMicrophone(); liveIng.value = false}function observerLive() { livePusher.value.setObserver({ onError: function (status, message) { createMessage.error(message) stopLive() }, onPushStatusUpdate: function (status, message) { if (status == 2) { liveIng.value = true createMessage.success(\"与服务器连接成功,直播推流开始啦!\") } if (status == 0) { createMessage.warn(\"与服务器连接断开,已关闭直播推流!\") } }, });}
参考 TXLivePusher 。
另一种是OBS工具推流。下载后添加源。
设置直播推流地址和推流码。
设置好后点击开始直播。
四、播放
1.web播放,使用腾讯云视立方SDK播放。
进入视立方控制台申请web端License:
安装 tcplayer 的 npm 包:
npm install tcplayer.js
licenseUrl为上述环节申请的。tcplayer播放器拉流WebRTC地址播放。
import TCPlayer from \"tcplayer.js\";import \"tcplayer.js/dist/tcplayer.min.css\";import { onBeforeUnmount, ref, watchEffect } from \"vue\"; import { useMessage } from \"@/hooks/web/useMessage\"; const { createMessage, } = useMessage();const livePlayer = ref(); const props = defineProps({ form: { type: Object, default: {} },});watchEffect(() => { if (props.form?.isLive) { //直播课程创建直播播放器 createLivePlayer(props.form.webrtcPlayUrl); }});//创建直播播放器function createLivePlayer(playUrl) { // live-player 为播放器容器 ID livePlayer.value = TCPlayer(\"live-player\", { sources: [{ src: playUrl // 播放地址 }], licenseUrl: \"https://license.vod2.myqcloud.com/license/v4/13013228971_1/v_cube.license\" // license 地址,必传 }); livePlayer.value.on(\"error\", function(e) { createMessage.error(\"直播出错啦:\" + (e.data.source.message ?? \"\") + \"(代码:\" + e.data.code + \")\"); }); livePlayer.value.on(\"play\", function() { createTimer(); });} //页面销毁前解除监听onBeforeUnmount(async () => { //销毁播放器 if (livePlayer.value) { livePlayer.value.dispose(); }});
参考 Tcplayer。
2.uniapp播放。
一种方式是 标签。 是小程序内部用于支持音视频下行(播放)能力的功能标签。开通该标签需要满足规定的类目,详见live-player。
另一种是小程序端和app端都使用video标签播放。在前面获取到的播放地址中已经生成了HLS播放地址。
export default {props: [\'form\'],data() {return {playUrl: \"\"};},watch: {form: {handler(val, oldVal) {if (val?.isLive) { //直播课程创建直播播放器if (val?.hlsPlayUrl) {//替换直播播放地址,从服务器代理获取推流this.playUrl = val.hlsPlayUrl.replace(\"http://play.minglin.com\",\"https://exam.minglin.com/hls-player\");}}},immediate: true},},methods: { handleError() {uni.showToast({icon: \"none\",title: \"获取直播推流失败\"})}, }}.player-content {position: relative;width: 750rpx;height: 450rpx;display: flex;background-size: 100% 100%;.live-player {width: 100%;height: 100%;position: relative;}}
需要注意的是生成的HLS播放地址是http的,小程序支持https。所以需要转换下,然后通过nginx代理播放直播流。
五、效果
1.web端:
2.uniapp端: