Commit 80d7f6c0 authored by liujinling's avatar liujinling

Merge branch 'master-develop' into 'master'

Master develop

See merge request !1
parents 0b801dd6 4989b255
# README
### 云直播微信小程序SDK版本
* 日期:2020年03月10
* 版本:1.4.1
* 日期:2021年08月04
* 版本:1.5.0
### 版本兼容
* 微信开发工具:建议使用 1.02.1912261 及以上版本
......@@ -18,6 +18,7 @@ https://eva.csslcloud.net
https://report.csslcloud.net
https://view.csslcloud.net
https://zeus.csslcloud.net
https://logger.csslcloud.net
```
socket合法域名
......@@ -34,6 +35,8 @@ wss://sio-7.csslcloud.net
downloadFile合法域名
```
https://image.csslcloud.net
https://live-watermark.csslcloud.net
https://replay-watermark.csslcloud.net
```
### ccsdk_demo使用方法
* WXCCLive小程序插件是CC云直播提供的小程序SDK,使用此插件可以快速实现与CC云直播对接。
......@@ -97,4 +100,3 @@ https://image.csslcloud.net
使用ccsdk_demo必须添加WXCCLive微信小程序插件。
登录微信公众平台 - 设置 - 第三方设置 - 添加插件中搜索 WXCCLive,添加后和客服确认审核即可使用。
//app.js
//app.js1
App({
onLaunch: function () {
onLaunch: function () {
},
globalData: {
ccsdk: requirePlugin('ccsdk')
}
},
globalData: {
ccsdk: requirePlugin('ccsdk')
// ccsdk: require('plugin/ccsdk')
}
});
\ No newline at end of file
......@@ -8,10 +8,13 @@
},
"plugins": {
"ccsdk": {
"version": "1.4.1",
"version": "1.5.0",
"provider": "wxf7200395f7f6b071"
}
},
"window": {
"enablePullDownRefresh": false
},
"subPackages": [
{
"root": "pages/live/",
......
......@@ -15,6 +15,10 @@ Component({
type: Boolean,
value: true
},
isDocuemntFullScreen: {
type: Boolean,
value: false
},
play: {
type: String,
value: ""
......@@ -49,8 +53,8 @@ Component({
toggleControl: true,
timer: {},
touchendDelay: {},
currentTime: "00:00",
duration: "00:00",
currentTime: "00:00 ",
duration: "00:00 ",
Duration: 0,
togglePlay: true,
percent: 0,
......@@ -94,26 +98,26 @@ Component({
hourTime = hourTime < 10 ? "0" + hourTime : hourTime;
result = "" + hourTime + ":" + result;
}
return result;
return result + ' ';
},
_setTime: function (newVal) {
if (JSON.stringify(newVal) === "{}") {
return;
}
if(this.data.Duration != newVal.detail.duration){
if (this.data.Duration != newVal.detail.duration) {
this.setData({
duration: this._formatSeconds(newVal.detail.duration),
Duration: newVal.detail.duration,
duration: this._formatSeconds(newVal.detail.duration),
Duration: newVal.detail.duration,
});
}
if (newVal.detail.duration > 0 && this.isPristineDuration) {
this.setData({
duration: this._formatSeconds(newVal.detail.duration),
Duration: newVal.detail.duration,
});
this.isPristineDuration = false;
this.setData({
duration: this._formatSeconds(newVal.detail.duration),
Duration: newVal.detail.duration,
});
this.isPristineDuration = false;
}
if (this.data.Duration && newVal.detail.currentTime >= this.data.Duration) {
......@@ -128,22 +132,29 @@ Component({
this.setData({
percent: this._formatePercent(newVal.detail.currentTime, newVal.detail.duration)
});
if (this.data.percent >= 0 && this.data.percent <= 100) {
if (this.data.percent >= 0 && this.data.percent <= 1) {
var nowLeft = (this.data.percent * this.data.loadingbarWidth);
this.setData({
left: nowLeft
});
}
if (this.data.left >= this.data.loadingbarWidth - this.data.circleWidth) {
this.setData({
left: this.data.loadingbarWidth - this.data.circleWidth
});
if (nowLeft < 16) {
this.setData({
left: '0px'
});
} else {
this.setData({
left: this.data.percent === 1 ? 'calc(' + this.data.percent * 100 + '% - 4.3vmin)' : 'calc(' + this.data.percent * 100 + '% - 3.5vmin)'
});
}
}
// if (this.data.left >= this.data.loadingbarWidth - this.data.circleWidth) {
// console.log('---2->>>>', nowLeft)
// this.setData({
// left: this.data.loadingbarWidth - this.data.circleWidth
// });
// }
}
},
_formatePercent: function (currentTime, duration) {
var percent = (currentTime / duration);
return percent.toFixed(2);
return percent.toFixed(2) > 1 ? 1 : percent.toFixed(2)
},
_bindControl: function () {
if (this.data.toggleControl) {
......@@ -206,6 +217,9 @@ Component({
var myEventDetail = e.detail;
var myEventOption = {};
this.triggerEvent("fullscreen", myEventDetail, myEventOption);
setTimeout(() => {
this._getLoadingBarSize()
}, 1000)
},
_getLoadingBarSize: function () {
var self = this;
......@@ -268,23 +282,32 @@ Component({
left: getParcent.left
});
}
if (getParcent.left >= this.data.loadingbarWidth - this.data.circleWidth) {
this.setData({
left: this.data.loadingbarWidth - this.data.circleWidth
});
}
// if (getParcent.left >= this.data.loadingbarWidth - this.data.circleWidth) {
// this.setData({
// left: this.data.loadingbarWidth - this.data.circleWidth
// });
// }
},
_getParcent: function (e) {
var pageX = e.touches[0].pageX;
var offsetLeft = e.currentTarget.offsetLeft;
var nowX = pageX - offsetLeft;
if (nowX < 0) {
nowX = 0
}
var width = this.data.loadingbarWidth;
var percent = (nowX / width).toFixed(2) > 1 ? 1 : (nowX / width).toFixed(2)
var nowLeft = (percent * width);
var data = {
left: nowX <= width ? nowX : width,
percent: (nowX / width).toFixed(2)
left: nowLeft < 16 ? '0px' : 'calc(' + percent * 100 + '% - 3.5vmin)',
percent: percent
};
return data;
},
_toggleDocumentFoo: function (e) {
var myEventDetail = e.detail;
var myEventOption = {};
this.triggerEvent("toggleDocumentFoo", myEventDetail, myEventOption);
}
},
ready: function () {
......
......@@ -7,11 +7,14 @@
</cover-view>
<cover-view class="center">
<cover-view class="btn-group"
style="display: {{toggleControl&&!fullscreen&&replayMode==='document'?'block':'none'}}">
<cover-view class="btn" catchtap="_catchSwitch">
style="display: {{toggleControl?'block':'none'}}">
<cover-view class="btn" style="display: {{isDocuemntFullScreen ? 'none' : 'block'}}" catchtap="_catchSwitch">
<cover-image class="switch" src="../../img/replay/replay/control/toggle@2x.png"></cover-image>
</cover-view>
<cover-view class="btn" catchtap="_catchShowHide">
<cover-view class="btn" style="display: {{!isDocuemntFullScreen ? 'none' : 'block'}}" catchtap="_toggleDocumentFoo">
<cover-image class="switch" src="../../img/replay/replay/control/toggle@2x.png"></cover-image>
</cover-view>
<cover-view class="btn" style="display: {{isDocuemntFullScreen ? 'none' : 'block'}}" catchtap="_catchShowHide">
<cover-image class="show-hide"
src="../../img/replay/replay/control/{{showHide?'hidden':'show'}}.png"></cover-image>
</cover-view>
......@@ -23,15 +26,15 @@
src="../../img/replay/replay/control/{{play!=='play'?'play':'pause'}}@2x.png"></cover-image>
</cover-view>
<cover-view class="time-box">
<cover-view class="time-current">{{currentTime}} .</cover-view>
<cover-view class="time-current">{{currentTime}} </cover-view>
<cover-view style="color: #fff;font-size:28rpx;padding-right: 5rpx">/</cover-view>
<cover-view class="time-duration">{{duration}} .</cover-view>
<cover-view class="time-duration">{{duration}} </cover-view>
</cover-view>
<cover-view id="loadingbar" class="loadingbar-box" catchtouchstart="_catchtouchstart"
catchtouchend="_catchtouchend"
catchtouchmove="_catchLoadingbarTouchmove">
<cover-view class="loadingbar">
<cover-view class="circle-box" style="left:{{left}}px">
<cover-view class="circle-box" style="left:{{left}}">
<!--<cover-view class="circle"></cover-view>-->
<cover-image id="circle" class="circle" src="../../img/replay/replay/control/circle@2x.png"></cover-image>
</cover-view>
......
......@@ -10,33 +10,33 @@
.container .top {
align-self: flex-end;
}
/* rpx-> vmin rpx* 100/750 vmin 看下兼容性*/
.container .top .replay-box {
background:rgba(0,0,0,0.3);
border-radius:100rpx;
width:115rpx;
height:52rpx;
margin: 20rpx 30rpx 0rpx 0rpx;
padding: 13rpx 22rpx;
border-radius: 13.3vmin;
width: 15.3vmin;
height: 6.94vmin;
margin: 2.7vmin 4vmin 0 0;
padding: 1.44vmin 2.94vmin;
box-sizing: border-box;
}
.container .top .circle {
float: left;
background:#26bb52;
box-shadow:1rpx 1rpx 1rpx 0rpx rgba(0,0,0,0.50);
width:12rpx;
height:12rpx;
box-shadow: .14vmin .14vmin .14vmin 0rpx rgba(0,0,0,0.50);
width:1.6vmin;
height:1.6vmin;
border-radius:100%;
margin-right: 5rpx;
margin-top:9rpx;
margin-right: .7vmin;
margin-top: 1.2vmin;
}
.container .top .replay {
float: left;
font-size:26rpx;
font-size: 3.47vmin;
color:#ffffff;
text-shadow:1rpx 1px 0rpx rgba(102,102,102,0.50);
text-shadow:.14vmin .14vmin 0rpx rgba(102,102,102,0.50);
}
.container .center {
......@@ -48,16 +48,16 @@
}
.container .center .btn-group .btn {
width: 130rpx;
height: 100rpx;
width: 17.4vmin;
height: 13.4vmin;
display: flex;
justify-content: center;
align-items: flex-end;
}
.container .center .btn-group .btn cover-image{
width: 70rpx;
height: 70rpx;
width: 9.4vmin;
height: 9.4vmin;
}
.container .center .btn-group .btn .show-hide {
......@@ -71,22 +71,22 @@
.container .bottom {
display: flex;
background:rgba(0,0,0,0.5);
height:70rpx;
height: 9.4vmin;
align-items: center;
padding: 5rpx 10rpx;
padding: .7vmin 1.4rem;
box-sizing: border-box;
width: 100%;
}
.container .bottom cover-image{
width: 60rpx;
height: 60rpx;
width: 8vmin;
height: 8vmin;
}
/*播放*/
.container .bottom .playBtn-box {
flex:1.2;
margin-right: 10rpx;
/* flex: 1.2; */
margin-right: 1.4vmin;
}
.container .bottom .playBtn-box .playBtn{
......@@ -95,35 +95,37 @@
/*时间*/
.container .bottom .time-box{
flex: 6.5;
/* flex: 6.5; */
display: flex;
justify-content: center;
vertical-align: middle;
width: 200rpx;
height: 28rpx;
width: 26.7vmin;
height: 3.74vmin;
overflow-x: auto;
}
.container .bottom .time-box .time-current {
font-size: 24rpx;
font-size: 3.2vmin;
color:#fff;
white-space: pre-wrap;
}
.container .bottom .time-box .time-duration {
font-size: 24rpx;
font-size: 3.2vmin;
color:rgba(255,255,255,0.6);
white-space: pre-wrap;
}
/*进度条*/
.container .bottom .loadingbar-box{
flex:10;
flex:1;
display: flex;
align-items: center;
margin-right: 10rpx;
margin-right: 1.34vmin;
}
.container .bottom .loadingbar-box .loadingbar{
height: 32rpx;
height: 4.27vmin;
/*width: 395rpx;*/
width: 100%;
display: flex;
......@@ -131,10 +133,10 @@
}
.container .bottom .loadingbar-box .loadingbar .background{
height: 6rpx;
height: .8vmin;
width: 100%;
background:#999999;
margin-left: -16rpx;
margin-left: -2.14vmin;
}
.container .bottom .loadingbar-box .loadingbar .background .progress{
......@@ -153,8 +155,8 @@
position: relative;
/*left:0rpx;*/
z-index: 1;
width:32rpx;
height:32rpx;
width: 4.27vmin;
height: 4.27vmin;
}
.container .bottom .loadingbar-box .loadingbar .circle{
......@@ -163,17 +165,14 @@
/*width:18rpx;*/
/*height:18rpx;*/
/*border-radius:100%;*/
width:32rpx;
height:32rpx;
width: 4.27vmin;
height: 4.27vmin;
}
/*全屏*/
.container .bottom .fullscreenBtn-box {
flex:1.5;
/* flex:1.5; */
}
.container .bottom .fullscreenBtn-box .fullScreenBtn{
}
var cc = getApp().globalData.ccsdk;
// components/replay/cclive-player/cclive-live.js
Component({
externalClasses: ["player-class"],
properties: {
_stopInterval: {
type: Boolean,
value: false,
observer: function (newVal) {
if (newVal) {
this.stopInterval();
}
}
},
netconnectstate: {
type: Object,
value: {},
observer: function (newVal) {
}
},
initialTime: {
type: Number,
value: 0
},
duration: {
type: Number,
value: 0
},
controls: {
type: Boolean,
value: false
},
autoplay: {
type: Boolean,
value: true
},
loop: {
type: Boolean,
value: false
},
muted: {
type: Boolean,
value: false
},
direction: {
type: Number,
value: 0
},
objectFit: {
type: String,
value: "contain"
},
showCenterPlayBtn: {
type: Boolean,
value: false
}
},
data: {
playerUrl: "",
enableProgressGesture: false,
togglePlayer: true
},
methods: {
bindPlay: function (e) {
this.startInterval();
cc.replay.listenerplay(e);
var myEventDetail = e.detail;
var myEventOption = {};
this.triggerEvent("play", myEventDetail, myEventOption);
},
bindPause: function (e) {
var myEventDetail = e.detail;
var myEventOption = {};
this.triggerEvent("pause", myEventDetail, myEventOption);
},
bindEnded: function (e) {
this.stopInterval();
cc.replay.listenerended(e);
var myEventDetail = e.detail;
var myEventOption = {};
this.triggerEvent("ended", myEventDetail, myEventOption);
},
bindTimeupdate: function (e) {
this.setTimestamp(e);
},
_timeupdate: function () {
var e = this.getTimestamp();
if (!e.detail) {
return;
}
cc.replay.timeupdate(e);
this.setCurrentTime(e);
var myEventDetail = e.detail;
var myEventOption = {};
this.triggerEvent("timeupdate", myEventDetail, myEventOption);
if (!this._interval) {
this.startInterval();
}
},
bindWaiting: function (e) {
cc.replay.waiting(e);
var myEventDetail = e.detail;
var myEventOption = {};
this.triggerEvent("waiting", myEventDetail, myEventOption);
},
bindFullscreenchange: function (e) {
var myEventDetail = e.detail;
var myEventOption = {};
this.triggerEvent("fullscreenchange", myEventDetail, myEventOption);
},
bindError: function (e) {
this.onErrorReplay(e);
cc.replay.error(e);
var myEventDetail = e.detail;
var myEventOption = {};
this.triggerEvent("error", myEventDetail, myEventOption);
},
setTimestamp: function (e) {
this.timestamp = e;
},
getTimestamp: function () {
return this.timestamp;
},
setCurrentTime: function (e) {
this.currentTime = e.detail.currentTime;
},
onErrorReplay: function (e) {
// console.log("bindError", e);
},
startInterval: function () {
var _this = this;
_this.stopInterval();
_this._interval = setInterval(function () {
_this._timeupdate();
}, 999);
},
stopInterval: function () {
var _this = this;
clearInterval(_this._interval);
_this._interval = 0;
_this.timestamp = {};
}
},
ready: function () {
var _this = this;
_this.videoContext = cc.replay.configPlayer(_this, wx);
_this.currentTime = 0;
_this.timestamp = {};
_this._interval = 0;
cc.replay.getPlayerUrls({
success: function(datas) {
console.log("getPlayerUrls success", datas);
},
fail: function(error) {
console.log("getPlayerUrls fail", error);
}
});
}
});
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
<video wx:if="{{togglePlayer}}" id="player" class="player-class" src="{{playerUrl}}" show-center-play-btn="{{showCenterPlayBtn}}"
initial-time="initialTime" autoplay="{{autoplay}}" duration="{{duration}}"
controls="{{controls}}" loop="{{loop}}" muted="{{muted}}" objectFit="{{objectFit}}" bindplay="bindPlay"
bindpause="bindPause" bindended="bindEnded" bindtimeupdate="bindTimeupdate"
bindwaiting="bindWaiting" bindfullscreenchange="bindFullscreenchange" binderror="bindError" enable-progress-gesture="{{enableProgressGesture}}">
<slot></slot>
</video>
/* components/replay/cclive-player/cclive-player.wxss */
\ No newline at end of file
......@@ -5,10 +5,19 @@ Page({
data: {},
onLoad: function () {
// cc.live.setDebug(true);
console.warn("Tip:获得场景视频微信小程序Demo,请使用真机测试推流端、观看直播、观看回放,开启设备音视频权限,开启微信公众平台小程序“实时播放音视频流”、“实时录制音视频流”功能。");
cc.live.setDebug(true);
},
toReplayApi: function () {
wx.navigateTo({
url: "../replay/api/api"
});
},
toLiveApi: function () {
wx.navigateTo({
url: "../live/api/api"
});
},
//推流端
bindPublisher: function () {
wx.navigateTo({
......
......@@ -237,7 +237,6 @@ Page({
+ "&viewerName=" + encodeURIComponent(self.data.viewerName)
+ "&groupid=" + encodeURIComponent(self.data.groupid)
+ "&viewerId=" + encodeURIComponent(self.data.viewerId);
wx.navigateTo({
url: "../player/player?" + str
});
......@@ -301,6 +300,23 @@ Page({
if (!self.data.userId || !self.data.roomId || !self.data.userName) {
return false;
}
if (self.data.userId.length >= 50 || self.data.roomId.length >= 50 || self.data.userName.length >= 50) {
wx.showToast({
title: '长度不能超过50',
icon: 'none',
duration: 2000
})
return false;
}
var pattern = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]")
if (pattern.test(self.data.userId) || pattern.test(self.data.roomId) || pattern.test(self.data.userName)) {
wx.showToast({
title: '不能包含特殊字符',
icon: 'none',
duration: 2000
})
return false;
}
return true;
}
......
......@@ -11,16 +11,16 @@
<view class="form">
<view class="form-cell">
<text>CC账号ID</text>
<input disabled="{{loading}}" placeholder="16位账号ID" value="{{userId}}" bindinput="setUserId" />
<input disabled="{{loading}}" placeholder="16位账号ID" value="{{userId}}" bindinput="setUserId" maxlength="50"/>
</view>
<view class="form-cell">
<text>直播间ID</text>
<input disabled="{{loading}}" placeholder="32位直播间ID" value="{{roomId}}" bindinput="setRoomId" />
<input disabled="{{loading}}" placeholder="32位直播间ID" value="{{roomId}}" bindinput="setRoomId" maxlength="50"/>
</view>