当前位置: 首页 > news >正文

web和uniapp接入腾讯云直播

        准备工作:首选需要一个通过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
@Service
public 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*/@Overridepublic 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 < data.length; i++) {out[j++] = DIGITS_LOWER[(0xF0 & data[i]) >>> 4];out[j++] = DIGITS_LOWER[0x0F & data[i]];}return new String(out);}
}

        三、前端页面推流

        1.首选需调用上述接口生成推流和播放地址。

        2.推流

        web推流  

        云直播提供了推流 SDK TXLivePusher 用于 Web 推流。 index.html页面的body 部分引入TXLivePusher js脚本。

         需要获取摄像头使用权限。推流页面代码:

<template><divid="local_video"ref="local_video"style="width: 100%; height: 500px; display: flex; align-items: center; justify-content: center;background-color: #bababa"></div><div style="display: flex;justify-content: center"><a-space style="margin-top: 30px;padding: 0 20px" size="large"><a-button type="dashed" block preIcon="ant-design:video-camera-outlined" @click="startLive"v-if="liveIng == false">开始直播</a-button><a-button type="primary" danger preIcon="ant-design:minus-circle-filled" @click="stopLive"v-else>停止直播</a-button></a-space></div></template><script lang="ts" setup>
import {ref} from "vue";
import {useMessage} from "@/hooks/web/useMessage";const record = ref<any>();  //传入你的数据
const local_video = ref();
const livePusher = ref<any>();
const {createMessage} = useMessage();
const liveIng = ref<boolean>(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 = truecreateMessage.success("与服务器连接成功,直播推流开始啦!")}if (status == 0) {createMessage.warn("与服务器连接断开,已关闭直播推流!")}},});
}
</script><style lang="less" scoped>
</style>

        参考 TXLivePusher 。

        另一种是OBS工具推流。下载后添加源。

        设置直播推流地址和推流码。

        设置好后点击开始直播。 

        四、播放

        1.web播放,使用腾讯云视立方SDK播放。

        进入视立方控制台申请web端License:

        安装 tcplayer 的 npm 包:

npm install tcplayer.js

        licenseUrl为上述环节申请的。tcplayer播放器拉流WebRTC地址播放。

<template><div class="course-banner-inner"><section class="section-study"><div class="wrapper-player"><div class="player-container"><div class="loki-player-wrapper" id="loki-player-wrapper"><div class="tc_player" id="course-playback-player"style="transform: translate(0px, 0px);"><video id="live-player" width="1200" height="618" preload="auto" playsinlinewebkit-playsinline></video></div></div></div></div></section></div>
</template><script lang="ts" setup>
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<any>();const props = defineProps({form: {type: Object,default: {}},
});watchEffect(() => {if (props.form?.isLive) { //直播课程创建直播播放器createLivePlayer(props.form.webrtcPlayUrl);}
});//创建直播播放器
function createLivePlayer(playUrl) {// live-player 为播放器容器 IDlivePlayer.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();}
});
</script><style scoped></style>

        参考 Tcplayer。

        2.uniapp播放。

       一种方式是<live-player> 标签。<live-player> 是小程序内部用于支持音视频下行(播放)能力的功能标签。开通该标签需要满足规定的类目,详见live-player。

        另一种是小程序端和app端都使用video标签播放。在前面获取到的播放地址中已经生成了HLS播放地址。

<template><view class="player-content"><video id="live-player" ref="livePlayer" :src="playUrl" autoplay controls class="live-player"  @error="handleError"></video></view>
</template><script>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: "获取直播推流失败"})},}}
</script><style lang="scss" scoped>.player-content {position: relative;width: 750rpx;height: 450rpx;display: flex;background-size: 100% 100%;.live-player {width: 100%;height: 100%;position: relative;}}
</style>

        需要注意的是生成的HLS播放地址是http的,小程序支持https。所以需要转换下,然后通过nginx代理播放直播流。

        五、效果

        1.web端:

                ​​​​​​​        ​​​​​​​        

        2.uniapp端:

        ​​​​​​​

http://www.lryc.cn/news/571555.html

相关文章:

  • 胰腺癌耐药机制新发现:超级增强子如何调控吉西他滨敏感性
  • 【Linux】基于单例模式的线程池设计
  • 构建智能问答系统:从零开始实现 RAG 应用
  • MySQL常用函数详解之流程函数
  • 逆向入门(12)程序逆向篇-Acid burn
  • Docker Compose部署Spring Cloud 微服务系统
  • CppCon 2016 学习:On using singletons in C++
  • 14.2 《3小时从零搭建企业级LLaMA3语言助手:GitHub配置+私有化模型集成全实战》
  • Uniapp性能优化全面指南:从原理到实践
  • 从0开始学习R语言--Day26--因果推断
  • 4. 时间序列预测的自回归和自动方法
  • Docker学习笔记:数据卷
  • 秋招是开发算法一起准备,还是只准备一个
  • 【CUDA编程】OptionalCUDAGuard详解
  • 【6G技术探索】MCP协议整理分享
  • 6.IK分词器拓展词库
  • # 我使用过的 HTML + CSS 实践总结笔记(含说明)
  • 设计模式笔记_创建型_工厂模式
  • 九日集训第六天
  • 【AI News | 20250617】每日AI进展
  • Tomcat本地部署Maven Java Web项目
  • 从C++编程入手设计模式——策略设计模式
  • uniapp 对接deepseek
  • 手术麻醉系统源码 手麻系统源码 Java手术室管理系统源码
  • 2025年渗透测试面试题总结-红队攻防工程师(题目+回答)
  • 缓存系统-基本概述
  • Ajax 核心知识点全面总结
  • 前端开发面试题总结-vue2框架篇(三)
  • 网络层协议 IP 协议介绍 -- IP 协议,网段划分,私有 IP 和 公网 IP,路由
  • KingbaseES 在线体验平台深度评测