872 lines
35 KiB
Vue
872 lines
35 KiB
Vue
<template>
|
||
<view class="page-live">
|
||
<view class="video-container">
|
||
<live-player
|
||
id="livePlayer"
|
||
@error="error"
|
||
@statechange="statechange"
|
||
mode="RTC"
|
||
:src="isHD ? videoHDSrc : videoSrc"
|
||
@tap.stop.prevent="onVideoTap"
|
||
:muted="!openSound"
|
||
:class="fullScreen ? 'video-item full-screen' : 'video-item'"
|
||
@fullscreenchange="fullscreenChange"
|
||
:object-fit="objectFit"
|
||
>
|
||
<!-- loading状态 -->
|
||
<cover-view class="video-loading-container" @tap.stop.prevent="onVideoTap" v-if="videoLoadingStatus !== 100">
|
||
<cover-image class="video-loading-bg" src="../../static/live/images/live/live_loading_bg.png"></cover-image>
|
||
<!-- 停止状态 -->
|
||
<cover-view class="video-loaing video-ready" v-if="videoLoadingStatus === 0">
|
||
<cover-image class="loading-gif" src="../../static/live/images/live/landscape_play.png" @tap.stop.prevent="handlePlay"></cover-image>
|
||
</cover-view>
|
||
<!-- 加载资源中状态 -->
|
||
<cover-view class="video-loaing" v-if="!(videoLoadingStatus === 0 || videoNetWorkError)">
|
||
<cover-image class="loading-gif" src="../../static/live/images/live/loading_grey.gif"></cover-image>
|
||
<cover-view class="video-loading-text">视频安全传输中...{{ videoLoadingStatus }}%</cover-view>
|
||
</cover-view>
|
||
</cover-view>
|
||
<!-- 开启隐私遮蔽状态 -->
|
||
<!-- <cover-view class="video-loading-container" hidden="{{!(panelStatus == 4)}}">
|
||
<cover-image class="video-loading-bg" src="../live/images/live/live_loading_bg.png"></cover-image>
|
||
<cover-view class="video-loaing">
|
||
<cover-image class="loading-gif" src="../live/images/live/preview_fail_yinsi.png"></cover-image>
|
||
<cover-view class="video-loading-text">已开启隐私遮蔽</cover-view>
|
||
</cover-view>
|
||
</cover-view> -->
|
||
<!-- 加载资源失败状态 -->
|
||
<cover-view class="video-loading-container" v-if="videoNetWorkError">
|
||
<cover-image class="video-loading-bg" src="../../static/live/images/live/live_loading_bg.png"></cover-image>
|
||
<cover-view class="video-loaing">
|
||
<cover-image class="loading-gif" src="../../static/live/images/live/preview_fail.png"></cover-image>
|
||
<cover-view class="video-loading-text">网络不稳定,加载失败</cover-view>
|
||
<cover-view class="video-loading-text reTry" ontap="handlePlay">重试</cover-view>
|
||
</cover-view>
|
||
</cover-view>
|
||
<!-- 设备不在线状态 -->
|
||
<cover-view class="video-loading-container" v-if="deviceOffline">
|
||
<cover-image class="video-loading-bg" src="../../static/live/images/live/live_loading_bg.png"></cover-image>
|
||
<cover-view class="video-loaing">
|
||
<cover-image class="loading-gif" src="../../static/live/images/live/preview_fail_offline.png"></cover-image>
|
||
<cover-view class="video-loading-text">设备不在线</cover-view>
|
||
<cover-view class="video-loading-text">离线时间:{{ deviceOfflineTime }}</cover-view>
|
||
</cover-view>
|
||
</cover-view>
|
||
<!-- 清晰度 -->
|
||
<!-- <cover-view class="{{showHDSelect ? 'hd-select' : 'hd-select hide'}}">
|
||
<cover-view class="{{isHD ? 'hd-option active': 'hd-option'}}" catchtap="changeVideoHD">高清</cover-view>
|
||
<cover-view class="{{!isHD ? 'hd-option active': 'hd-option'}}" catchtap="changeVideoNormal">标清</cover-view>
|
||
</cover-view> -->
|
||
<!-- 竖屏模式 -->
|
||
<!-- <cover-view class="{{fullScreen ? 'hidden' : ''}} video-controls-container">
|
||
</cover-view>
|
||
<cover-view class="{{(fullScreen || !showVideoControls) ? 'hidden' : ''}} video-controls-container">
|
||
<cover-image class="controls-img" src='{{playVideo ? "../live/images/video_icon_stop.png":"../live/images/video_icon_play.png"}}' catchtap="{{playVideo ? 'handleStop': 'handlePlay'}}"></cover-image>
|
||
<cover-image class="controls-img" src='{{!openSound ? "../live/images/video_icon_closesound.png":"../live/images/video_icon_opensound.png"}}' catchtap="handleSound"></cover-image>
|
||
<cover-image class="controls-img hd" src="{{isHD ? '../live/images/video_icon_hd.png' : '../live/images/video_icon_bq.png' }}" catchtap="handleHD">
|
||
</cover-image>
|
||
<cover-image class="controls-img" catchtap="fullScreen" src="../live/images/video_icon_full.png"></cover-image>
|
||
</cover-view> -->
|
||
<!-- 横屏模式 -->
|
||
<!-- <cover-view class="{{!fullScreen ? 'hidden' : '' }}' video-back-container">
|
||
<cover-image class="back-img" src="../live/images/nav_icon_back_full.png" catchtap="unfullScreen"></cover-image>
|
||
<cover-view class="back-device">{{deviceName}}</cover-view>
|
||
</cover-view>
|
||
<cover-view class="{{(!fullScreen || !showVideoControls) ? 'hidden' : '' }}' video-controls-container">
|
||
<cover-image class="controls-img" src='{{playVideo ? "../live/images/live_icon_stop_full.png":"../live/images/live_icon_play_full.png"}}' catchtap="{{playVideo ? 'handleStop' : 'handlePlay'}}"></cover-image>
|
||
<cover-image class="controls-img" src='{{!openSound ? "../live/images/live_icon_unsound_full.png":"../live/images/live_icon_sound_full.png"}}' catchtap="handleSound"></cover-image>
|
||
<cover-image class="controls-img" catchtap="ToggleObjectFit" src="../live/images/live_icon_adapt_full.png"></cover-image>
|
||
</cover-view> -->
|
||
<!-- 云台超限 -->
|
||
<!-- <cover-image class="ptz-limit right" src="../live/images/yuntai/ptz_limit_right.jpg">
|
||
</cover-image> -->
|
||
<!-- <cover-view class="ptz-limit {{ptzLimit ? ptzLimit : 'hidden'}}"></cover-view> -->
|
||
</live-player>
|
||
</view>
|
||
<view class="controls-container">
|
||
<view class="controls-item" @tap.stop.prevent="screenShoot">
|
||
<image
|
||
class="item-img"
|
||
:src="playVideo && videoLoadingStatus == 100 ? '../../static/live/images/preview_cut_normal.png' : '../../static/live/images/preview_cut_disable.png'"
|
||
></image>
|
||
<text :class="playVideo && videoLoadingStatus == 100 ? 'item-text' : 'item-text disabled'">截屏</text>
|
||
</view>
|
||
<button class="controls-item" open-type="share">
|
||
<image class="item-img" src="../../static/live/images/preview_share_normal.png"></image>
|
||
<text class="item-text">分享</text>
|
||
</button>
|
||
</view>
|
||
|
||
<view class="cloudSwitch">
|
||
<!-- 日期选择器 -->
|
||
<view style="float: left; lineheight: 30px">{{ date }}</view>
|
||
<picker mode="date" :value="date" @change="bindDateChange" start="2000-01-01" :end="toDay" style="float: left">
|
||
<view class="picker">
|
||
<!-- 当前选择: {{date}} -->
|
||
<!-- 日期选择图标 -->
|
||
<image class="item-img" src="../../static/playback/images/datepicker.png"></image>
|
||
</view>
|
||
</picker>
|
||
<!-- 云存储/本地录像选择 -->
|
||
<view style="float: right">
|
||
{{ switchText }}
|
||
<switch :checked="switch1Checked" @change="switch1Change" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 时间轴 -->
|
||
<view>
|
||
<timeLine :inner-text="innerText" @getPalyParam="getPalyParam" :playCode="playCode" :dateLine="dateLine"></timeLine>
|
||
</view>
|
||
|
||
<!-- 返回直播 -->
|
||
<view class="backToLiveIcon" style="position: fixed; bottom: 100rpx; right: 20rpx" v-if="page != 1">
|
||
<button @tap.stop.prevent="goToLive" style="text-align: center; font-size: 14px; background: #ff8f42; padding: 8">
|
||
<view>
|
||
<cover-image class="back-img" src="../../static/live/images/nav_icon_back_full.png"></cover-image>
|
||
回直播
|
||
</view>
|
||
</button>
|
||
</view>
|
||
|
||
<!-- 模态框 -->
|
||
<mp-dialog :title="dialogTitle" :show="dialogShow" @buttontap="tapDialogButton" :buttons="buttons">
|
||
<view>{{ dialogContent }}</view>
|
||
</mp-dialog>
|
||
<mp-dialog :title="dialogNodataTitle" :show="dialogNodataShow" @buttontap="tapDialogNodataButton" :buttons="buttons">
|
||
<view>{{ dialogNodataContent }}</view>
|
||
</mp-dialog>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import timeLine from '../../component/timeLine/timeLine';
|
||
import mpDialog from '../../component/dialog/dialog';
|
||
// pages/playback/playback.js
|
||
import { OPEN_DOMAIN } from '../../config/config';
|
||
let livePlayerContext;
|
||
var init;
|
||
export default {
|
||
components: {
|
||
timeLine,
|
||
mpDialog
|
||
},
|
||
data() {
|
||
return {
|
||
accessToken: '',
|
||
deviceSerial: '',
|
||
channelNo: '',
|
||
videoSrc:
|
||
'rtmp://xyrtmp.ys7.com:1935/v3/openpb/C78957921_1_1?begin=20211110061910&end=20211110061931&expire=1636615248&id=378564661994004480&rec=cloud&t=7920d6711740bfe795e9f06ceff646a6345d059b8fc14152acde1478468ccdbf&ev=100&ownerId=openteam&streamer=cloud.ys7.com:32723&VideoType=2&StorageVersion=2',
|
||
coverDisabled: true,
|
||
coverInterval: false,
|
||
showVideoControls: true,
|
||
autoHideTimer: undefined,
|
||
videoLoadingStatus: 0,
|
||
playVideo: false,
|
||
videoNetWorkError: false,
|
||
objectFit: 'contain',
|
||
openSound: true,
|
||
isHD: false,
|
||
showHDSelect: false,
|
||
fullScreen: false,
|
||
deviceOffline: false,
|
||
deviceOfflineTime: new Date(),
|
||
deviceName: '',
|
||
dialogTitle: '',
|
||
dialogContent: '',
|
||
|
||
buttons: [
|
||
{
|
||
text: '知道了'
|
||
}
|
||
],
|
||
|
||
dialogShow: false,
|
||
dialogNodataTitle: '',
|
||
dialogNodataContent: '',
|
||
dialogNodataShow: false,
|
||
cloudPalayParam: null,
|
||
playCode: 0,
|
||
|
||
// 当前播放错误码,
|
||
switch1Checked: true,
|
||
|
||
recType: 2,
|
||
|
||
// 1-云存储,2-本地录像
|
||
type: 2,
|
||
|
||
// 2-本地录像回放,3-云存储录像回放
|
||
switchText: '本地',
|
||
|
||
param: {},
|
||
|
||
// 获取播放片段参数
|
||
date: '',
|
||
|
||
// 当前选择日期
|
||
dateLine: [],
|
||
|
||
// 时间片段
|
||
contentItemShow: false,
|
||
|
||
// 暂无数据
|
||
toDay: '',
|
||
|
||
// 今日日期
|
||
// 当前页面层级
|
||
page: 1,
|
||
|
||
panelStatus: 0,
|
||
list: '',
|
||
videoHDSrc: '',
|
||
innerText: ''
|
||
};
|
||
},
|
||
onLoad: function (options) {
|
||
livePlayerContext = uni.createLivePlayerContext('livePlayer');
|
||
console.log('获取参数', options);
|
||
// 获取当前页面栈
|
||
const currentPage = getCurrentPages();
|
||
console.log(currentPage.nv_length);
|
||
|
||
// 获取url携带的参数
|
||
const { accessToken, deviceSerial, channelNo, date, switch1Checked } = options;
|
||
this.playVideo=true,
|
||
this.accessToken=accessToken,
|
||
this.deviceSerial=deviceSerial,
|
||
this.channelNo=channelNo,
|
||
this.page=currentPage.nv_length
|
||
console.log(date);
|
||
// 通过分享今日指定日期
|
||
if (date) {
|
||
this.date=date,
|
||
this.toDay=date
|
||
} else {
|
||
// 获取当前日期
|
||
this.getTodayDate();
|
||
}
|
||
if (switch1Checked == 'false') {
|
||
this.switchText='云存储',
|
||
this.switch1Checked=false,
|
||
this.recType=1,
|
||
this.type=3
|
||
}
|
||
// 获取包含播放片段的时间片段
|
||
this.getTimeLine();
|
||
},
|
||
/**
|
||
* 用户点击右上角分享
|
||
*/
|
||
onShareAppMessage: function (res) {
|
||
const { accessToken, deviceSerial, channelNo, date, switch1Checked } = this;
|
||
console.log(switch1Checked);
|
||
if (res.from === 'button') {
|
||
// 来自页面内转发按钮
|
||
console.log(res.target);
|
||
this.panelStatus=0
|
||
}
|
||
return {
|
||
title: '小程序',
|
||
path:
|
||
'/pages/playback/playback?accessToken=' +
|
||
accessToken +
|
||
'&deviceSerial=' +
|
||
deviceSerial +
|
||
'&channelNo=' +
|
||
channelNo +
|
||
'&date=' +
|
||
date +
|
||
'&switch1Checked=' +
|
||
switch1Checked
|
||
};
|
||
},
|
||
methods: {
|
||
// 模态框按钮
|
||
tapDialogButton(e) {
|
||
this.dialogShow=false
|
||
uni.navigateBack({
|
||
delta: 1
|
||
});
|
||
},
|
||
|
||
// 无时间片段数据时
|
||
tapDialogNodataButton() {
|
||
this.dialogNodataShow=false
|
||
},
|
||
|
||
// 获取存储类型
|
||
switch1Change: function (e) {
|
||
console.log('当前存储类型', e.detail);
|
||
if (e.detail.value == false) {
|
||
this.switchText='云存储',
|
||
this.switch1Checked=false,
|
||
this.recType=1,
|
||
this.type=3
|
||
this.getTimeLine();
|
||
} else {
|
||
this.switchText='本地',
|
||
this.switch1Checked=true,
|
||
this.recType=2,
|
||
this.type=2
|
||
this.getTimeLine();
|
||
}
|
||
},
|
||
|
||
// 获取当天日期
|
||
getTodayDate: function () {
|
||
const that = this;
|
||
let type = null;
|
||
var time = new Date();
|
||
var h = time.getFullYear();
|
||
var m = time.getMonth() + 1;
|
||
var d = time.getDate();
|
||
let date = (h > 9 ? h : '0' + h) + '-' + (m > 9 ? m : '0' + m) + '-' + (d > 9 ? d : '0' + d);
|
||
this.date=date
|
||
// 获取当前操作系统类型
|
||
uni.getSystemInfo({
|
||
success(res) {
|
||
console.log('当前操作系统:', res.system);
|
||
const sys = res.system;
|
||
type = sys.split(' ');
|
||
console.log(type);
|
||
if (type[0] == 'iOS') {
|
||
that.toDay=date.replace(/\-/g, '/')
|
||
} else {
|
||
that.toDay=date
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
format: function (now) {
|
||
var time = new Date(now);
|
||
var h = time.getHours(); //返回日期中的小时数(0到23)
|
||
var m = time.getMinutes(); //返回日期中的分钟数(0到59)
|
||
var s = time.getSeconds(); //返回日期中的秒数(0到59)
|
||
return (h > 9 ? h : '0' + h) + ':' + (m > 9 ? m : '0' + m) + ':' + (s > 9 ? s : '0' + s);
|
||
},
|
||
|
||
// 获取时间轴
|
||
getTimeLine: function () {
|
||
const { recType, date, accessToken, deviceSerial, channelNo, timelineTimer, currentTimer } = this;
|
||
console.log('获取到的accessToken, accessToken', accessToken);
|
||
var that = this;
|
||
let currentDate = null;
|
||
let timestampCurrent = null;
|
||
let timestampToday = null;
|
||
// 时间戳转换:Date.parse(new Date("2020-09-23 12:13:56"))
|
||
if (date) {
|
||
currentDate = date;
|
||
const time = currentDate + ' ' + '00:00:00';
|
||
const endTime = currentDate + ' ' + '23:59:59';
|
||
timestampToday = Date.parse(new Date(time.replace(/\-/g, '/'))); // 选择日期凌晨时间戳
|
||
timestampCurrent = Date.parse(new Date(endTime.replace(/\-/g, '/'))); // 选择日期时间戳
|
||
}
|
||
|
||
uni.request({
|
||
url: `${OPEN_DOMAIN}/api/lapp/video/by/time`,
|
||
method: 'POST',
|
||
data: {
|
||
accessToken: accessToken,
|
||
deviceSerial: deviceSerial,
|
||
channelNo: channelNo,
|
||
recType: recType,
|
||
startTime: timestampToday,
|
||
endTime: timestampCurrent
|
||
},
|
||
header: {
|
||
'content-type': 'application/x-www-form-urlencoded' // 默认值
|
||
},
|
||
|
||
success: (res) => {
|
||
console.log('获取播放时间片段', res.data);
|
||
if (res.data.code == 200) {
|
||
if (res.data.data != null) {
|
||
var result = res.data.data;
|
||
const len = result.length;
|
||
let availArr = [];
|
||
for (let i = len - 1; i >= 0; i--) {
|
||
let res = result[i];
|
||
let et = null;
|
||
let st = null;
|
||
// 最近片段可能存在endTime超过当前时间
|
||
if (i == len - 1 && res.endTime > timestampCurrent) {
|
||
et = this.format(timestampCurrent);
|
||
} else {
|
||
et = this.format(res.endTime);
|
||
}
|
||
// 存在startTime可能为前一天的时间
|
||
if (i == 0 && res.startTime < timestampToday) {
|
||
st = this.format(timestampToday);
|
||
} else {
|
||
st = this.format(res.startTime);
|
||
}
|
||
availArr.push({
|
||
st: st,
|
||
et: et
|
||
});
|
||
}
|
||
console.log('availArr:', availArr);
|
||
this.dateLine=availArr
|
||
} else {
|
||
this.dialogNodataTitle='暂无数据',
|
||
this.dialogNodataContent=' 暂无录像片段',
|
||
this.dialogNodataShow=true,
|
||
this.dateLine=[]
|
||
this.handleStop();
|
||
}
|
||
} else if (res.data.code == '10002') {
|
||
this.dialogTitle='',
|
||
this.dialogContent='accessToken过期或异常',
|
||
this.dialogShow=true,
|
||
this.dateLine=[]
|
||
} else if (res.data.code == '20002') {
|
||
this.dialogTitle='获取播放时间片段失败',
|
||
this.dialogContent='设备不存在',
|
||
this.dialogShow=true,
|
||
this.dateLine=[]
|
||
} else if (res.data.code == '20007') {
|
||
this.dialogTitle='获取播放时间片段失败',
|
||
this.dialogContent='设备不在线',
|
||
this.dialogShow=true,
|
||
this.dateLine=[]
|
||
} else {
|
||
this.dialogTitle='获取播放时间片段失败',
|
||
this.dialogContent=res.data.msg,
|
||
this.dialogShow=true,
|
||
this.dateLine=[]
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
// 获取播放时间片段
|
||
getPalyParam: function (e) {
|
||
let stTime = e.detail.stTime;
|
||
let etTime = e.detail.etTime;
|
||
const { type, date, accessToken, deviceSerial, channelNo, videoSrc } = this;
|
||
console.log('当前播放时间', stTime, etTime);
|
||
let startTime = null;
|
||
let stopTime = null;
|
||
startTime = date + ' ' + stTime;
|
||
stopTime = date + ' ' + etTime;
|
||
const param = {
|
||
accessToken: accessToken,
|
||
channelNo: channelNo,
|
||
deviceSerial: deviceSerial,
|
||
protocol: 3,
|
||
// 流播放协议,1-ezopen、2-hls、3-rtmp
|
||
startTime: startTime,
|
||
stopTime: stopTime,
|
||
type: type,
|
||
// 由页面按钮传入值
|
||
expireTime: 86400
|
||
};
|
||
// 获取播放地址
|
||
this.getPlayUrl(param);
|
||
this.param=param
|
||
},
|
||
|
||
// 获取播放地址
|
||
getPlayUrl(param) {
|
||
var _this = this;
|
||
uni.request({
|
||
url: `${OPEN_DOMAIN}/api/lapp/v2/live/address/get`,
|
||
method: 'POST',
|
||
data: param,
|
||
header: {
|
||
'content-type': 'application/x-www-form-urlencoded' // 默认值
|
||
},
|
||
|
||
success: (res) => {
|
||
console.log('获取到的播放地址:', res.data);
|
||
if (res.data.code == '200' && res.data.data && res.data.data.url) {
|
||
const playUrl = res.data.data.url;
|
||
this.videoSrc=playUrl
|
||
// 先停止
|
||
this.handleStop();
|
||
// 开始播放
|
||
this.handlePlay();
|
||
console.log('当前播放地址:', this.videoSrc);
|
||
} else if (res.data.code == '20007') {
|
||
debugger;
|
||
this.dialogTitle='获取播放地址失败',
|
||
this.dialogContent='设备不在线',
|
||
this.dialogShow=true
|
||
} else if (res.data.code == '20002') {
|
||
this.dialogTitle='获取播放地址失败',
|
||
this.dialogContent='设备不存在',
|
||
this.dialogShow=true
|
||
} else if (res.data.code == '20001') {
|
||
this.dialogTitle='获取播放地址失败',
|
||
this.dialogContent='摄像头不存在',
|
||
this.dialogShow=true
|
||
} else if (res.data.code == '20018') {
|
||
this.dialogTitle='获取播放地址失败',
|
||
this.dialogContent='用户不拥有该设备',
|
||
this.dialogShow=true
|
||
} else if (res.data.code == '10001') {
|
||
this.dialogTitle='获取播放地址失败',
|
||
this.dialogContent='参数错误',
|
||
this.dialogShow=true
|
||
} else if (res.data.code == '60019') {
|
||
this.dialogTitle='获取播放地址失败',
|
||
this.dialogContent='设备已被加密,无法继续查看,请前往萤石云app解密。',
|
||
this.dialogShow=true
|
||
} else {
|
||
this.dialogTitle='获取播放地址失败',
|
||
this.dialogContent=res.data.msg,
|
||
this.dialogShow=true
|
||
console.log('获取rtmp播放地址失败');
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
checkNetWork() {
|
||
const _this = this;
|
||
uni.getNetworkType({
|
||
success(res) {
|
||
const networkType = res.networkType;
|
||
if (!networkType || networkType === 'none') {
|
||
uni.showToast({
|
||
title: '当前网络异常',
|
||
icon: 'none',
|
||
duration: 2000
|
||
});
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
fullScreenFun() {
|
||
var _this = this;
|
||
livePlayerContext.requestFullScreen({
|
||
direction: 90,
|
||
success: function () {
|
||
_this.fullScreen=true
|
||
}
|
||
});
|
||
console.log('开启全屏');
|
||
},
|
||
|
||
unfullScreen() {
|
||
var _this = this;
|
||
livePlayerContext.exitFullScreen({
|
||
success: function () {
|
||
_this.fullScreen=false
|
||
}
|
||
});
|
||
console.log('开启全屏');
|
||
},
|
||
|
||
ToggleObjectFit() {
|
||
var objectFit = this.objectFit;
|
||
if(objectFit === 'contain'){
|
||
this.objectFit = 'fillCrop'
|
||
}else{
|
||
this.objectFit = 'contain'
|
||
}
|
||
},
|
||
|
||
fullscreenChange(event) {
|
||
console.log('监听到全屏变化', event);
|
||
},
|
||
|
||
handlePlay(callback) {
|
||
console.log('handelPlay', this.playVideo, this.isHD);
|
||
this.checkNetWork();
|
||
livePlayerContext.play({
|
||
success: () => {
|
||
// playVideo: true,
|
||
this.showVideoControls=true,
|
||
// videoLoadingStatus: 100,
|
||
this.videoNetWorkError=false
|
||
if (callback && typeof callback === 'function') {
|
||
callback();
|
||
}
|
||
},
|
||
fail: (error) => {
|
||
this.checkNetWork();
|
||
uni.showToast({
|
||
title: '网络异常',
|
||
icon: 'none'
|
||
});
|
||
console.log('开始播放失败');
|
||
this.videoNetWorkError=true
|
||
this.showVideoControls=false
|
||
this.videoLoadingStatus=100
|
||
}
|
||
});
|
||
},
|
||
|
||
handleStop(callback) {
|
||
console.log('stop');
|
||
const { list } = this;
|
||
livePlayerContext.stop({
|
||
success: () => {
|
||
this.playVideo=false
|
||
this.videoLoadingStatus=0
|
||
this.list=list
|
||
this.panelStatus=0
|
||
if (callback && typeof callback === 'function') {
|
||
callback();
|
||
}
|
||
},
|
||
fail: (error) => {
|
||
console.log('停止播放失败');
|
||
}
|
||
});
|
||
},
|
||
|
||
autoHideControl() {
|
||
console.log('showHdSelect', this.showHDSelect);
|
||
const _this = this;
|
||
clearTimeout(this.autoHideTimer);
|
||
this.autoHideTimer = setTimeout(() => {
|
||
const { showHDSelect } = _this;
|
||
if (!showHDSelect) {
|
||
this.showVideoControls=false
|
||
}
|
||
}, 5000);
|
||
},
|
||
|
||
handleSound(e) {
|
||
var openSound = this.openSound;
|
||
this.openSound=!openSound
|
||
},
|
||
|
||
handleHD(e) {
|
||
var showHDSelect = this.showHDSelect;
|
||
console.log('handleHD', showHDSelect);
|
||
this.showHDSelect=!showHDSelect
|
||
},
|
||
|
||
changeVideoHD(e) {
|
||
var _this = this;
|
||
this.showHDSelect=false,
|
||
this.isHD=true
|
||
this.handleStop(_this.handlePlay);
|
||
},
|
||
|
||
changeVideoNormal(e) {
|
||
this.showHDSelect=false,
|
||
this.isHD=false
|
||
this.handleStop(this.handlePlay);
|
||
},
|
||
|
||
statechange(e) {
|
||
console.log('live-player code:', e.detail.code, e.detail);
|
||
const { code } = e.detail;
|
||
let { videoLoadingStatus, list, panelStatus } = this;
|
||
switch (code) {
|
||
case 2007:
|
||
//启动loading
|
||
videoLoadingStatus = 0;
|
||
this.playVideo=true,
|
||
this.videoLoadingStatus=0
|
||
break;
|
||
case 2001:
|
||
//连接服务器
|
||
videoLoadingStatus = 20 + Math.floor(Math.random() * 10 + 1);
|
||
break;
|
||
case 2002:
|
||
//已经连接 RTMP 服务器,开始拉流
|
||
videoLoadingStatus = 40 + Math.floor(Math.random() * 10 + 1);
|
||
break;
|
||
case 2008:
|
||
// 解码器启动
|
||
break;
|
||
case 2009:
|
||
//视频分辨率改动
|
||
break;
|
||
case 2004:
|
||
// 视频播放开始
|
||
videoLoadingStatus = 80 + Math.floor(Math.random() * 10 + 1);
|
||
break;
|
||
case 2003:
|
||
//网络接收到首个视频数据包(IDR)
|
||
videoLoadingStatus = 100;
|
||
this.playVideo=true,
|
||
this.autoHideControl();
|
||
break;
|
||
case 2103:
|
||
//网络断连, 已启动自动重连(本小程序不自动重连)
|
||
break;
|
||
case 3001:
|
||
case 3002:
|
||
case 3003:
|
||
case 3005:
|
||
// 播放失败
|
||
videoLoadingStatus = 100;
|
||
this.checkNetWork();
|
||
this.handleStop(this.playError);
|
||
this.showVideoControls=false,
|
||
this.videoNetWorkError=true,
|
||
this.videoLoadingStatus=100
|
||
break;
|
||
case -2301:
|
||
// 经多次重连抢救无效,更多重试请自行重启播放
|
||
videoLoadingStatus = 100;
|
||
this.showVideoControls=false,
|
||
this.videoNetWorkError=true,
|
||
this.videoLoadingStatus=100
|
||
break;
|
||
}
|
||
this.videoLoadingStatus=videoLoadingStatus
|
||
this.playCode=code
|
||
},
|
||
|
||
playError() {
|
||
this.showVideoControls=false,
|
||
this.videoNetWorkError=true,
|
||
this.videoLoadingStatus=100
|
||
},
|
||
|
||
error(e) {
|
||
console.log('live-player', e);
|
||
console.error('live-player error:', e.detail.errMsg);
|
||
if (e.detail.errCode == 10001) {
|
||
uni.showToast({
|
||
title: '视频直播对讲需要你手机授权微信录音或麦克风权限',
|
||
icon: 'none',
|
||
duration: 3000
|
||
});
|
||
}
|
||
},
|
||
|
||
onVideoTap(e) {
|
||
console.log('点击视频');
|
||
const { deviceOffline, showVideoControls, panelStatus, videoNetWorkError } = this;
|
||
if (deviceOffline || panelStatus === 4 || videoNetWorkError) {
|
||
return false;
|
||
}
|
||
if (showVideoControls) {
|
||
this.showVideoControls=false
|
||
clearTimeout(this.autoHideTimer);
|
||
} else {
|
||
this.showVideoControls=true
|
||
this.autoHideControl();
|
||
}
|
||
},
|
||
|
||
screenShoot(e) {
|
||
const { playVideo, videoLoadingStatus } = this;
|
||
if (!playVideo || videoLoadingStatus != 100) {
|
||
console.log('非播放状态下点击截图');
|
||
return false;
|
||
}
|
||
console.log('开始截图');
|
||
// livePlayerContext.snapshot('raw');
|
||
let that = this;
|
||
uni.getSetting({
|
||
success(res) {
|
||
if (res.authSetting['scope.writePhotosAlbum']) {
|
||
that.saveImg();
|
||
} else if (res.authSetting['scope.writePhotosAlbum'] === undefined) {
|
||
uni.authorize({
|
||
scope: 'scope.writePhotosAlbum',
|
||
success() {
|
||
that.saveImg();
|
||
},
|
||
fail() {
|
||
that.authConfirm();
|
||
}
|
||
});
|
||
} else {
|
||
that.authConfirm();
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
saveImg() {
|
||
livePlayerContext
|
||
.snapshot('raw')
|
||
.then((data) => {
|
||
console.log('data', data);
|
||
if (data) {
|
||
console.log(data);
|
||
uni.saveImageToPhotosAlbum({
|
||
filePath: data.tempImagePath,
|
||
success(res) {
|
||
console.log('保存成功', res);
|
||
uni.showToast({
|
||
title: '截图已保存至手机相册',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
});
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
console.log('err', err);
|
||
});
|
||
},
|
||
|
||
// 授权拒绝后,再次授权提示弹窗
|
||
authConfirm() {
|
||
let that = this;
|
||
uni.showModal({
|
||
content: '您没打开保存图片权限,是否去设置打开?',
|
||
confirmText: '确认',
|
||
cancelText: '取消',
|
||
success: function (res) {
|
||
if (res.confirm) {
|
||
uni.openSetting({
|
||
success: (res) => {
|
||
if (res.authSetting['scope.writePhotosAlbum']) {
|
||
that.saveImg();
|
||
} else {
|
||
uni.showToast({
|
||
title: '您没有授权,无法保存到相册',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
}
|
||
});
|
||
} else {
|
||
uni.showToast({
|
||
title: '您没有授权,无法保存到相册',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
tapDialogButton(e) {
|
||
this.dialogShow=false
|
||
this.pageBack();
|
||
},
|
||
|
||
pageBack() {
|
||
uni.navigateBack({
|
||
delta: 1
|
||
});
|
||
},
|
||
|
||
// 时间选择器
|
||
bindDateChange: function (e) {
|
||
console.log('picker发送选择改变,携带值为', e.detail.value);
|
||
this.date=e.detail.value
|
||
this.getTimeLine();
|
||
},
|
||
|
||
// 返回直播
|
||
goToLive() {
|
||
const { accessToken, deviceSerial, channelNo } = this;
|
||
let url = '/packDetail1/pages/device/index1?accessToken=' + accessToken + '&deviceSerial=' + deviceSerial + '&channelNo=' + channelNo;
|
||
uni.navigateTo({
|
||
url: url
|
||
});
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
<style>
|
||
@import './playback.css';
|
||
</style>
|