En route hai 1 ano
pai
achega
9ff300e871
Modificáronse 3 ficheiros con 1208 adicións e 156 borrados
  1. 166 156
      pages/live/index.vue
  2. 566 0
      pages/live/index2.vue
  3. 476 0
      pages/live/index9.vue

+ 166 - 156
pages/live/index.vue

@@ -38,6 +38,7 @@
 			return {
 				signModal: false,
 				signSuccess: false,
+				// playerJs: "https://player.polyv.net/resp/live-h5-player/latest/liveplayer.min.js",
 				playerJs: "https://player.polyv.net/livesdk/polyv-live.min.js",
 				chatroomJs: "https://player.polyv.net/jssdk/polyv-chatroom.min.js",
 				uidzb: "egsxlptzdq",
@@ -232,174 +233,183 @@
 			},
 
 			loadPlayerzb() {
-				var els = {
-					playerEl: '', // 播放器容器选择器, 移动端和PC的el参数设置不
-					pptEl: '', // 文档容器选择器, 普通直播不需要设置pptEl
-					controllerEl: '', // 三分屏控制栏的容器选择器, pc三分屏的场景才需要设置controllerEl,
-					chatContainer: '', // 聊天室的容器选择器
-					pptEl: '#tab-ppt'
-				};
-
-				$('.plv-watch-mobile').css('display', '');
-				els.playerEl = '#plv-mobile-player'; // 讲师区域元素
-				els.chatContainer = '#plv-mobile-chat'; // DOM选择器,HTML元素,用于渲染聊天室
-				els.pptEl = '#tab-ppt'; // ppt文档元素选择器,非云课堂可不填
-				var chatroom = new PolyvChatRoom({
-					//实例聊天室SDK
-					roomId: this.channelId,
-					userId: this.userInfo.userAccount,
-					nick: this.userInfo.realname,
-					accountId: this.userInfo.userAccount,
-					pic: this.$method.splitImgHost(this.userInfo.avatar, true) ||
-						"http://livestatic.videocc.net/assets/wimages/missing_face.png",
-					container: els.chatContainer,
-					userType: "slice",
-					version: "2.0",
-					showUserList: false,
-					width: '100%',
-					height: '100%',
-					token: this.token,
-					enableWelcome: true, // 是否开启欢迎语,默认为true
-					enableFlower: true, // 是否开启送花功能,默认为true
-					mediaChannelKey: this.mediaChannelKey,
-					tabData: [{
-							name: "文档",
-							type: "ppt",
-						},
-						{
-							name: "聊天", // 菜单栏名称
-							type: "chat", // 菜单栏类型, 有3个已有的内置类型(chat, user-list, ask),详情请参考文档
-						},
-						{
-							name: "提问",
-							type: "ask",
-						}
-					],
-					roomMessage: (data) => {
-						console.log(data, 'data')
-						// data为聊天室socket消息,当有聊天室消息时会触发此方法
-						if (this.liveSdk && this.liveSdk.player) {
-							var event = data.EVENT;
-							if (event === 'sendMessage' || event === 'SPEAK') {
-								this.liveSdk.player.sendBarrage(data.content);
-							}
-						}
-					},
-					customChatColor: {
-						selfBgColor: '#2b2c35',
-						selfColor: '#fff',
-						otherBgColor: '#2b2c35',
-						otherColor: '#fff',
-						specialBgColor: '#2b2c35',
-						specialColor: '#fff'
-					}
-				});
-				this.plv.socket = chatroom.chat.socket;
-				console.log(chatroom.chat.socket)
-				this.plv.liveSdk = new PolyvLiveSdk({
-					//实例直播SDK
-					channelId: this.channelId,
-					appId: this.appId,
-					sign: this.sign,
-					timestamp: this.timestamp,
-					socket: chatroom.chat.socket, //传入聊天室的socket
-					user: {
+				try {
+					var els = {
+						playerEl: '', // 播放器容器选择器, 移动端和PC的el参数设置不
+						pptEl: '', // 文档容器选择器, 普通直播不需要设置pptEl
+						controllerEl: '', // 三分屏控制栏的容器选择器, pc三分屏的场景才需要设置controllerEl,
+						chatContainer: '', // 聊天室的容器选择器
+						pptEl: '#tab-ppt'
+					};
+
+					$('.plv-watch-mobile').css('display', '');
+					els.playerEl = '#plv-mobile-player'; // 讲师区域元素
+					els.chatContainer = '#plv-mobile-chat'; // DOM选择器,HTML元素,用于渲染聊天室
+					els.pptEl = '#tab-ppt'; // ppt文档元素选择器,非云课堂可不填
+					var chatroom = new PolyvChatRoom({
+						//实例聊天室SDK
+						roomId: this.channelId,
 						userId: this.userInfo.userAccount,
-						userName: this.userInfo.realname,
+						nick: this.userInfo.realname,
+						accountId: this.userInfo.userAccount,
 						pic: this.$method.splitImgHost(this.userInfo.avatar, true) ||
 							"http://livestatic.videocc.net/assets/wimages/missing_face.png",
-					},
-				});
-
-				// 监听流状态变化刷新播放器
-				this.plv.liveSdk.on(PolyvLiveSdk.EVENTS.STREAM_UPDATE, (event, status) => {
-					console.log(status, 'STREAM_UPDATE')
-					if (status == 'end') {
-						clearInterval(this.timer)
-						let duraing = this.playTime - this.duraing;
-						this.duraing = 0;
-						this.isEnd = true;
-						this.studyRecord(1, duraing)
-					}
-				}); // 监听流状态变化
-
-
-				// 第四步:监听频道信息读取完成事件,初始化播放器
-				let options = {
-					pptEl: els.pptEl,
-					el: els.playerEl,
-					switchPlayer: true,
-					controllerPosition: "ppt",
-					pptNavBottom: "180px",
-					controllerPosition: "player",
-					fixedController: true,
-					barrage: true,
-					defaultBarrageStatus: true,
-					controllerEl: els.controllerEl,
-					autoplay: true, // 设置自动播放
-				}
-				if (this.sectionType == 3) {
-					// 回放模式需要fileId、url、sessionId
-					// fileId: undefined, //ppt数据id,回放模式必填
-					// url: undefined,  // 回放视频链接,回放模式必填
-					// sessionId: undefined, // 回放场次id,回放模式必填
-					// vid: undefined,  // 回放id,回放模式下传入该参数,可不传fileId、url、sessionId
-					options.type = 'vod',
-						options.vid = this.vid
-				}
-				console.log('options', options)
-				this.plv.liveSdk.on(PolyvLiveSdk.EVENTS.CHANNEL_DATA_INIT, (event, data) => {
-					this.plv.liveSdk.setupPlayer(options);
-
-					this.plv.liveSdk.player.on("switchPlayer", () => {
-						this.changeState = !this.changeState;
-						if (this.changeState) {
-							this.plv.liveSdk.player.setFullscreenEl(this.$refs.ppt);
-						} else {
-							this.plv.liveSdk.player.setFullscreenEl(this.$refs.player);
+						container: els.chatContainer,
+						userType: "slice",
+						version: "2.0",
+						showUserList: false,
+						width: '100%',
+						height: '100%',
+						token: this.token,
+						enableWelcome: true, // 是否开启欢迎语,默认为true
+						enableFlower: true, // 是否开启送花功能,默认为true
+						mediaChannelKey: this.mediaChannelKey,
+						tabData: [{
+								name: "文档",
+								type: "ppt",
+							},
+							{
+								name: "聊天", // 菜单栏名称
+								type: "chat", // 菜单栏类型, 有3个已有的内置类型(chat, user-list, ask),详情请参考文档
+							},
+							{
+								name: "提问",
+								type: "ask",
+							}
+						],
+						roomMessage: (data) => {
+							console.log(data, 'data')
+							// data为聊天室socket消息,当有聊天室消息时会触发此方法
+							if (this.liveSdk && this.liveSdk.player) {
+								var event = data.EVENT;
+								if (event === 'sendMessage' || event === 'SPEAK') {
+									this.liveSdk.player.sendBarrage(data.content);
+								}
+							}
+						},
+						customChatColor: {
+							selfBgColor: '#2b2c35',
+							selfColor: '#fff',
+							otherBgColor: '#2b2c35',
+							otherColor: '#fff',
+							specialBgColor: '#2b2c35',
+							specialColor: '#fff'
 						}
 					});
-
-					this.plv.liveSdk.player.on("switchMainScreen", (main) => {
-						console.log("切换主讲位置,当前主屏为", main); // 'player'|'ppt'
+					this.plv.socket = chatroom.chat.socket;
+					console.log(chatroom.chat.socket)
+					this.plv.liveSdk = new PolyvLiveSdk({
+						//实例直播SDK
+						channelId: this.channelId,
+						appId: this.appId,
+						sign: this.sign,
+						timestamp: this.timestamp,
+						socket: chatroom.chat.socket, //传入聊天室的socket
+						user: {
+							userId: this.userInfo.userAccount,
+							userName: this.userInfo.realname,
+							pic: this.$method.splitImgHost(this.userInfo.avatar, true) ||
+								"http://livestatic.videocc.net/assets/wimages/missing_face.png",
+						},
 					});
 
-					// this.plv.liveSdk.player.on("ended", (state) => {
-					// 	console.log(state,'ended')
-					// 	clearInterval(this.timer)
-					// 	let duraing = this.playTime - this.duraing;
-					// 	this.duraing = 0;
-					// 	this.studyRecord(1,duraing)
-					// })
-
-					this.plv.liveSdk.player.on("pause", (state) => {
-						console.log(state, 'pause')
-						let duraing = this.playTime - this.duraing;
-						this.duraing = 0;
-						if (!this.isEnd) {
-							this.studyRecord(0, duraing)
+					// 监听流状态变化刷新播放器
+					this.plv.liveSdk.on(PolyvLiveSdk.EVENTS.STREAM_UPDATE, (event, status) => {
+						console.log(status, 'STREAM_UPDATE')
+						if (status == 'end') {
+							clearInterval(this.timer)
+							let duraing = this.playTime - this.duraing;
+							this.duraing = 0;
+							this.isEnd = true;
+							this.studyRecord(1, duraing)
 						}
+					}); // 监听流状态变化
+
+
+					// 第四步:监听频道信息读取完成事件,初始化播放器
+					let options = {
+						pptEl: els.pptEl,
+						el: els.playerEl,
+						switchPlayer: true,
+						controllerPosition: "ppt",
+						pptNavBottom: "180px",
+						controllerPosition: "player",
+						fixedController: true,
+						barrage: true,
+						defaultBarrageStatus: true,
+						controllerEl: els.controllerEl,
+						autoplay: true, // 设置自动播放
+					}
+					if (this.sectionType == 3) {
+						// 回放模式需要fileId、url、sessionId
+						// fileId: undefined, //ppt数据id,回放模式必填
+						// url: undefined,  // 回放视频链接,回放模式必填
+						// sessionId: undefined, // 回放场次id,回放模式必填
+						// vid: undefined,  // 回放id,回放模式下传入该参数,可不传fileId、url、sessionId
+						options.type = 'vod',
+							options.vid = this.vid
+					}
+					console.log('options', options)
+					this.plv.liveSdk.on(PolyvLiveSdk.EVENTS.CHANNEL_DATA_INIT, (event, data) => {
+						this.plv.liveSdk.setupPlayer(options);
+
+						this.plv.liveSdk.player.on("switchPlayer", () => {
+							this.changeState = !this.changeState;
+							if (this.changeState) {
+								this.plv.liveSdk.player.setFullscreenEl(this.$refs.ppt);
+							} else {
+								this.plv.liveSdk.player.setFullscreenEl(this.$refs.player);
+							}
+						});
+
+						this.plv.liveSdk.player.on("switchMainScreen", (main) => {
+							console.log("切换主讲位置,当前主屏为", main); // 'player'|'ppt'
+						});
+
+						// this.plv.liveSdk.player.on("ended", (state) => {
+						// 	console.log(state,'ended')
+						// 	clearInterval(this.timer)
+						// 	let duraing = this.playTime - this.duraing;
+						// 	this.duraing = 0;
+						// 	this.studyRecord(1,duraing)
+						// })
+
+						this.plv.liveSdk.player.on("pause", (state) => {
+							console.log(state, 'pause')
+							let duraing = this.playTime - this.duraing;
+							this.duraing = 0;
+							if (!this.isEnd) {
+								this.studyRecord(0, duraing)
+							}
 
-						clearInterval(this.timer)
-					})
+							clearInterval(this.timer)
+						})
 
-					this.plv.liveSdk.player.on("loadedmetadata", (state) => {
-						if (this.isFirst) {
-							this.studyRecord(0, 0)
-							this.isFirst = false;
-						}
-						this.isEnd = false;
-						clearInterval(this.timer)
-						this.timer = setInterval(() => {
-							this.studyRecord(0, 20)
-							this.duraing += 20;
-						}, 20000)
-					})
+						this.plv.liveSdk.player.on("loadedmetadata", (state) => {
+							if (this.isFirst) {
+								this.studyRecord(0, 0)
+								this.isFirst = false;
+							}
+							this.isEnd = false;
+							clearInterval(this.timer)
+							this.timer = setInterval(() => {
+								this.studyRecord(0, 20)
+								this.duraing += 20;
+							}, 20000)
+						})
+
+						this.plv.liveSdk.player.on("timeupdate", (time) => {
+							this.playTime = time;
+						})
+					});
 
-					this.plv.liveSdk.player.on("timeupdate", (time) => {
-						this.playTime = time;
+				} catch (e) {
+					uni.showToast({
+						title: '提示:' + e
 					})
-				});
+					console.error(e, ':报错')
+					//TODO handle the exception
+				}
 			},
 			/**
 			 * @param {String} 直播js加载

+ 566 - 0
pages/live/index2.vue

@@ -0,0 +1,566 @@
+<template>
+	<div class="living-room">
+		<div class="container">
+			<div class="plv-watch-mobile">
+				<div class="plv-watch-mobile__top">
+					<div class="plv-watch-mobile-player" id="plv-mobile-player"></div>
+				</div>
+				<div class="plv-watch-mobile-chatroom plv-skin--dark" id="plv-mobile-chat"></div>
+			</div>
+		</div>
+
+		<div class="sign-modal" v-if="signModal">
+			<div class="sign-modal__content">
+				<img class="img" src="@/static/sign-img.png" alt="">
+				<div class="box">
+					<div class="title">直播已经开始啦,赶紧签到进入直播吧!</div>
+					<div class="btn" @click="close">立即签到</div>
+				</div>
+			</div>
+		</div>
+
+		<div class="sign-success" v-if="signSuccess">
+			<div class="sign-success__content">
+				<img class="img" src="@/static/sign-success.png" alt="">
+				<div class="title">签到成功!</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+	import "@/static/chatroom.css";
+	import "@/static/mobile.css";
+	import "@/static/tool.css";
+	import "@/static/public.css";
+	export default {
+		data() {
+			return {
+				signModal: false,
+				signSuccess: false,
+				playerJs: "https://player.polyv.net/resp/live-h5-player/latest/liveplayer.min.js",
+				// playerJs: "https://player.polyv.net/livesdk/polyv-live.min.js",
+				chatroomJs: "https://player.polyv.net/jssdk/polyv-chatroom.min.js",
+				uidzb: "egsxlptzdq",
+				channelId: "",
+				appId: "",
+				sign: "",
+				timestamp: "",
+				mediaChannelKey: "",
+				changeState: false,
+				liveSdk: null,
+				userInfo: {},
+				token: '',
+				sectionId: 0,
+				goodsId: 0,
+				courseId: 0,
+				orderGoodsId: 0,
+				gradeId: 0,
+				chapterId: 0,
+				moduleId: 0,
+				playTime: 0,
+				duraing: 0,
+				timer: null,
+				isFirst: true,
+				isEnd: false,
+				plv: {
+					liveSdk: null, // 保存直播 JS-SDK 实例
+					socket: null, // 保存 WebSocket 实例
+					scene: "", // 场景
+					mainPosition: "player", // 用于记录当前主屏幕是文档还是播放器
+				},
+				buyCourse: 1, // 是否购买课程:1是 0否
+				identification: '', // 标识
+				sectionType: 2, // 节类型 1录播 2直播 3回放	
+				vid: '', // 回放的id
+			}
+		},
+		async mounted() {
+			console.log('直播间参数', this.$route.query)
+			const {
+				buyCourse,
+				ident,
+				sectionType,
+				vid
+			} = this.$route.query
+			console.log('sectionType:', sectionType, vid)
+			this.buyCourse = buyCourse
+			this.identification = ident
+			this.sectionType = sectionType || 2
+			this.vid = vid || ''
+			this.sectionId = this.$route.query.sectionId;
+			this.goodsId = this.$route.query.goodsId;
+			this.courseId = this.$route.query.courseId;
+			this.orderGoodsId = this.$route.query.orderGoodsId;
+			this.gradeId = +this.$route.query.gradeId;
+			this.chapterId = this.$route.query.chapterId;
+			this.moduleId = this.$route.query.moduleId;
+			this.channelId = this.$route.query.channelId;
+			if (this.$route.query.tid) {
+				await this.setStorageAwait('tid', this.$route.query.tid)
+			}
+			this.userInfo = this.$route.query.userInfo && this.$route.query.userInfo !== 'null' ? JSON.parse(this
+				.$route
+				.query.userInfo) : {
+				userAccount: parseInt(Math.random() * 100000),
+				realname: '匿名' + parseInt(Math.random() * 100000)
+			}
+			let token = this.$route.query.token;
+
+
+			if (token) {
+				uni.setStorageSync('token', token)
+			}
+			this.playVideo();
+			if (this.sectionId && this.sectionType != 3) {
+				this.studyRecordGetLastLive();
+			}
+
+		},
+		methods: {
+			setStorageAwait() {
+				return new Promise(resolve => {
+					uni.setStorage({
+						key: 'tid',
+						data: this.$route.query.tid,
+						success: function() {
+							resolve()
+						}
+					});
+				})
+			},
+			close() {
+				this.signModal = false;
+				this.signSuccess = true;
+				setTimeout(() => {
+					this.signSuccess = false;
+				}, 1000)
+			},
+			/**
+			 * 获取上次观看的直播
+			 */
+			studyRecordGetLastLive() {
+				if (!this.gradeId) {
+					this.$http({
+						url: '/study/record/queryLiveLast',
+						data: {
+							orderGoodsId: this.orderGoodsId,
+							courseId: this.courseId,
+						}
+					}).then(res => {
+						if (res.data.code == 200) {
+							if (!res.data.data) {
+								this.signModal = true;
+							}
+						}
+					})
+				}
+			},
+			polyvLivesign() {
+				this.$http({
+					loading: true,
+					url: '/polyv/live/sign',
+					data: {
+						channelId: this.channelId,
+					}
+				}).then(res => {
+					if (res.data.code == 200) {
+						this.sign = res.data.data.sign;
+						this.token = res.data.data.token;
+						this.mediaChannelKey = res.data.data.mediaChannelKey;
+						this.timestamp = res.data.data.timestamp;
+						this.appId = res.data.data.appId;
+
+						this.loadPlayerzb();
+					} else {
+						uni.showToast({
+							title: res.data.msg,
+							icon: 'none'
+						})
+					}
+				}).catch((err) => {})
+			},
+
+			studyRecord(status, duraing) {
+
+				if (!this.sectionId) {
+					return;
+				}
+				let self = this;
+				this.$http({
+					load: false,
+					url: '/study/record',
+					data: {
+						buyCourse: this.buyCourse,
+						identification: this.identification,
+						sectionId: parseInt(this.sectionId),
+						goodsId: parseInt(self.goodsId),
+						courseId: parseInt(self.courseId),
+						orderGoodsId: this.orderGoodsId,
+						studyDuration: parseInt(duraing) || 0,
+						gradeId: parseInt(self.gradeId),
+						chapterId: parseInt(self.chapterId),
+						moduleId: parseInt(self.moduleId),
+						videoCurrentTime: parseInt(
+							2
+						),
+						status: status,
+						fromPlat: 1,
+					},
+					method: 'POST'
+				})
+			},
+
+			async playVideo() {
+				await this.jquery();
+				await this.loadPlayerScriptzb();
+				await this.loadChatroomScriptzb();
+				console.log('this.userInfo', this.userInfo);
+				this.polyvLivesign();
+			},
+
+			jquery() {
+				return new Promise((resolve) => {
+					if (!window.polyvLivePlayer) {
+						const myScript = document.createElement("script");
+						myScript.setAttribute("src", '../../static/jquery.min.js');
+						document.body.appendChild(myScript);
+						myScript.onload = resolve;
+					} else {
+						resolve();
+					}
+				});
+			},
+
+			loadPlayerzb() {
+				try {
+					var els = {
+						playerEl: '', // 播放器容器选择器, 移动端和PC的el参数设置不
+						pptEl: '', // 文档容器选择器, 普通直播不需要设置pptEl
+						controllerEl: '', // 三分屏控制栏的容器选择器, pc三分屏的场景才需要设置controllerEl,
+						chatContainer: '', // 聊天室的容器选择器
+						pptEl: '#tab-ppt'
+					};
+
+					$('.plv-watch-mobile').css('display', '');
+					els.playerEl = '#plv-mobile-player'; // 讲师区域元素
+					els.chatContainer = '#plv-mobile-chat'; // DOM选择器,HTML元素,用于渲染聊天室
+					els.pptEl = '#tab-ppt'; // ppt文档元素选择器,非云课堂可不填
+					var chatroom = new PolyvChatRoom({
+						//实例聊天室SDK
+						roomId: this.channelId,
+						userId: this.userInfo.userAccount,
+						nick: this.userInfo.realname,
+						accountId: this.userInfo.userAccount,
+						pic: this.$method.splitImgHost(this.userInfo.avatar, true) ||
+							"http://livestatic.videocc.net/assets/wimages/missing_face.png",
+						container: els.chatContainer,
+						userType: "slice",
+						version: "2.0",
+						showUserList: false,
+						width: '100%',
+						height: '100%',
+						token: this.token,
+						enableWelcome: true, // 是否开启欢迎语,默认为true
+						enableFlower: true, // 是否开启送花功能,默认为true
+						mediaChannelKey: this.mediaChannelKey,
+						tabData: [{
+								name: "文档",
+								type: "ppt",
+							},
+							{
+								name: "聊天", // 菜单栏名称
+								type: "chat", // 菜单栏类型, 有3个已有的内置类型(chat, user-list, ask),详情请参考文档
+							},
+							{
+								name: "提问",
+								type: "ask",
+							}
+						],
+						roomMessage: (data) => {
+							console.log(data, 'data')
+							// data为聊天室socket消息,当有聊天室消息时会触发此方法
+							if (this.liveSdk && this.liveSdk.player) {
+								var event = data.EVENT;
+								if (event === 'sendMessage' || event === 'SPEAK') {
+									this.liveSdk.player.sendBarrage(data.content);
+								}
+							}
+						},
+						customChatColor: {
+							selfBgColor: '#2b2c35',
+							selfColor: '#fff',
+							otherBgColor: '#2b2c35',
+							otherColor: '#fff',
+							specialBgColor: '#2b2c35',
+							specialColor: '#fff'
+						}
+					});
+					this.plv.socket = chatroom.chat.socket;
+					console.log(chatroom.chat.socket)
+					const polyvLivePlayer = window.polyvLivePlayer;
+					this.plv.liveSdk = polyvLivePlayer({
+						danmuEnable: true,
+						wrap: els.playerEl,
+						width: '100%',
+						height: '100%',
+						isAutoChange: true, // 自动切直播/回放
+						uid: this.uidzb, // 用户id,即开发者信息下的userId(账号ID)
+						vid: this.channelId // 频道id,即频道号
+					});
+
+					// 监听流状态变化刷新播放器
+					this.plv.liveSdk.on('s2j_onApiStatus', (status) => {
+						console.log(status, 'STREAM_UPDATE')
+						if (status == 'end') {
+							clearInterval(this.timer)
+							let duraing = this.playTime - this.duraing;
+							this.duraing = 0;
+							this.isEnd = true;
+							this.studyRecord(1, duraing)
+						}
+					}); // 监听流状态变化
+
+
+					// 第四步:监听频道信息读取完成事件,初始化播放器
+					let options = {
+						pptEl: els.pptEl,
+						el: els.playerEl,
+						switchPlayer: true,
+						controllerPosition: "ppt",
+						pptNavBottom: "180px",
+						controllerPosition: "player",
+						fixedController: true,
+						barrage: true,
+						defaultBarrageStatus: true,
+						controllerEl: els.controllerEl,
+						autoplay: true, // 设置自动播放
+					}
+					if (this.sectionType == 3) {
+						// 回放模式需要fileId、url、sessionId
+						// fileId: undefined, //ppt数据id,回放模式必填
+						// url: undefined,  // 回放视频链接,回放模式必填
+						// sessionId: undefined, // 回放场次id,回放模式必填
+						// vid: undefined,  // 回放id,回放模式下传入该参数,可不传fileId、url、sessionId
+						options.type = 'vod',
+							options.vid = this.vid
+					}
+					console.log('options', options)
+					this.plv.liveSdk.on('s2j_onInitOver', () => {
+						
+						var previewPPT = this.plv.liveSdk.previewPPT({
+							// 方式1:字符串的形式
+							el: els.pptEl, // 需要显示预览ppt的dom选择器
+							// 方式2:DOM 元素
+							// el: document.getElementById('previewPPT'),
+							autoId: '3106611', // 请求获取频道文档列表接口,返回的结果:autoId「文档 id」
+							type: 'new', // 类型,区分旧版PPT还是新版PPT,新版值为“new”,旧版值为“old”
+							width: '600',
+							height: '100%',
+							pptNav: true, //是否显示ppt控制控件,默认`true`
+							pptNavBottom: '50px' //ppt控制栏距离底部距离,例:`pptNavBottom: '50px'`
+						});
+
+						previewPPT.on('success', function() {
+							console.log('预览成功');
+						});
+
+						previewPPT.on('error', function(err) {
+							console.log('预览失败', err);
+						});
+
+						previewPPT.on('pptStatusChange', function(data) {
+							console.log('当前页改变', data);
+						});
+
+						return
+						this.plv.liveSdk.player.setupPlayer(options);
+
+						this.plv.liveSdk.player.on("switchPlayer", () => {
+							this.changeState = !this.changeState;
+							if (this.changeState) {
+								this.plv.liveSdk.player.setFullscreenEl(this.$refs.ppt);
+							} else {
+								this.plv.liveSdk.player.setFullscreenEl(this.$refs.player);
+							}
+						});
+
+						this.plv.liveSdk.player.on("switchMainScreen", (main) => {
+							console.log("切换主讲位置,当前主屏为", main); // 'player'|'ppt'
+						});
+						this.plv.liveSdk.player.on("pause", (state) => {
+							console.log(state, 'pause')
+							let duraing = this.playTime - this.duraing;
+							this.duraing = 0;
+							if (!this.isEnd) {
+								this.studyRecord(0, duraing)
+							}
+
+							clearInterval(this.timer)
+						})
+
+						this.plv.liveSdk.player.on("loadedmetadata", (state) => {
+							if (this.isFirst) {
+								this.studyRecord(0, 0)
+								this.isFirst = false;
+							}
+							this.isEnd = false;
+							clearInterval(this.timer)
+							this.timer = setInterval(() => {
+								this.studyRecord(0, 20)
+								this.duraing += 20;
+							}, 20000)
+						})
+
+						this.plv.liveSdk.player.on("timeupdate", (time) => {
+							this.playTime = time;
+						})
+					});
+
+				} catch (e) {
+					uni.showToast({
+						title: '提示:' + e
+					})
+					console.error(e, ':报错')
+					//TODO handle the exception
+				}
+			},
+			/**
+			 * @param {String} 聊天室js加载
+			 */
+			loadChatroomScriptzb() {
+				return new Promise((resolve) => {
+					if (!window.PolyvChatRoom) {
+						const myScript = document.createElement("script");
+						myScript.setAttribute("src", this.chatroomJs);
+						document.body.appendChild(myScript);
+						myScript.onload = resolve;
+					} else {
+						resolve();
+					}
+				});
+			},
+			/**
+			 * @param {String} 直播js加载
+			 */
+			loadPlayerScriptzb() {
+				return new Promise((resolve) => {
+					if (!window.polyvLivePlayer) {
+						const myScript = document.createElement("script");
+						myScript.setAttribute("src", this.playerJs);
+						document.body.appendChild(myScript);
+						myScript.onload = resolve;
+					} else {
+						resolve();
+					}
+				});
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.mobile-wrap .polyv-chat-input input {
+		width: 100%;
+		height: 100%;
+		padding: 0 5px;
+		color: #212121;
+		border: none;
+		border-radius: 4px;
+		background: #fafafa;
+		outline: none;
+		border: 1px solid #ecf0f1;
+	}
+
+	.sign-modal {
+		position: fixed;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100%;
+		z-index: 999;
+		background: rgba(0, 0, 0, 0.3);
+
+		&__content {
+			position: absolute;
+			left: 50%;
+			top: 50%;
+			transform: translate3d(-50%, -50%, 0);
+			border-radius: 24rpx;
+			overflow: hidden;
+
+			.img {
+				width: 640rpx;
+				display: block;
+			}
+
+			.box {
+				background: #fff;
+				padding: 20rpx 0;
+				overflow: hidden;
+
+				.title {
+					font-size: 30rpx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #333333;
+					line-height: 48rpx;
+					text-align: center;
+				}
+
+				.btn {
+					margin: 40rpx auto 0;
+					width: 528rpx;
+					height: 80rpx;
+					background: #007AFF;
+					border-radius: 40rpx;
+					line-height: 80rpx;
+					text-align: center;
+					color: #fff;
+					font-size: 30rpx;
+				}
+			}
+		}
+	}
+
+	.sign-success {
+		position: fixed;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100%;
+		z-index: 999;
+		background: rgba(0, 0, 0, 0.3);
+
+		&__content {
+			position: absolute;
+			left: 50%;
+			top: 50%;
+			transform: translate3d(-50%, -50%, 0);
+			border-radius: 24rpx;
+			width: 640rpx;
+			height: 324rpx;
+			background: #FFFFFF;
+			border-radius: 24rpx;
+
+			.img {
+				position: absolute;
+				left: 50%;
+				margin-left: -140rpx;
+				top: -72rpx;
+				width: 280rpx;
+				display: block;
+			}
+
+			.title {
+				margin-top: 200rpx;
+				font-size: 30rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 48rpx;
+				text-align: center;
+			}
+		}
+	}
+</style>

+ 476 - 0
pages/live/index9.vue

@@ -0,0 +1,476 @@
+<template>
+	<div class="living-room" style="width:950px">
+		<div id="player" class="subScreen"></div>
+		<div id="wrap" class="chatroom"></div>
+		<div id="ppt" class="mainScreen"></div>
+	</div>
+</template>
+
+<script>
+	import "@/static/chatroom.css";
+	import "@/static/mobile.css";
+	import "@/static/tool.css";
+	import "@/static/public.css";
+	export default {
+		data() {
+			return {
+				signModal: false,
+				signSuccess: false,
+				// playerJs: "https://player.polyv.net/resp/live-h5-player/latest/liveplayer.min.js",
+				playerJs: "https://player.polyv.net/livesdk/polyv-live.min.js",
+				chatroomJs: "https://player.polyv.net/jssdk/polyv-chatroom.min.js",
+				uidzb: "egsxlptzdq",
+				channelId: "",
+				appId: "",
+				sign: "",
+				timestamp: "",
+				mediaChannelKey: "",
+				changeState: false,
+				liveSdk: null,
+				userInfo: {},
+				token: '',
+				sectionId: 0,
+				goodsId: 0,
+				courseId: 0,
+				orderGoodsId: 0,
+				gradeId: 0,
+				chapterId: 0,
+				moduleId: 0,
+				playTime: 0,
+				duraing: 0,
+				timer: null,
+				isFirst: true,
+				isEnd: false,
+				plv: {
+					liveSdk: null, // 保存直播 JS-SDK 实例
+					socket: null, // 保存 WebSocket 实例
+					scene: "", // 场景
+					mainPosition: "player", // 用于记录当前主屏幕是文档还是播放器
+				},
+				buyCourse: 1, // 是否购买课程:1是 0否
+				identification: '', // 标识
+				sectionType: 2, // 节类型 1录播 2直播 3回放	
+				vid: '', // 回放的id
+			}
+		},
+		async mounted() {
+			this.query = {
+				"token": "eyJhbGciOiJIUzUxMiJ9.eyJ3eF9sb2dpbl91c2VyX2tleSI6IjdjZDg3OTU0NmRjOTRiMTFiZWJlN2U5MWUwZDRkYWQ3MTE2MTU5NzE2ODkzNTY0NTE4NCJ9.RirvlKi5Hhj0MifXKCbfpydl1aaYF5klXEf7uFtFKflTkGzPWn40Ef8Kcl0R9XA6O_M1_EwQ80FQelWxFfiBWA",
+				"userInfo": "{\"userId\":399,\"userAccount\":\"1161597168935645184\",\"nickname\":\"185****9508\",\"realname\":\"测试账号(勿删)\",\"sex\":2,\"idCard\":\"430482198902252180\",\"telphone\":\"18588699507\",\"orderNum\":null,\"userLevel\":1,\"createTime\":1696987946,\"userBirth\":null,\"eduLevel\":\"专科\",\"schoolId\":null,\"major\":\"456456456\",\"entranceTime\":null,\"openId\":null,\"idCardImg1\":\"oss/images/avatar/20240307/1709794000124/1709794000126_1833679356\",\"idCardImg2\":\"oss/images/avatar/20240307/1709794010541/1709794010542_1631941990\",\"country\":null,\"province\":null,\"city\":null,\"integral\":0,\"status\":1,\"certified\":0,\"certifiedTime\":null,\"district\":null,\"marry\":null,\"houseProvince\":null,\"houseCity\":null,\"houseDistrict\":null,\"oneInchPhotos\":\"oss/images/avatar/20240307/1709794006209/1709794006210_2020657710\",\"politic\":null,\"email\":null,\"avatar\":\"oss/images/avatar/20210623/1624414559368_44562477.png\",\"money\":0,\"gzhOpenId\":null,\"courseNum\":null,\"studyTime\":null,\"registerPlat\":\"1\",\"lastLoginTime\":1711593197,\"studentCode\":\"1161597168935645184\",\"workYear\":\"3~5年\",\"companyName\":\"广东中正教育科技有限公司\",\"nation\":null,\"census\":null,\"nativePlace\":null,\"contactAddress\":null,\"consigneeAddress\":null,\"remark\":null,\"houseAddress\":null,\"jobStatus\":null,\"goodsCourseNum\":null,\"goodsBankNum\":null,\"goodsLiveNum\":null,\"importNo\":null,\"userBindWx\":null,\"userFollowWx\":null,\"lastVisitTime\":null,\"visitFromPlat\":null,\"studyFromPlat\":null,\"lastStudyTime\":null,\"classGradeUserGoodsVoList\":null,\"job\":\"机械员\",\"keyValue\":null,\"shareCode\":null,\"shareActivityCode\":null,\"pwdTime\":null,\"eduPhone\":\"12345659\",\"unitContact\":\"45645654\",\"unitTel\":\"45646456\",\"school\":\"45643645\",\"graduationTime\":\"2021-03-11\",\"applySiteExamTime\":null,\"applySiteStartTime\":null,\"applySiteEndTime\":null,\"subscribeId\":null,\"seatNumber\":null}",
+				"channelId": "4220433",
+				"gradeId": "2003",
+				"courseId": "273649",
+				"goodsId": "628463",
+				"orderGoodsId": "6426",
+				"sectionId": "17666",
+				"chapterId": "126098",
+				"moduleId": "82154",
+				"buyCourse": "1",
+				"ident": "1711596862261",
+				"tid": "867735392558919680"
+			}
+			// console.log('直播间参数', JSON.stringify(this.query))
+			const {
+				buyCourse,
+				ident,
+				sectionType,
+				vid
+			} = this.query
+			console.log('sectionType:', sectionType, vid)
+			this.buyCourse = buyCourse
+			this.identification = ident
+			this.sectionType = sectionType || 2
+			this.vid = vid || ''
+			this.sectionId = this.query.sectionId;
+			this.goodsId = this.query.goodsId;
+			this.courseId = this.query.courseId;
+			this.orderGoodsId = this.query.orderGoodsId;
+			this.gradeId = this.query.gradeId;
+			this.chapterId = this.query.chapterId;
+			this.moduleId = this.query.moduleId;
+			this.channelId = this.query.channelId;
+			if (this.query.tid) {
+				await this.setStorageAwait('tid', this.query.tid)
+			}
+			this.userInfo = this.query.userInfo && this.query.userInfo !== 'null' ? JSON.parse(this
+				.query.userInfo) : {
+				userAccount: parseInt(Math.random() * 100000),
+				realname: '匿名' + parseInt(Math.random() * 100000)
+			}
+			let token = this.query.token;
+
+
+			if (token) {
+				uni.setStorageSync('token', token)
+			}
+			this.playVideo();
+			if (this.sectionId && this.sectionType != 3) {
+				this.studyRecordGetLastLive();
+			}
+
+		},
+		methods: {
+			setStorageAwait() {
+				return new Promise(resolve => {
+					uni.setStorage({
+						key: 'tid',
+						data: this.query.tid,
+						success: function() {
+							resolve()
+						}
+					});
+				})
+			},
+			close() {
+				this.signModal = false;
+				this.signSuccess = true;
+				setTimeout(() => {
+					this.signSuccess = false;
+				}, 1000)
+			},
+			/**
+			 * 获取上次观看的直播
+			 */
+			studyRecordGetLastLive() {
+				if (!this.gradeId) {
+					this.$http({
+						url: '/study/record/queryLiveLast',
+						data: {
+							orderGoodsId: this.orderGoodsId,
+							courseId: this.courseId,
+						}
+					}).then(res => {
+						if (res.data.code == 200) {
+							if (!res.data.data) {
+								this.signModal = true;
+							}
+						}
+					})
+				}
+			},
+			polyvLivesign() {
+				this.$http({
+					loading: true,
+					url: '/polyv/live/sign',
+					data: {
+						channelId: this.channelId,
+					}
+				}).then(res => {
+					if (res.data.code == 200) {
+						this.sign = res.data.data.sign;
+						this.token = res.data.data.token;
+						this.mediaChannelKey = res.data.data.mediaChannelKey;
+						this.timestamp = res.data.data.timestamp;
+						this.appId = res.data.data.appId;
+
+						this.loadPlayerzb();
+					} else {
+						uni.showToast({
+							title: res.data.msg,
+							icon: 'none'
+						})
+					}
+				}).catch((err) => {})
+			},
+
+			studyRecord(status, duraing) {
+
+				if (!this.sectionId) {
+					return;
+				}
+				let self = this;
+				this.$http({
+					load: false,
+					url: '/study/record',
+					data: {
+						buyCourse: this.buyCourse,
+						identification: this.identification,
+						sectionId: parseInt(this.sectionId),
+						goodsId: parseInt(self.goodsId),
+						courseId: parseInt(self.courseId),
+						orderGoodsId: this.orderGoodsId,
+						studyDuration: parseInt(duraing) || 0,
+						gradeId: parseInt(self.gradeId),
+						chapterId: parseInt(self.chapterId),
+						moduleId: parseInt(self.moduleId),
+						videoCurrentTime: parseInt(
+							2
+						),
+						status: status,
+						fromPlat: 1,
+					},
+					method: 'POST'
+				})
+			},
+
+			async playVideo() {
+				await this.jquery();
+				await this.loadPlayerScriptzb();
+				await this.loadChatroomScriptzb();
+				console.log('this.userInfo', this.userInfo);
+				this.polyvLivesign();
+			},
+
+			jquery() {
+				return new Promise((resolve) => {
+					if (!window.polyvLivePlayer) {
+						const myScript = document.createElement("script");
+						myScript.setAttribute("src", '../../static/jquery.min.js');
+						document.body.appendChild(myScript);
+						myScript.onload = resolve;
+					} else {
+						resolve();
+					}
+				});
+			},
+
+			loadPlayerzb() {
+				try {
+					var els = {
+						playerEl: '', // 播放器容器选择器, 移动端和PC的el参数设置不
+						pptEl: '', // 文档容器选择器, 普通直播不需要设置pptEl
+						controllerEl: '', // 三分屏控制栏的容器选择器, pc三分屏的场景才需要设置controllerEl,
+						chatContainer: '', // 聊天室的容器选择器
+						pptEl: '#tab-ppt'
+					};
+
+					$('.plv-watch-mobile').css('display', '');
+					els.playerEl = '#plv-mobile-player'; // 讲师区域元素
+					els.chatContainer = '#plv-mobile-chat'; // DOM选择器,HTML元素,用于渲染聊天室
+					els.pptEl = '#tab-ppt'; // ppt文档元素选择器,非云课堂可不填
+					var chatroom = new PolyvChatRoom({
+						//实例聊天室SDK
+						roomId: this.channelId,
+						userId: this.userInfo.userAccount,
+						nick: this.userInfo.realname,
+						accountId: this.userInfo.userAccount,
+						pic: this.$method.splitImgHost(this.userInfo.avatar, true) ||
+							"http://livestatic.videocc.net/assets/wimages/missing_face.png",
+						container: "#wrap",
+						userType: "slice",
+						version: "2.0",
+						showUserList: false,
+						width: '100%',
+						height: '100%',
+						token: this.token,
+						enableWelcome: true, // 是否开启欢迎语,默认为true
+						enableFlower: true, // 是否开启送花功能,默认为true
+						mediaChannelKey: this.mediaChannelKey,
+						tabData: [{
+								name: "文档",
+								type: "ppt",
+							},
+							{
+								name: "聊天", // 菜单栏名称
+								type: "chat", // 菜单栏类型, 有3个已有的内置类型(chat, user-list, ask),详情请参考文档
+							},
+							{
+								name: "提问",
+								type: "ask",
+							}
+						],
+						roomMessage: (data) => {
+							console.log(data, 'data')
+							// data为聊天室socket消息,当有聊天室消息时会触发此方法
+							if (this.liveSdk && this.liveSdk.player) {
+								var event = data.EVENT;
+								if (event === 'sendMessage' || event === 'SPEAK') {
+									this.liveSdk.player.sendBarrage(data.content);
+								}
+							}
+						},
+						customChatColor: {
+							selfBgColor: '#2b2c35',
+							selfColor: '#fff',
+							otherBgColor: '#2b2c35',
+							otherColor: '#fff',
+							specialBgColor: '#2b2c35',
+							specialColor: '#fff'
+						}
+					});
+					this.plv.socket = chatroom.chat.socket;
+					console.log(chatroom.chat.socket)
+					this.plv.liveSdk = new PolyvLiveSdk({
+						//实例直播SDK
+						channelId: this.channelId,
+						appId: this.appId,
+						sign: this.sign,
+						timestamp: this.timestamp,
+						socket: chatroom.chat.socket, //传入聊天室的socket
+						user: {
+							userId: this.userInfo.userAccount,
+							userName: this.userInfo.realname,
+							pic: this.$method.splitImgHost(this.userInfo.avatar, true) ||
+								"http://livestatic.videocc.net/assets/wimages/missing_face.png",
+						},
+					});
+					// 监听频道信息并初始化播放器
+					this.plv.liveSdk.on(PolyvLiveSdk.EVENTS.CHANNEL_DATA_INIT, (event, data) => {
+						//第三步:设置直播播放器
+						this.plv.liveSdk.setupPlayer({
+							pptEl: "#ppt",
+							el: "#player",
+							type: "auto",
+							controllerPosition: "player",
+							pptNavBottom: "80px",
+							autoplay: true,
+						});
+					});
+
+
+					// // 第四步:监听频道信息读取完成事件,初始化播放器
+					// let options = {
+					// 	pptEl: els.pptEl,
+					// 	el: els.playerEl,
+					// 	switchPlayer: true,
+					// 	controllerPosition: "ppt",
+					// 	pptNavBottom: "180px",
+					// 	controllerPosition: "player",
+					// 	fixedController: true,
+					// 	barrage: true,
+					// 	defaultBarrageStatus: true,
+					// 	controllerEl: els.controllerEl,
+					// 	autoplay: true, // 设置自动播放
+					// }
+					// if (this.sectionType == 3) {
+					// 	// 回放模式需要fileId、url、sessionId
+					// 	// fileId: undefined, //ppt数据id,回放模式必填
+					// 	// url: undefined,  // 回放视频链接,回放模式必填
+					// 	// sessionId: undefined, // 回放场次id,回放模式必填
+					// 	// vid: undefined,  // 回放id,回放模式下传入该参数,可不传fileId、url、sessionId
+					// 	options.type = 'vod',
+					// 		options.vid = this.vid
+					// }
+					// console.log('options', options)
+					// this.plv.liveSdk.on('s2j_onInitOver', () => {
+
+					// 	var previewPPT = this.plv.liveSdk.previewPPT({
+					// 		// 方式1:字符串的形式
+					// 		el: els.pptEl, // 需要显示预览ppt的dom选择器
+					// 		// 方式2:DOM 元素
+					// 		// el: document.getElementById('previewPPT'),
+					// 		autoId: '3106611', // 请求获取频道文档列表接口,返回的结果:autoId「文档 id」
+					// 		type: 'new', // 类型,区分旧版PPT还是新版PPT,新版值为“new”,旧版值为“old”
+					// 		width: '600',
+					// 		height: '100%',
+					// 		pptNav: true, //是否显示ppt控制控件,默认`true`
+					// 		pptNavBottom: '50px' //ppt控制栏距离底部距离,例:`pptNavBottom: '50px'`
+					// 	});
+
+					// 	previewPPT.on('success', function() {
+					// 		console.log('预览成功');
+					// 	});
+
+					// 	previewPPT.on('error', function(err) {
+					// 		console.log('预览失败', err);
+					// 	});
+
+					// 	previewPPT.on('pptStatusChange', function(data) {
+					// 		console.log('当前页改变', data);
+					// 	});
+
+					// 	return
+					// 	this.plv.liveSdk.player.setupPlayer(options);
+
+					// 	this.plv.liveSdk.player.on("switchPlayer", () => {
+					// 		this.changeState = !this.changeState;
+					// 		if (this.changeState) {
+					// 			this.plv.liveSdk.player.setFullscreenEl(this.$refs.ppt);
+					// 		} else {
+					// 			this.plv.liveSdk.player.setFullscreenEl(this.$refs.player);
+					// 		}
+					// 	});
+
+						this.plv.liveSdk.player.on("switchMainScreen", (main) => {
+							console.log("切换主讲位置,当前主屏为", main); // 'player'|'ppt'
+						});
+						this.plv.liveSdk.player.on("pause", (state) => {
+							console.log(state, 'pause')
+							let duraing = this.playTime - this.duraing;
+							this.duraing = 0;
+							if (!this.isEnd) {
+								this.studyRecord(0, duraing)
+							}
+
+							clearInterval(this.timer)
+						})
+
+					// 	this.plv.liveSdk.player.on("loadedmetadata", (state) => {
+					// 		if (this.isFirst) {
+					// 			this.studyRecord(0, 0)
+					// 			this.isFirst = false;
+					// 		}
+					// 		this.isEnd = false;
+					// 		clearInterval(this.timer)
+					// 		this.timer = setInterval(() => {
+					// 			this.studyRecord(0, 20)
+					// 			this.duraing += 20;
+					// 		}, 20000)
+					// 	})
+
+					// 	this.plv.liveSdk.player.on("timeupdate", (time) => {
+					// 		this.playTime = time;
+					// 	})
+					// });
+
+				} catch (e) {
+					uni.showToast({
+						title: '提示:' + e
+					})
+					console.error(e, ':报错')
+					//TODO handle the exception
+				}
+			},
+			/**
+			 * @param {String} 聊天室js加载
+			 */
+			loadChatroomScriptzb() {
+				return new Promise((resolve) => {
+					if (!window.PolyvChatRoom) {
+						const myScript = document.createElement("script");
+						myScript.setAttribute("src", this.chatroomJs);
+						document.body.appendChild(myScript);
+						myScript.onload = resolve;
+					} else {
+						resolve();
+					}
+				});
+			},
+			/**
+			 * @param {String} 直播js加载
+			 */
+			loadPlayerScriptzb() {
+				return new Promise((resolve) => {
+					if (!window.polyvLivePlayer) {
+						const myScript = document.createElement("script");
+						myScript.setAttribute("src", this.playerJs);
+						document.body.appendChild(myScript);
+						myScript.onload = resolve;
+					} else {
+						resolve();
+					}
+				});
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.mainScreen {
+		position: absolute;
+		top: 10px;
+		left: 310px;
+		width: 400px;
+		height: 500px;
+	}
+
+	.subScreen {
+		width: 300px;
+		height: 300px;
+	}
+
+	.chatroom {
+		width: 300px;
+		height: 500px;
+	}
+</style>