uniapp小程序对接腾讯云直播
相关教程贴:https://cloud.tencent.com/document/product/269/44527
demo下载贴:https://cloud.tencent.com/document/product/269/36887#TLS
小程序后台配置贴:https://web.sdk.qcloud.com/im/doc/zh-cn/tutorial-02-upgradeguideline.html
推流的话可以关注 "腾讯视频云" ,这里的是拉流
成品:
该教程仅适用于微信小程序!!!
1、项目开始,根目录新建components文件夹(如果已经有了,可以忽略这步)
2、导入组件
3、vue页面
XML/HTML Code复制内容到剪贴板
- <template>
- <gui-page :customHeader="false" statusBarStyle="background-color:rgba(1,1,1,0)"
- headerStyle="background-color:rgba(1,1,1,0)" :headerSets="headerSets">
- <!-- 自定义头部导航 -->
- <!-- <view slot="gHeader"></view> -->
- <!-- 页面主体 -->
- <view slot="gBody">
- <view class="live-room-bg" :style="'height: '+mainHeight+'px'">
- <view class="live-room-content">
- <!-- 头部 start -->
- <room-header :userInfo="userInfo" @attention="attention" @cancel-attention="cancelAttention"
- :groupinfo="groupInfo" :ownerInfo="ownerInfo" @show-user-card="showUserCard" @coupon="coupon"
- @show-introduction="showIntroduction" @show-online-user="showOnlineUser"></room-header>
- <!-- 头部 end -->
- <!-- 聊天室 start -->
- <chatroom class="chatroom" :message="messageQueen"></chatroom>
- <!-- 聊天室 end -->
- <!-- 底部 -->
- <room-bottom class="live-room-bottom" @send-message="sendMessage" :isTimReady="isTimReady"
- @quitGroup="quitGroup" @like="like" @showGift="showGift" @showgoods="showgoods"></room-bottom>
- <!-- 底部 -->
- <!-- 礼物面板 start -->
- <gifts class="gifts" :animation="animation" @hideGift="hideGift" @sendgift="sendgift"></gifts>
- <!-- 礼物面板 end -->
- <!-- 商品面板 start -->
- <goods-list class="goodslist" :animation="animation2" @hidegoods="hidegoods" @buy="buy" :goods="goods"></goods-list>
- <!-- 商品面板 end -->
- <!-- 礼物以及动画 start -->
- <gift-animation v-if="hasgift" class="gift-animation" :avatar="giftAvatar" :nick="giftNick" @hideani="hideani"></gift-animation>
- <!-- 礼物以及动画 end -->
- </view>
- <!-- #ifdef MP-WEIXIN -->
- <!-- 直播拉流 -->
- <!-- https://uniapp.dcloud.io/component/live-player -->
- <live-player v-if="roomStatus!=='0'"
- src="rtmp://lvwu.play.liqinwl.com/live/lvwulivestream"
- mode="RTC" autoplay @statechange="statechange" @error="error"
- :style="'width:100%;height: '+mainHeight+'px'" beauty="9" object-fit="fillCrop"
- whiteness="9" />
- <!-- #endif -->
- </view>
- </view>
- </gui-page>
- </template>
- <script>
- // https://console.cloud.tencent.com/ 后台域名管理配置
- import { getHeight } from '@/GraceUI5/js/system.js'
- import roomHeader from '@/components/look/room/room-header.vue'
- import roomBottom from '@/components/look/room/room-bottom.vue'
- import chatroom from '@/components/look/room/chatroom.vue'
- import gifts from '@/components/look/room/gifts.vue'
- import giftAnimation from '@/components/look/room/gift-animation.vue'
- import goodsList from '@/components/look/room/goods-list.vue'
- import TLS from 'im-live-sells'
- // #ifdef H5
- // Web 环境
- import TIM from 'tim-js-sdk'
- // #endif
- // #ifdef MP-WEIXIN
- // 小程序环境
- import TIM from 'tim-wx-sdk'
- // #endif
- export default {
- components: {
- roomHeader,
- roomBottom,
- chatroom,
- gifts,
- giftAnimation,
- goodsList
- },
- data() {
- return {
- headerSets: {
- height: 0,
- zIndex: 100
- },
- initConfig:{
- SDKAppID: 1400568042,
- userSig: 'eJwtzMEOgjAQRdF-6dqQaa0FSdxjaNQIC12incpINKSAVoz-LgGW77zkflmus*CFjsVMBMAW4yaDz5Ysjdw16Ph8NKYq6poMi7kEWKkIpJielh44qFpCqADEelL0NbnBFcgIYG7Qbag6H3Y*0Tnct6o4Xc*47w89dll52VWJtSbVx6b9WF6m7w37-QHY7DI3',
- userName: 'user1',
- },
- mainHeight: 0,
- tls: null,
- roomId: '@TGS#aHTCDBNHL',
- userInfo: {},
- groupInfo: {},
- ownerInfo: {},
- roomStatus: '0',
- isTimReady: false,
- message: [], // 通知
- animation: null, // 礼物面板的动画
- animation2: null, // 商品面板的动画
- hasgift: false, // 是否有礼物
- giftAvatar: '', // 礼物的图像
- giftNick: '', // 礼物的名称
- goods: [], // 商品列表
- }
- },
- computed: {
- messageQueen: function() {
- const queenLen = 100 //内存里面放100条消息,以免观看直播太久撑爆内存
- if (this.message.length > queenLen) {
- const vl = this.message.length - queenLen
- for (let i = 0; i < vl; i++) {
- this.message.shift()
- }
- }
- return this.message
- }
- },
- async onLoad(data) {
- console.log(data)
- try {
- this.roomId = data.roomId
- this.roomStatus = data.roomStatus
- await this.auth() // 获取用户信息
- // this.getUserSig() // 获取生成码
- console.log('roomStatus', this.roomStatus)
- this.init()
- } catch (e) {
- console.warn(e)
- }
- },
- methods: {
- statechange(e) {
- console.log('live-player code:', e.detail.code)
- },
- error(e) {
- console.error('live-player error:', e.detail.errMsg)
- },
- init: function(e) {
- this.$nextTick(e => {
- const height = getHeight('window');
- this.mainHeight = height;
- console.log('高度', this.mainHeight)
- })
- // 初始化
- this.tls = new TLS({
- SDKAppID: this.initConfig.SDKAppID,
- roomID: this.roomId,
- userSig: this.initConfig.userSig,
- userName: this.initConfig.userName,
- TIM: TIM
- })
- this.tls.on(TLS.EVENT.SDK_READY, async () => {
- console.log('SDK 已经初始化好了', Math.random())
- this.isTimReady = true
- //sdk可用了
- // 调用加入房间(joinRoom)的API
- let {
- groupInfo,
- userInfo
- } = await this.tls.joinRoom({
- roomID: this.roomId,
- getOwnerInfo: true
- })
- console.log("userinfo", userInfo)
- // mock数据,上线前删除
- userInfo = {
- "avatar": "/static/live/7.png",
- "nick": "1111"
- }
- groupInfo = {
- "groupID": this.roomId,
- "memberNum": 1990,
- "notification": "欢迎新人入直播间"
- }
- // mock数据,上线前删除 end
- this.userInfo = userInfo;
- this.groupInfo = groupInfo
- this.ownerInfo = groupInfo.ownerInfo
- this.noticeText = groupInfo.notification
- let goods
- console.log('获取groupInfo', groupInfo)
- // 获取商品的API
- try {
- goods = JSON.parse(this._getVarsByKey(groupInfo.groupCustomField, 'addgoods'))
- } catch (err) {
- goods = []
- }
- // mock数据,上线前删除
- goods = [
- {
- "gid":1,
- "name":"商品测试",
- "price":45
- }
- ]
- // mock数据,上线前删除 end
- this.goods = goods
- if (this.noticeText) {
- let msg = []
- msg.push({
- name: '公告',
- message: this.noticeText,
- id: `id${Date.now()}`,
- type: 2
- })
- thisthis.message = this.message.concat(msg)
- }
- })
- this.tls.on(TLS.EVENT.JOIN_GROUP, async (data) => {
- console.log('已经加入了群聊', data)
- //有人加群
- let msg = []
- msg.push({
- name: this._formatNick(data.userID, data.nick),
- message: '加入了群聊',
- id: `id${Date.now()}`
- })
- thisthis.message = this.message.concat(msg)
- })
- this.tls.on(TLS.EVENT.ERROR, async (data) => {})
- this.tls.on(TLS.EVENT.EXIT_GROUP, async (data) => {
- //有人退群
- let msg = []
- msg.push({
- name: this._formatNick(data.userID, data.nick),
- message: '退出了群聊',
- id: `id${Date.now()}`
- })
- thisthis.message = this.message.concat(msg)
- })
- this.tls.on(TLS.EVENT.NOTIFACATION, async (data) => {
- //有新的公告
- this.noticeText = data.notification
- let msg = []
- msg.push({
- name: '公告',
- message: this.noticeText,
- id: `id${Date.now()}`,
- type: 2
- })
- thisthis.message = this.message.concat(msg)
- })
- // 群名和群资料变更
- this.tls.on(TLS.EVENT.INTRODUCTION, async ({
- name,
- introduction
- }) => {
- const msg = []
- msg.push({
- name: '公告',
- message: '群资料变更,请注意查看',
- id: `id${Date.now()}`,
- type: 2
- })
- thisthis.message = this.message.concat(msg)
- this.groupInfo = Object.assign(this.groupInfo, {
- name,
- introduction
- })
- })
- this.tls.on(TLS.EVENT.MESSAGE, async (data) => {
- //有人发消息
- let msg = []
- msg.push({
- name: this._formatNick(data.userID, data.nick),
- message: data.message,
- id: `id${Date.now()}`
- })
- thisthis.message = this.message.concat(msg)
- })
- this.tls.on(TLS.EVENT.LIKE, async (data) => {
- //有人给主播点赞
- let msg = []
- msg.push({
- name: this._formatNick(data.userID, data.nick),
- message: '给主播点赞了',
- id: `id${Date.now()}`
- })
- thisthis.message = this.message.concat(msg)
- })
- this.tls.on(TLS.EVENT.SEND_GIFT, async (data) => {
- //有人给主播送礼
- let msg = []
- msg.push({
- name: this._formatNick(data.userID, data.nick),
- message: '给主播送礼了',
- id: `id${Date.now()}`
- })
- thisthis.message = this.message.concat(msg)
- this.hasgift = true
- this.giftAvatar = data.avatar
- this.giftNick = data.nick
- })
- this.tls.on(TLS.EVENT.ATTENTION, async (data) => {
- //有人关注了主播
- let msg = []
- msg.push({
- name: this._formatNick(data.userID, data.nick),
- message: '关注了主播',
- id: `id${Date.now()}`
- })
- thisthis.message = this.message.concat(msg)
- this.$store.dispatch({
- type: ADD_FOLLOWER
- })
- // const a = await this.tls.getUserInfo()
- })
- this.tls.on(TLS.EVENT.CANCELATTENTION, async (data) => {
- //有人关注了主播
- let msg = []
- msg.push({
- name: this._formatNick(data.userID, data.nick),
- message: '取消关注关注了主播',
- id: `id${Date.now()}`
- })
- thisthis.message = this.message.concat(msg)
- this.$store.dispatch({
- type: REDUCE_FOLLOWER
- })
- // const a = await this.tls.getUserInfo()
- })
- this.tls.on(TLS.EVENT.BUY_GOODS, async (data) => {
- //有人购买了商品
- let msg = []
- msg.push({
- name: this._formatNick(data.userID, data.nick),
- message: `购买了商品(${JSON.parse(data.value).name})`,
- id: `id${Date.now()}`
- })
- thisthis.message = this.message.concat(msg)
- })
- this.tls.on(TLS.EVENT.USE_COUPON, async (data) => {
- //有人领了优惠券
- let msg = []
- msg.push({
- name: this._formatNick(data.userID, data.nick),
- message: '领取了优惠券',
- id: `id${Date.now()}`
- })
- thisthis.message = this.message.concat(msg)
- })
- this.tls.on(TLS.EVENT.ADD_GOODS, async (data) => {
- //该场直播推荐商品有变更
- wx.showToast({
- title: '有新的商品上架'
- })
- let goods
- try {
- goods = JSON.parse(data.value)
- } catch (err) {
- goods = []
- }
- this.goods = goods
- })
- this.tls.on(TLS.EVENT.KICKED, async () => {
- //被踢下线
- })
- this.tls.on(TLS.EVENT.NETWORK_CHANGE, async () => {
- //网络变化
- })
- this.tls.on(TLS.EVENT.SDK_NOT_READY, async () => {
- //sdk不可用
- })
- this.tls.on(TLS.EVENT.PROFILE_UPDATE, async () => {
- //用户资料发生改变
- })
- this.tls.on(TLS.EVENT.ERROR, async () => {
- //sdk发生错误
- })
- },
- hidecoupon() {
- this.hascoupon = false
- setTimeout(() => {
- if (this.couponStack.shift()) {
- this.hascoupon = true
- }
- }, 1000)
- },
- usecoupon() {
- this.tls.useCoupon().then((data) => {
- this.hidecoupon()
- })
- },
- coupon() {
- this.hascoupon = true
- },
- _formatNick(userID, nick) {
- console.log('userID', userID)
- console.log('nick', nick)
- if (userID === this.userInfo.userID) {
- return '我'
- }
- return nick
- },
- buy(data) {
- wx.showLoading()
- this.tls.buy(data).then(() => {
- wx.hideLoading()
- this.hidegoods()
- })
- },
- hideani() {
- this.hasgift = false,
- this.giftAvatar = '',
- this.giftNick = ''
- setTimeout(() => {
- var msg = this.giftStack.shift()
- if (msg) {
- this.hasgift = true,
- this.giftAvatar = msg.giftAvatar,
- this.giftNick = msg.giftNick
- }
- }, 1000)
- },
- showgoods() {
- const ani = wx.createAnimation({
- duration: 200
- })
- ani.bottom(0).step()
- this.animation2 = ani.export()
- },
- hidegoods() {
- const ani = wx.createAnimation({
- duration: 200
- })
- ani.bottom('-45vh').step()
- this.animation2 = ani.export()
- },
- showGift() {
- const ani = wx.createAnimation({
- duration: 200
- })
- ani.bottom(0).step()
- this.animation = ani.export()
- },
- showIntroduction() {
- const ani = wx.createAnimation({
- duration: 200
- })
- ani.bottom(0).step()
- this.animation3 = ani.export()
- },
- hideIntroductione() {
- const ani = wx.createAnimation({
- duration: 200
- })
- ani.bottom('-45vh').step()
- this.animation3 = ani.export()
- },
- showOnlineUser() {
- this.isShowOnlineUser = true
- setTimeout(() => {
- const ani = wx.createAnimation({
- duration: 200
- })
- ani.bottom(0).step()
- this.animation4 = ani.export()
- }, 0)
- },
- hideOnlineUser() {
- const duration = 200
- const ani = wx.createAnimation({
- duration
- })
- ani.bottom('-45vh').step()
- this.animation4 = ani.export()
- setTimeout(() => {
- this.isShowOnlineUser = false
- }, duration)
- },
- showUserCard({
- user_id
- }) {
- this.isShowUserCard = true
- this.userCardId = user_id
- setTimeout(() => {
- const ani = wx.createAnimation({
- duration: 200
- })
- ani.bottom(0).step()
- this.animationUserCard = ani.export()
- }, 0)
- },
- hideUserCard() {
- const duration = 200
- const ani = wx.createAnimation({
- duration
- })
- ani.bottom('-45vh').step()
- this.animationUserCard = ani.export()
- setTimeout(() => {
- this.isShowUserCard = false
- }, duration)
- },
- sendgift() {
- uni.showModal({
- title: '提示',
- content: '确认送礼?',
- success: async (data) => {
- try {
- if (data.confirm) {
- await Model.sendGift({
- from_id: this.userInfo.userID,
- to_id: this.groupInfo.ownerID,
- gift_id: 1
- })
- this.tls.sendGift('礼物')
- }
- } catch (e) {
- console.log("送礼物的回调", e)
- // uni.showToast({
- // title: e.message
- // })
- // mock数据,上线前删除 模拟送礼动画
- let msg = []
- msg.push({
- name: this._formatNick(this.userInfo.userID, this.userInfo.nick),
- message: '给主播送礼了',
- id: `id${Date.now()}`
- })
- thisthis.message = this.message.concat(msg)
- this.hasgift = true
- this.giftAvatar = '/static/live/gift-item.png'
- this.giftNick = '火箭'
- // mock数据,上线前删除 模拟结束
- } finally {
- this.hideGift();
- }
- }
- })
- },
- hideGift() {
- const ani = wx.createAnimation({
- duration: 200
- })
- ani.bottom('-45vh').step()
- this.animation = ani.export()
- },
- async like() {
- console.log('喜欢的动作')
- // 这里需要接入API
- // try {
- // await Model.like({
- // from_id: this.userInfo.userID,
- // to_id: this.groupInfo.ownerID
- // })
- // this.tls.like()
- // } catch (e) {
- // uni.showToast({
- // title: e.message
- // })
- // }
- },
- attention() {
- wx.showLoading()
- this.tls.attention().then((data) => {
- wx.hideLoading()
- }).catch(() => {
- wx.hideLoading()
- })
- },
- cancelAttention() {
- wx.showLoading()
- this.tls.cancelAttention().then((data) => {
- wx.hideLoading()
- }).catch(() => {
- wx.hideLoading()
- })
- },
- quitGroup() {
- wx.showLoading({
- mask: true
- })
- this.tls.exitRoom().then(() => {
- wx.hideLoading()
- wx.navigateBack()
- this.isTimReady = false
- }).catch((err) => {
- wx.navigateBack()
- })
- },
- _getVarsByKey(arr, key) {
- var res
- for (var i = 0; i < arr.length; i++) {
- if (arr[i].key === key) {
- res = arr[i].value;
- break;
- }
- }
- return res
- },
- sendMessage(data) {
- console.log("有人发消息", data)
- this.tls.sendMessage(data).then((res) => {
- thisthis.message = this.message.concat([{
- name: this._formatNick(this.userInfo.userID, this.userInfo.nick),
- message: res.message,
- id: `id${Date.now()}`
- }])
- })
- },
- // getUserSig() {
- // wx.request({
- // url: `${CONST.HOST}/getUserSig`,
- // method: 'GET',
- // header: {
- // "content-type": "application/x-www-form-urlencoded"
- // },
- // data: {
- // userId: app.userData.id
- // },
- // success: (data) => {
- // this.userSig = data.data.userSig
- // this.initTimLiveSell()
- // },
- // fail() {}
- // })
- // },
- // TODO:临时加入,为了能直接进入直播间
- async auth() {
- let userId = parseInt(Math.random() * 1000);
- userId = "user"+userId
- console.log("userName", userId)
- let res = await this.$store.dispatch("user/sign",{user_id:userId})
- // console.log("请求结果", res)
- this.initConfig.userName = userId
- this.initConfig.userSig = res.usersig
- }
- },
- }
- </script>
- <style lang="less" scoped>
- .live{
- &-room-bg {
- width: 100vw;
- overflow: hidden;
- position: relative;
- }
- &-room-content {
- height: 100vh;
- width: 100vw;
- position: absolute;
- top: 0;
- left: 0;
- z-index: 2;
- // 礼物
- .gifts,
- .goodslist,
- .introduction,
- .online-user,
- .user-card {
- position: absolute;
- width: 100vw;
- height: 45vh;
- background-color: #fff;
- bottom: -45vh;
- z-index: 800;
- left: 0;
- }
- .user-card {
- background-color: unset;
- }
- .gift-animation {
- // 送礼的动画,显示在左下角
- position: absolute;
- bottom: 30vh;
- left: 20rpx;
- }
- .coupon {
- margin-top: 400rpx;
- }
- }
- &-room-bottom {
- position: absolute;
- bottom: 0;
- width: 100vw;
- height: 50px;
- }
- }
- </style>
上一篇 仿知乎叠加卡片动画切换效果
下一篇 小程序-微信登录