yfs-video.vue 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163
  1. <template>
  2. <view class="bbl-content">
  3. <view class="uni-padding-wrap uni-common-mt">
  4. <view class="bbl-content_video">
  5. <!-- #ifdef H5 -->
  6. <EasyPlayer v-model="videoUrl" :muted="muted" ref="easyPlayer" live :reconnection="true"></EasyPlayer>
  7. <!-- #endif -->
  8. <!-- #ifndef H5 -->
  9. <video id="myVideo" :src="videoUrl" :autoplay="autoplay" :muted="muted" :loop="loop"
  10. :initial-time="initialtime" :duration="duration" :controls="controls"
  11. :show-center-play-btn="showcenterplaybtn" :danmu-list="danmuList" :enable-danmu="enabledanmu"
  12. :page-gesture="pagegesture" :direction="90" :show-play-btn="false" :show-fullscreen-btn="true"
  13. :objectFit="objectFit" :poster="poster" :enable-progress-gesture="false"
  14. :enable-play-gesture="enableplaygesture" :videoTitle="videoTitle" @play="Clickplay"
  15. @pause="Clickpause" @error="videoErrorCallback" @ended="Clickended" @timeupdate="Clicktimeupdate"
  16. @loadedmetadata="loadedmetadata" @fullscreenchange="Clickfullscreenchange" @waiti="Clickwaitin"
  17. @click="clk" @waiting="waiting">
  18. <!--顶部栏 竖屏-->
  19. <view class="video-control" v-if="isMenu && showLeftBack" @tap.stop>
  20. <view class="video-control-back" @tap.native.stop="backup">
  21. <cover-image :src="settingFile.root_img+'/static/app/yfs-video/backup.png'"></cover-image>
  22. </view>
  23. <view class="video-control-text" v-if="isFullScree" @tap.native.stop="backup">
  24. {{ ResVideoTitle }}
  25. </view>
  26. <view class="video-control-more" v-if="isFullScree">
  27. <cover-image :src="settingFile.root_img+'/static/app/yfs-video/more.png'"></cover-image>
  28. </view>
  29. </view>
  30. <!--全屏左侧锁定-->
  31. <view class="video-hz-lock" v-if="isFullScree && isMenu" @tap.native.stop="lock">
  32. <cover-image :src="srcLock"></cover-image>
  33. </view>
  34. <!--全屏右侧截屏-->
  35. <!-- <view class="video-hz-jp" @tap.native.stop="tapImg">
  36. <cover-image :src="srcLock"></cover-image>
  37. </view> -->
  38. <!--底部栏 竖屏 非全屏-->
  39. <view class="video-control-bottom" v-if="isMenu && !isFullScree" @tap.native.stop>
  40. <!--播放暂停区域-->
  41. <view class="video-control-bottom-playOrPause" @tap.native.stop="playPause">
  42. <cover-image :src="playOrPauseSrc" mode="aspectFit"></cover-image>
  43. </view>
  44. <!--时间区域-->
  45. <view class="video-control-bottom-time">{{ currtime }}/{{ druation }}</view>
  46. <!--进度条区域-->
  47. <view class="video-control-bottom-bar" :style="[{ width: dotBaseWidth + 'rpx' }]">
  48. <!--灰色进度条区域-->
  49. <view class="video-control-bottom-bar-gray">
  50. <!--动态有进度进度条区域-->
  51. <view class="video-control-bottom-bar-color" :style="[{ width: dotSlide + 'rpx' }]">
  52. </view>
  53. </view>
  54. <view class="video-control-bottom-bar-dot" :style="[{ left: dotSlide + 'rpx' }]"
  55. @touchmove.stop.prevent="moveDot" @touchstart="touchstartDot" @touchend="touchendDot">
  56. <view class="video-control-bottom-bar-dot-pad"></view>
  57. </view>
  58. </view>
  59. <!--全屏按钮区域-->
  60. <view class="video-control-bottom-fullScree" @tap.native.stop="fullscree">
  61. <cover-image :src="settingFile.root_img+'/static/app/yfs-video/full.png'"></cover-image>
  62. </view>
  63. </view>
  64. <!--底部栏 竖屏 全屏-->
  65. <view class="video-control-bottom" v-if="isMenu && isFullScree" @tap.stop>
  66. <!--播放暂停区域-->
  67. <view class="video-control-bottom-playOrPause" @tap.native.stop="playPause">
  68. <cover-image :src="playOrPauseSrc" mode="aspectFit"></cover-image>
  69. </view>
  70. <!--时间区域-->
  71. <view class="video-control-bottom-time">{{ currtime }}/{{ druation }}</view>
  72. <!--进度条区域-->
  73. <view class="video-control-bottom-bar" :style="[{ width: dotBaseWidth + 'rpx' }]">
  74. <!--灰色进度条区域-->
  75. <view class="video-control-bottom-bar-gray">
  76. <!--动态有进度进度条区域-->
  77. <view class="video-control-bottom-bar-color" :style="[{ width: dotSlide + 'rpx' }]">
  78. </view>
  79. </view>
  80. <view class="video-control-bottom-bar-dot" :style="[{ left: dotSlide + 'rpx' }]"
  81. @touchmove.stop.prevent="moveDot" @touchstart="touchstartDot" @touchend="touchendDot">
  82. <view class="video-control-bottom-bar-dot-pad"></view>
  83. </view>
  84. </view>
  85. <view class="video-fullScree-speed" @tap.native.stop="showSwitchRate">x {{ currentRate }}
  86. </view>
  87. <!--全屏按钮区域-->
  88. <view class="video-control-bottom-fullScree" @tap.native.stop="fullscree">
  89. <cover-image :src="settingFile.root_img+'/static/app/yfs-video/exitfull.png'"></cover-image>
  90. </view>
  91. </view>
  92. <!--上顶菜单栏-->
  93. <view class="multi-list rate" :class="{ active: rateShow }" @tap.native.stop>
  94. <view v-for="(item, index) in ['0.5', '0.8', '1.0', '1.25', '1.5']" :key="index"
  95. class="multi-item rate" :data-rate="item" @tap="switchRate"
  96. :class="{ active: item == currentRate }">
  97. {{ item }}
  98. </view>
  99. </view>
  100. </video>
  101. <!-- #endif -->
  102. <view v-if="hasptz==1" class="outer-ring">
  103. <view class="control-wrapper">
  104. <view @touchstart="PtzCtrl(1,'ptz1')" id="ptz1" @touchend="onMouseOut('ptz1')"
  105. :class="ptzid=='ptz1'?'control-btn control-top selectbtn':'control-btn control-top'"></view>
  106. <view @touchstart="PtzCtrl(7,'ptz7')" id="ptz7" @touchend="onMouseOut('ptz7')"
  107. :class="ptzid=='ptz7'?'control-btn control-left selectbtn':'control-btn control-left'">
  108. </view>
  109. <view @touchstart="PtzCtrl(4,'ptz4')" id="ptz4" @touchend="onMouseOut('ptz4')"
  110. :class="ptzid=='ptz4'?'control-btn control-bottom selectbtn':'control-btn control-bottom'">
  111. </view>
  112. <view @touchstart="PtzCtrl(8,'ptz8')" id="ptz8" @touchend="onMouseOut('ptz8')"
  113. :class="ptzid=='ptz8'?'control-btn control-right selectbtn':'control-btn control-right'">
  114. </view>
  115. <view class="control-round">
  116. <view :class="ptzid=='ptz9'?'inner-ring1':(ptzid=='ptz10'?'inner-ring2':'inner-ring')">
  117. <view class="anticon anticon-plus plus" style="border: none;">
  118. <u-icon @touchstart="PtzCtrl(9,'ptz9')" id="ptz9" @touchend="onMouseOut('ptz9')"
  119. name="plus" size="20"></u-icon>
  120. </view>
  121. <view class="line"></view>
  122. <view class="anticon anticon-minus minus" style="border: none;">
  123. <u-icon @touchstart="PtzCtrl(10,'ptz10')" id="ptz10" @touchend="onMouseOut('ptz10')"
  124. name="minus" size="20"></u-icon>
  125. </view>
  126. </view>
  127. </view>
  128. </view>
  129. </view>
  130. </view>
  131. </view>
  132. </view>
  133. </template>
  134. <script>
  135. import home from '@/api/home/index.js';
  136. // #ifdef H5
  137. import EasyPlayer from "@easydarwin/easyplayer"
  138. // #endif
  139. export default {
  140. props: {
  141. src: {
  142. //视频路径
  143. type: String,
  144. default: ''
  145. },
  146. videoTitle: {
  147. //视频标题
  148. type: String,
  149. default: ''
  150. },
  151. autoplay: {
  152. //是否自播放
  153. type: Boolean,
  154. default: true
  155. },
  156. showcenterplaybtn: {
  157. //视频中间按钮
  158. type: Boolean,
  159. default: false
  160. },
  161. loop: {
  162. //是否循环播放
  163. type: Boolean,
  164. default: false
  165. },
  166. muted: {
  167. //是否静音播放
  168. type: Boolean,
  169. default: false
  170. },
  171. initialtime: {
  172. //指定视频初始播放位置 单位为秒(s)
  173. type: Number,
  174. default: 0
  175. },
  176. showLeftBack: {
  177. type: Boolean,
  178. default: false
  179. },
  180. duration: {
  181. //指定视频时长
  182. type: Number,
  183. default: 0
  184. },
  185. danmuList: {
  186. //弹幕列表
  187. type: Array,
  188. default: () => []
  189. },
  190. enabledanmu: {
  191. //是否展示弹幕,只在初始化时有效,不能动态变更
  192. type: Boolean,
  193. default: false
  194. },
  195. pagegesture: {
  196. //在非全屏模式下,是否开启亮度与音量调节手势
  197. type: Boolean,
  198. default: false
  199. },
  200. controls: {
  201. //在非全屏模式下,是否开启亮度与音量调节手势
  202. type: Boolean,
  203. default: true
  204. },
  205. objectFit: {
  206. //当视频大小与 video 容器大小不一致时,视频的表现形式。contain:包含,fill:填充,cover:覆盖
  207. type: String,
  208. default: 'contain'
  209. },
  210. poster: {
  211. //视频封面的图片网络资源地址,如果 controls 属性值为 false 则设置 poster 无效
  212. type: String,
  213. default: ''
  214. },
  215. enableplaygesture: {
  216. //是否开启播放手势,即双击切换播放/暂停
  217. type: Boolean,
  218. default: true
  219. },
  220. isMenu: {
  221. //是否显示控制面板
  222. type: Boolean,
  223. default: false
  224. }
  225. },
  226. components: {
  227. // #ifdef H5
  228. EasyPlayer
  229. // #endif
  230. },
  231. data() {
  232. return {
  233. videoUrl: '',
  234. input: '',
  235. startVideotape: false,
  236. settingFile: getApp().globalData.siteinfo,
  237. rateShow: false, //是否显示播放速度选项
  238. fullControlsWidth: 0, //屏幕窗口宽度
  239. fullControlsHeigt: 0, //屏幕窗口高度
  240. currentRate: '1.0', //当前播放速度
  241. videoCtx: '', //视频上下文
  242. touchStartTime: 0, //双击视频播放还是暂停
  243. damu: {}, //弹幕
  244. dotLeftBase: 0, //基础偏移度 初步计算为滑块的半径 现在 为0
  245. dotSlide: 0, //进度
  246. dotBaseWidth: 0, //进度条计算后宽度
  247. currtime: '00:00:00', //当前播放时间 字符串 计算后
  248. druation: '00:00:00', //总时间 字符串 计算后
  249. durationInt: 0, //总时间
  250. currentInt: 0, //当前播放时间
  251. isPlay: false, //是否播放
  252. isFullScree: false, //是否全屏
  253. // ismoregn:false,
  254. rdo: 0.94, //基础比例 为了设置进度条
  255. playOrPauseSrc: getApp().globalData.siteinfo.siteroot + '/public/static/app/yfs-video/play.png', //播放或者暂停图片
  256. srcLock: getApp().globalData.siteinfo.siteroot + '/public/static/app/yfs-video/uplock.png', //锁住横屏
  257. isLock: false, //是否锁屏
  258. hasptz: 0,
  259. did: 0,
  260. ptzid: '',
  261. };
  262. },
  263. mounted() {
  264. },
  265. destroyed() {
  266. },
  267. created() {
  268. },
  269. onResize: function() {
  270. },
  271. methods: {
  272. PtzCtrl(ptztype, id) {
  273. let that = this;
  274. that.ptzid = id;
  275. let pdata = {
  276. id: that.did,
  277. ptztype: ptztype,
  278. speed: 250
  279. };
  280. home.ptzctrl(pdata).then(res => {
  281. if (res.status != 200) {
  282. that.$api.msg(res.msg);
  283. }
  284. });
  285. },
  286. onMouseOut(id) {
  287. let that = this;
  288. let pdata = {
  289. id: that.did,
  290. ptztype: 0,
  291. speed: 250
  292. };
  293. setTimeout(function() {
  294. that.ptzid = '';
  295. }, 100)
  296. setTimeout(function() {
  297. home.ptzctrl(pdata).then(res => {
  298. if (res.status != 200) {
  299. that.$api.msg(res.msg);
  300. }
  301. });
  302. }, 1000)
  303. },
  304. playvideo(_src, _did = 0, _hasptz = 0) {
  305. this.hasptz = _hasptz;
  306. this.did = _did;
  307. this.videoUrl = _src
  308. },
  309. player() {
  310. if (!this.input) {
  311. this.$api.msg('播放地址错误!');
  312. } else {
  313. this.videoUrl = this.input
  314. }
  315. },
  316. //保存快照
  317. saveSnap() {
  318. if (!this.videoUrl) {
  319. this.$api.msg('播放地址错误!');
  320. } else {
  321. this.$refs.easyPlayer.saveLocalSnapshot()
  322. }
  323. },
  324. //录像
  325. videotape() {
  326. if (!this.videoUrl) {
  327. this.$api.msg('播放地址错误!');
  328. } else {
  329. if (this.$refs.easyPlayer.switchRecording) {
  330. this.$refs.easyPlayer.switchRecording()
  331. this.startVideotape = !this.startVideotape
  332. }
  333. }
  334. },
  335. play() {
  336. this.$refs.easyPlayer.play()
  337. },
  338. pause() {
  339. this.$refs.easyPlayer.pause()
  340. },
  341. switchAudio() {
  342. this.$refs.easyPlayer.switchAudio()
  343. this.muted = !this.muted
  344. },
  345. fullScreen() {
  346. this.$refs.easyPlayer.fullscreen()
  347. },
  348. loadedmetadata: function() {
  349. console.log('loadedmetadata')
  350. this.closeloading();
  351. },
  352. waiting: function() {
  353. console.log('waiting')
  354. this.closeloading();
  355. },
  356. closeloading: function() {
  357. setTimeout(function() {
  358. uni.hideLoading();
  359. }, 1000)
  360. },
  361. videoErrorCallback: function(e) {
  362. console.log(e);
  363. let that = this;
  364. that.closeloading();
  365. },
  366. sendDanMu: function(obj) {
  367. //发送弹幕
  368. let that = this;
  369. that.videoCtx.sendDanmu(obj);
  370. },
  371. Clickplay: function(e) {
  372. let that = this;
  373. that.isPlay = true;
  374. that.playOrPauseSrc = that.settingFile.siteroot + '/public/static/app/yfs-video/pause.png';
  375. },
  376. Clickpause: function(e) {
  377. let that = this;
  378. that.isPlay = false;
  379. that.playOrPauseSrc = that.settingFile.siteroot + '/public/static/app/yfs-video/play.png';
  380. },
  381. Clickended: function() {
  382. //当播放到末尾时触发 ended 事件
  383. console.log('ended');
  384. },
  385. Clicktimeupdate: function(event) {
  386. let that = this;
  387. //播放进度变化时触发,event.detail = {currentTime, duration} 。触发频率 250ms 一次
  388. that.$emit('getTimeVideo', event.detail.currentTime);
  389. that.dotSlide = (event.detail.currentTime / event.detail.duration) * that.dotBaseWidth * that.rdo;
  390. that.druation = that.formatSeconds(event.detail.duration);
  391. that.currtime = that.formatSeconds(event.detail.currentTime);
  392. that.durationInt = event.detail.duration;
  393. that.currentInt = event.detail.currentTime;
  394. },
  395. Clickfullscreenchange: function(e) {
  396. let that = this;
  397. if (!that.isFullScree) {
  398. that.dotBaseWidth = that.fullControlsHeigt * 1.4;
  399. } else {
  400. that.dotBaseWidth = that.fullControlsWidth * 1.2;
  401. }
  402. that.isFullScree = !that.isFullScree;
  403. },
  404. Clickwaitin: function() {
  405. //视频出现缓冲时触发
  406. console.log('Clickwaitin');
  407. },
  408. showSwitchRate: function(rate) {
  409. let that = this;
  410. that.rateShow = true;
  411. },
  412. switchRate: function(e) {
  413. let that = this;
  414. let rate = Number(e.currentTarget.dataset.rate);
  415. that.currentRate = rate;
  416. that.rateShow = false;
  417. that.videoCtx.playbackRate(rate * 1);
  418. if (!that.isPlay) {
  419. that.videoCtx.play();
  420. }
  421. },
  422. clk: function() {
  423. //video点击事件
  424. let that = this;
  425. that.rateShow = false;
  426. if (!that.isPlay) {
  427. that.videoCtx.play();
  428. } else {
  429. // that.videoCtx.pause();
  430. }
  431. },
  432. formatSeconds(a) {
  433. var hh = parseInt(a / 3600);
  434. var mm = parseInt((a - hh * 3600) / 60);
  435. if (mm < 10) mm = '0' + mm;
  436. var ss = parseInt((a - hh * 3600) % 60);
  437. if (ss < 10) ss = '0' + ss;
  438. if (hh < 10) hh = hh == 0 ? '' : `0${hh}:`;
  439. var length = hh + mm + ':' + ss;
  440. if (a >= 0) {
  441. return length;
  442. } else {
  443. return '00:00';
  444. }
  445. },
  446. playPause: function() {
  447. let that = this;
  448. if (!that.isPlay) {
  449. that.videoCtx.play();
  450. } else {
  451. // that.videoCtx.pause();
  452. }
  453. },
  454. fullscree: function() {
  455. let that = this;
  456. if (that.isLock) {
  457. return false;
  458. }
  459. if (!that.isFullScree) {
  460. that.videoCtx.requestFullScreen({
  461. direction: 'horizontal'
  462. });
  463. that.dotBaseWidth = that.fullControlsHeigt * 1.4;
  464. } else {
  465. that.videoCtx.exitFullScreen();
  466. that.dotBaseWidth = that.fullControlsWidth * 1.2;
  467. }
  468. },
  469. backup: function() {
  470. let that = this;
  471. if (that.isFullScree) {
  472. that.fullscree();
  473. return false;
  474. }
  475. uni.navigateBack();
  476. },
  477. moregn: function() {
  478. this.ismoregn = !this.ismoregn;
  479. },
  480. hideModal: function() {
  481. this.ismoregn = false;
  482. },
  483. moveDot: function(e) {
  484. //进度条移动点 触摸移动
  485. // 单指触摸 不是单指触摸不移动
  486. let that = this;
  487. if (e.touches.length !== 1) {
  488. return false;
  489. }
  490. that.dotSlide = e.touches[0].clientX;
  491. if (that.dotSlide < 0) {
  492. //左边界
  493. that.dotSlide = 0;
  494. }
  495. if (that.dotSlide > that.dotBaseWidth * that.rdo) {
  496. //右边界
  497. that.dotSlide = that.dotBaseWidth * that.rdo;
  498. }
  499. let time = (that.dotSlide / that.dotBaseWidth) * that.rdo * that.durationInt;
  500. that.currentInt = time;
  501. that.currtime = that.formatSeconds(time);
  502. that.videoCtx.seek(time);
  503. },
  504. touchstartDot: function(e) {
  505. //进度条移动点 触摸开始
  506. // this.initX = e.changedTouches[0].clientX;
  507. console.log('startdot');
  508. },
  509. touchendDot: function(e) {
  510. console.log('enddot');
  511. },
  512. lock: function() {
  513. if (this.isLock) {
  514. this.srcLock = this.settingFile.siteroot + '/public/static/app/yfs-video/uplock.png';
  515. } else {
  516. this.srcLock = this.settingFile.siteroot + '/public/static/app/yfs-video/downlock.png';
  517. }
  518. this.isLock = !this.isLock;
  519. }
  520. }
  521. };
  522. </script>
  523. <style>
  524. .selectbtn {
  525. color: black;
  526. background: #1298c8;
  527. }
  528. .control-wrapper {
  529. position: relative;
  530. width: 50vw;
  531. height: 50vw;
  532. max-width: 300px;
  533. max-height: 300px;
  534. min-width: 240px;
  535. min-height: 240px;
  536. margin: 0 auto;
  537. border-radius: 50%;
  538. background: transparent;
  539. }
  540. .control-btn {
  541. position: absolute;
  542. width: 38%;
  543. height: 38%;
  544. display: flex;
  545. align-items: center;
  546. justify-content: center;
  547. border: 1px solid #78aee4;
  548. box-sizing: border-box;
  549. transition: all .3s linear;
  550. }
  551. .control-btn:after {
  552. content: '';
  553. position: absolute;
  554. width: 60%;
  555. height: 60%;
  556. background: #fff;
  557. z-index: 2;
  558. }
  559. .control-btn:before {
  560. content: '';
  561. position: relative;
  562. display: block;
  563. width: 16px;
  564. height: 16px;
  565. border-top: 3px solid #78aee4;
  566. border-right: 3px solid #78aee4;
  567. border-radius: 0 4px 0 0;
  568. box-sizing: border-box;
  569. z-index: 2;
  570. }
  571. .control-top {
  572. top: 0;
  573. left: 50%;
  574. transform: translateX(-50%) rotate(-45deg);
  575. border-radius: 4px 100% 4px 4px;
  576. }
  577. .control-top:before {
  578. transform: translate(30%, -25%);
  579. }
  580. .control-top:after {
  581. left: 0;
  582. bottom: 0;
  583. border-top: 1px solid #78aee4;
  584. border-right: 1px solid #78aee4;
  585. border-radius: 0 100% 0 0;
  586. }
  587. .control-bottom {
  588. left: 50%;
  589. bottom: 0;
  590. transform: translateX(-50%) rotate(45deg);
  591. border-radius: 4px 4px 100% 4px;
  592. }
  593. .control-bottom:before {
  594. transform: translate(25%, 25%) rotate(90deg);
  595. }
  596. .control-bottom:after {
  597. top: 0;
  598. left: 0;
  599. border-bottom: 1px solid #78aee4;
  600. border-right: 1px solid #78aee4;
  601. border-radius: 0 0 100% 0;
  602. }
  603. .control-left {
  604. top: 50%;
  605. left: 0;
  606. transform: translateY(-50%) rotate(45deg);
  607. border-radius: 4px 4px 4px 100%;
  608. }
  609. .control-left:before {
  610. transform: translate(-25%, 30%) rotate(180deg);
  611. }
  612. .control-left:after {
  613. right: 0;
  614. top: 0;
  615. border-bottom: 1px solid #78aee4;
  616. border-left: 1px solid #78aee4;
  617. border-radius: 0 0 0 100%;
  618. }
  619. .control-right {
  620. top: 50%;
  621. right: 0;
  622. transform: translateY(-50%) rotate(45deg);
  623. border-radius: 4px 100% 4px 4px;
  624. }
  625. .control-right:before {
  626. transform: translate(30%, -25%);
  627. }
  628. .control-right:after {
  629. left: 0;
  630. bottom: 0;
  631. border-top: 1px solid #78aee4;
  632. border-right: 1px solid #78aee4;
  633. border-radius: 0 100% 0 0;
  634. }
  635. .control-round {
  636. position: absolute;
  637. top: 50%;
  638. left: 50%;
  639. transform: translate(-50%, -50%);
  640. width: 51.2%;
  641. height: 51.2%;
  642. background: #fff;
  643. border-radius: 50%;
  644. }
  645. .control-round-inner {
  646. position: absolute;
  647. top: 50%;
  648. left: 50%;
  649. transform: translate(-50%, -50%);
  650. display: flex;
  651. justify-content: center;
  652. align-items: center;
  653. width: 66%;
  654. height: 66%;
  655. border: 1px solid #78aee4;
  656. border-radius: 50%;
  657. }
  658. .control-round-inner:after {
  659. content: "| |";
  660. display: block;
  661. width: 50px;
  662. line-height: 50px;
  663. text-align: center;
  664. font-weight: bolder;
  665. color: #fff;
  666. border-radius: 50%;
  667. }
  668. .outer-ring .inner-ring .line {
  669. height: 1px;
  670. width: 100%;
  671. background-color: #ddd;
  672. position: absolute;
  673. top: 50px;
  674. left: 0;
  675. }
  676. .outer-ring .inner-ring {
  677. position: absolute;
  678. top: 50%;
  679. left: 50%;
  680. transform: translate(-50%, -50%);
  681. width: 100px;
  682. height: 100px;
  683. border-radius: 50%;
  684. background-color: #fff;
  685. border: 1px solid #ddd;
  686. }
  687. .outer-ring .inner-ring1 {
  688. position: absolute;
  689. top: 50%;
  690. left: 50%;
  691. transform: translate(-50%, -50%);
  692. width: 100px;
  693. height: 100px;
  694. border-radius: 50%;
  695. background-color: #fff;
  696. border: 1px solid #ddd;
  697. background: linear-gradient(to top,
  698. white 0%,
  699. white 50%,
  700. #1298c8 50.01%,
  701. #1298c8 100%);
  702. }
  703. .outer-ring .inner-ring2 {
  704. position: absolute;
  705. top: 50%;
  706. left: 50%;
  707. transform: translate(-50%, -50%);
  708. width: 100px;
  709. height: 100px;
  710. border-radius: 50%;
  711. background-color: #fff;
  712. border: 1px solid #ddd;
  713. background: linear-gradient(to bottom,
  714. white 0%,
  715. white 50%,
  716. #1298c8 50.01%,
  717. #1298c8 100%);
  718. }
  719. .outer-ring .inner-ring .minus {
  720. position: absolute;
  721. bottom: 15px;
  722. left: 41px;
  723. }
  724. .outer-ring .inner-ring .plus {
  725. position: absolute;
  726. top: 15px;
  727. left: 41px;
  728. }
  729. .outer-ring .inner-ring1 .minus {
  730. position: absolute;
  731. bottom: 15px;
  732. left: 41px;
  733. }
  734. .outer-ring .inner-ring1 .plus {
  735. position: absolute;
  736. top: 15px;
  737. left: 41px;
  738. }
  739. .outer-ring .inner-ring2 .minus {
  740. position: absolute;
  741. bottom: 15px;
  742. left: 41px;
  743. }
  744. .outer-ring .inner-ring2 .plus {
  745. position: absolute;
  746. top: 15px;
  747. left: 41px;
  748. }
  749. video {
  750. width: 100%;
  751. height: 419rpx;
  752. }
  753. video::-webkit-media-controls {
  754. display: none !important;
  755. }
  756. .bbl-content {
  757. width: 100%;
  758. }
  759. .bbl-content_video {
  760. width: 100%;
  761. height: 419rpx;
  762. }
  763. .uni-padding-wrap.uni-common-mt {
  764. width: 100%;
  765. }
  766. #myVideo {
  767. width: 100%;
  768. height: 419rpx;
  769. }
  770. .video {
  771. width: 100%;
  772. }
  773. .video-wrap {
  774. position: relative;
  775. }
  776. .multi-list.full-screen.vertical {
  777. height: 100vh !important;
  778. padding: 8vh 0;
  779. }
  780. .multi-list.full-screen.horizontal {
  781. height: 100vw !important;
  782. padding: 8vw 0;
  783. }
  784. .multi {
  785. position: absolute;
  786. right: 30rpx;
  787. top: 50%;
  788. transform: translateY(-50%);
  789. z-index: 998;
  790. width: 100rpx;
  791. color: red;
  792. padding: 10rpx 0;
  793. text-align: center;
  794. transition: color ease 0.3s;
  795. }
  796. .multi.rate {
  797. right: 30rpx;
  798. color: red;
  799. }
  800. .multi-list {
  801. position: absolute;
  802. height: 100%;
  803. width: 0;
  804. background-color: rgba(0, 0, 0, 0.65);
  805. top: 0;
  806. right: 0;
  807. transition: width 0.3s ease;
  808. z-index: 999;
  809. box-sizing: border-box;
  810. padding: 50rpx 0;
  811. }
  812. .multi-list.rate {
  813. padding: 25rpx 0;
  814. }
  815. .multi-list.active {
  816. width: 300rpx;
  817. }
  818. .multi-item {
  819. text-align: center;
  820. color: #fff;
  821. line-height: 80rpx;
  822. transition: color ease 0.3s;
  823. }
  824. .multi-item.rate {
  825. line-height: 70rpx;
  826. }
  827. .multi-item:hover,
  828. .multi:hover {
  829. color: #00d8ff;
  830. }
  831. .multi-item.active {
  832. color: #00d8ff;
  833. }
  834. .cuIcon-more.text-white {
  835. color: #ffffff;
  836. font-size: 40upx;
  837. }
  838. .video-contrl-top {
  839. height: 80upx;
  840. line-height: 80upx;
  841. min-height: 80upx;
  842. display: flex;
  843. padding: 0;
  844. z-index: 999;
  845. background-color: rgba(0, 0, 0, 0.1);
  846. background: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.1)));
  847. background: -o-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5));
  848. background: linear-gradient(to bottom, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1));
  849. }
  850. .cu-list-tb {
  851. width: 60upx;
  852. height: 60upx;
  853. border-radius: 50%;
  854. background: #cccccc;
  855. padding: auto;
  856. margin: auto;
  857. text-align: center;
  858. height: auto;
  859. line-height: 60upx;
  860. align-items: center;
  861. }
  862. .cu-list {
  863. align-items: flex-start;
  864. justify-items: left;
  865. text-align: left;
  866. padding: 30upx 0;
  867. }
  868. .video-control {
  869. background-color: rgba(0, 0, 0, 0.2);
  870. height: 80upx;
  871. position: absolute;
  872. top: 0;
  873. left: 0;
  874. width: 100%;
  875. z-index: 999;
  876. flex-direction: row;
  877. display: flex;
  878. }
  879. .video-control-back {
  880. position: relative;
  881. width: 74rpx;
  882. height: 100%;
  883. line-height: 80upx;
  884. }
  885. .video-control-back cover-image {
  886. position: absolute;
  887. top: 20rpx;
  888. left: 10rpx;
  889. width: 50%;
  890. height: 50%;
  891. }
  892. .video-control-text {
  893. color: #ffffff;
  894. width: 70%;
  895. height: 100%;
  896. text-align: left;
  897. line-height: 80upx;
  898. overflow: hidden;
  899. text-overflow: ellipsis;
  900. display: -webkit-box;
  901. word-break: break-all;
  902. -webkit-box-orient: vertical;
  903. -webkit-line-clamp: 1;
  904. }
  905. .video-control-more {
  906. position: relative;
  907. height: 100%;
  908. width: 80upx;
  909. margin-left: 10%;
  910. }
  911. .video-control-more cover-image {
  912. position: absolute;
  913. top: 20rpx;
  914. left: 10rpx;
  915. width: 50%;
  916. height: 50%;
  917. }
  918. /* 底部栏样式 */
  919. .video-control-bottom {
  920. background-color: rgba(0, 0, 0, 0.2);
  921. height: 60rpx;
  922. position: absolute;
  923. padding-top: 10rpx;
  924. line-height: 60rpx;
  925. padding: 5upx;
  926. bottom: 0;
  927. left: 0;
  928. width: 100%;
  929. z-index: 999;
  930. display: flex;
  931. align-items: center;
  932. justify-items: center;
  933. }
  934. .video-control-bottom-playOrPause {
  935. height: 80%;
  936. width: 48rpx;
  937. align-items: center;
  938. justify-items: center;
  939. padding-top: 10rpx;
  940. flex-shrink: none;
  941. }
  942. .video-control-bottom-playOrPause cover-image {
  943. width: 80%;
  944. height: 80%;
  945. margin: auto;
  946. }
  947. .video-control-bottom-time {
  948. height: 80%;
  949. width: 185rpx;
  950. line-height: 48rpx;
  951. align-items: center;
  952. justify-items: center;
  953. text-align: center;
  954. margin-right: 10upx;
  955. flex-shrink: none;
  956. color: #ffffff;
  957. font-size: 20rpx;
  958. }
  959. .video-control-bottom-bar {
  960. height: 80%;
  961. line-height: 48rpx;
  962. align-items: center;
  963. justify-items: center;
  964. flex-shrink: none;
  965. padding: 0 10rpx;
  966. }
  967. .video-control-bottom-bar-gray {
  968. background-color: #fcf7e9;
  969. position: relative;
  970. height: 5rpx;
  971. width: 94%;
  972. top: 45%;
  973. left: 12.5rpx;
  974. right: 12.5rpx;
  975. border-radius: 5rpx;
  976. }
  977. .video-control-bottom-bar-color {
  978. height: 100%;
  979. background-color: #e54d42;
  980. }
  981. .video-control-bottom-bar-dot {
  982. position: relative;
  983. width: 25rpx;
  984. height: 25rpx;
  985. line-height: 15rpx;
  986. border-radius: 50%;
  987. top: 15%;
  988. background-color: rgba(255, 0, 0, 0.3);
  989. box-shadow: -1px 1px 1px 2px rgba(255, 255, 255, 0.1), -1px 1px 1px 0 rgba(0, 0, 0, 0.1) inset;
  990. }
  991. .video-control-bottom-bar-dot-pad {
  992. width: 15upx;
  993. height: 15upx;
  994. border-radius: 50%;
  995. background: #e54d42;
  996. /* box-shadow: 0 0 2px 0 rgba(0,0,0,0.2) inset; */
  997. position: absolute;
  998. left: 0;
  999. top: 0;
  1000. right: 0;
  1001. bottom: 0;
  1002. margin: auto;
  1003. }
  1004. .video-control-bottom-fullScree {
  1005. height: 25rpx;
  1006. width: 25rpx;
  1007. flex-shrink: none;
  1008. margin-right: 10rpx;
  1009. }
  1010. .video-control-bottom-fullScree cover-image {
  1011. width: 100%;
  1012. height: 100%;
  1013. }
  1014. .video-control-item {
  1015. color: #cccccc;
  1016. padding: 2rpx;
  1017. margin-top: 10rpx;
  1018. width: 100%;
  1019. }
  1020. .video-heizith-menu {
  1021. position: absolute;
  1022. right: 0;
  1023. top: 20%;
  1024. z-index: 998;
  1025. /* background-color: rgba(0,0,0,0.1); */
  1026. height: 100rpx;
  1027. width: 80rpx;
  1028. padding: 10rpx;
  1029. padding-top: 30rpx;
  1030. border-top-left-radius: 10rpx;
  1031. border-bottom-left-radius: 10rpx;
  1032. line-height: 200rpx;
  1033. align-items: center;
  1034. justify-items: center;
  1035. text-align: center;
  1036. flex-direction: row;
  1037. }
  1038. .video-fullScree-speed {
  1039. margin-right: 20rpx;
  1040. color: #ffffff;
  1041. font-size: 25rpx;
  1042. text-align: center;
  1043. align-items: center;
  1044. }
  1045. .video-hz-lock {
  1046. position: absolute;
  1047. left: 50rpx;
  1048. top: 45%;
  1049. z-index: 998;
  1050. background-color: rgba(0, 0, 0, 0.1);
  1051. height: 50rpx;
  1052. width: 50rpx;
  1053. border-radius: 50%;
  1054. padding: 10rpx;
  1055. }
  1056. .video-hz-lock cover-image {
  1057. height: 100%;
  1058. width: 100%;
  1059. }
  1060. .video-hz-jp {
  1061. position: absolute;
  1062. right: 50rpx;
  1063. top: 45%;
  1064. z-index: 998;
  1065. background-color: rgba(0, 0, 0, 0.1);
  1066. height: 50rpx;
  1067. width: 50rpx;
  1068. border-radius: 50%;
  1069. padding: 10rpx;
  1070. }
  1071. .video-hz-jp cover-image {
  1072. height: 100%;
  1073. width: 100%;
  1074. }
  1075. </style>