uniapp 基于xgplayer(西瓜视频) + renderjs开辟,实现APP视频播放 ...

打印 上一主题 下一主题

主题 1052|帖子 1052|积分 3156

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
配景:在uniapp中因原生video组件功能有限,选择引入xgplayer库来展示视频播放等功能。而且APP端无法操作dom,以是使用了renderjs。
  其他的不多说,主要枚举一下renderjs中必要注意的点:
1、使用:在标签后,添加<script module="xgPlayerModule" lang="renderjs"></script >,然后有关操作dom的代码都写在script 标签内里。此中module的值是自界说的,后续会用这个值来调用renderjs的方法。
2、平常 script 标签是逻辑层,带renderjs的 script 标签是视图层。
3、逻辑层向视图层传值:在 template 某元素上添加 :属性名=“vue 变量”:change:属性名=“renderjs 模块名.方法名” (此中 vue 变量 为 Vue 组件中的某个数据, renderjs 模块名 为之前界说的 module 属性的值,当 vue 变量 值改变时会触发 renderjs模块名.方法名 的方法)。例如:
  1. <view :iosTimes="iosTimes" :change:iosTimes="xgPlayerModule.changeTimes"></view>
  2. <script module="xgPlayerModule" lang="renderjs">
  3. export default {
  4.         data(){
  5.                 return {
  6.               renderIosTimes: null
  7.                 }
  8.         },
  9.         methods: {
  10.              changeTimes() { // 当检测到iosTimes变化时,触发此方法,重新赋值后,保存在renderjs里面的renderIosTimes 变量中,因为后面renderjs里面的其他方法要使用这个值。
  11.                  this.renderIosTimes = this.iosTimes
  12.              }
  13.      }
  14. }
  15. </script>  
复制代码
4、**视图层向逻辑层传参:**在 template 元素的变乱绑定中使用 @变乱=“renderjs 模块名.方法名” ,通过该方式触发 renderjs 中的方法,然后在这个方法中可以使用 this.$ownerinstance.callmethod('vue 组件中的方法名', 参数) 来调用平常 Vue 组件中的方法并传值。
  1. this.$ownerInstance.callMethod('playerMethods')
复制代码
接下来就是在renderjs中,通过xgplayer创建视频,而且完成交互
准备:
npm install xgplayer --save
以下是完备的代码案例:
video.vue中调用xgplayer组件
  1. <xg-player :data-idkey="modId" ref="video" :videoConfig="videoConfig" ></xg-player>
  2. import xgPlayer from '@/components/player/xgplayer';
  3. <script>
  4. export default {
  5.         data(){
  6.                 return {
  7.                       videoConfig: {
  8.                         videoUrl: '', // 播放地址
  9.                         lastPlayTime: '' // 上次播放时间
  10.                     }       
  11.             }
  12.         },
  13.         methods: {
  14.              changeTimes() { // 当检测到iosTimes变化时,触发此方法,重新赋值后,保存在renderjs里面的renderIosTimes 变量中,因为后面renderjs里面的其他方法要使用这个值。
  15.                  this.renderIosTimes = this.iosTimes
  16.              }
  17.      },
  18.     onHide: function() { // 退出应用时调用
  19.         this.$refs['video'].beforeLeave()  // 调用子组件的方法,暂停视频播放
  20.      }
  21. }
  22. </script>  
复制代码
xgplayer.vue组件中:
  1. <template>
  2.     <view>
  3.         <!-- 视频 -->
  4.         <view
  5.             :id='videoId'
  6.             class="mse-box"
  7.             :style="customStyle"
  8.             v-if="type === 'VOD'"
  9.             :conEnd="conEnd" :change:conEnd="xgPlayerModule.initVideo"
  10.         ></view>
  11.         <view :iosTimes="iosTimes" :change:iosTimes="xgPlayerModule.changeTimes"></view>
  12.         <view :modOpenTrial="modOpenTrial" :change:modOpenTrial="xgPlayerModule.changeModOpenTrial"></view>
  13.         <view :playOrPauseStatus="playOrPauseStatus" :change:playOrPauseStatus="xgPlayerModule.playOrPauseVideoRenderjs"></view>
  14.     </view>
  15. </template>
  16. <!-- 逻辑层 -->
  17. <script>
  18. export default {
  19.     name: 'xgPlayerHls',
  20.     data: function() {
  21.         return {
  22.             config: {
  23.                 id: this.videoId,
  24.                 url: '',
  25.                 fluid: true,
  26.                 playbackRate: [0.75, 1, 1.5, 2],
  27.                 defaultPlaybackRate: 1,
  28.                 definitionActive: 'click',
  29.                 poster: '',
  30.                 volume: 1,
  31.                 autoplay: false, // 手动点击播放,节省用户流量
  32.                 playsinline: true,
  33.                 lastPlayTime: 0, //视频起播时间(单位:秒)
  34.                 lastPlayTimeHideDelay: 3,
  35.                 enableVideoDbltouch: true,
  36.                 rotateFullscreen: true,
  37.                 // rotate: {
  38.                 //     innerRotate: true,
  39.                 //     clockwise: false
  40.                 // },
  41.                 fitVideoSize: 'auto'
  42.             },
  43.             inFullscreen: false,
  44.             inLandscape: false,
  45.             conEnd: null,
  46.             playOrPauseStatus: 'pause'
  47.         };
  48.     },
  49.     components: {
  50.     },
  51.     computed: {
  52.         // h5通过监听屏幕角度去写入样式
  53.         customStyle() {
  54.             const that = this;
  55.             if (that.inFullscreen && that.inLandscape) {
  56.                 return {
  57.                     height: '100vh !important',
  58.                     minWidth: '100%',
  59.                     width: '100% !important',
  60.                     left: '0%',
  61.                     transform: 'rotate(0deg)'
  62.                 };
  63.             } else if (that.inLandscape) {
  64.                 return {
  65.                     width: '100% !important',
  66.                     height: '400rpx !important'
  67.                 };
  68.             } else {
  69.                 return {
  70.                     width: '100%',
  71.                     height: '400rpx'
  72.                 };
  73.             }
  74.         }
  75.     },
  76.     props: {
  77.         rootStyle: {
  78.             type: Object,
  79.             default() {
  80.                 return {};
  81.             }
  82.         },
  83.         iosTimes: {
  84.             type: Boolean,
  85.             default() {
  86.                 return false;
  87.             }
  88.         },
  89.         videoConfig: {
  90.             type: Object,
  91.             default() {
  92.                 return {videoUrl: '', lastPlayTime: 0};
  93.             }
  94.         },
  95.         modOpenTrial: {
  96.             type: Boolean,
  97.             default() {
  98.                 return true;
  99.             }
  100.         },
  101.         modDrag: {
  102.             type: Boolean,
  103.             default() {
  104.                 return true;
  105.             }
  106.         },
  107.         fastForward: {
  108.             type: Boolean,
  109.             default() {
  110.                 return true;
  111.             }
  112.         },
  113.         type: {
  114.             type: String,
  115.             default() {
  116.                 return 'VOD';
  117.             }
  118.         },
  119.         videoId: {
  120.             type: String,
  121.             default() {
  122.                 return 'mse';
  123.             }
  124.         }
  125.     },
  126.     methods: {
  127.         beforeLeave() { // 离开页面暂停视频播放
  128.             this.playOrPauseStatus = 'pause'
  129.         },
  130.         playVideo() {
  131.             this.playOrPauseStatus = 'play'
  132.         },
  133.         pauseVideo() {
  134.             this.playOrPauseStatus = 'pause'
  135.         },
  136.         handleOrientation() {
  137.             const orientation = window.orientation;
  138.             console.log('orientation=当设备的方向发生变化时触发的事件===', orientation);
  139.             
  140.             switch (orientation) {
  141.             case 0:
  142.                 // 竖屏
  143.                 this.inLandscape = false;
  144.                 break;
  145.             case 90:
  146.                 // 左横屏
  147.                 this.inLandscape = true;
  148.                 break;
  149.             case -90:
  150.                 // 右横屏
  151.                 this.inLandscape = true;
  152.                 break;
  153.             case 180:
  154.                 // 倒立
  155.                 break;
  156.             default:
  157.                 // 未知
  158.                 break;
  159.             }
  160.         },
  161.         fullScreenMe() { // 进入全屏
  162.             this.inFullscreen = true;
  163.             this.$emit('on-goLandscape', 'ON');
  164.         },
  165.         exitFullScreenMe() { // 退出全屏
  166.             this.inFullscreen = false;
  167.             this.$emit('on-goLandscape', 'OFF');
  168.         },
  169.         playTimeUpdate(currentTime) { // timeupdate播放中
  170.             // console.log('播放中=============');
  171.             this.$emit('playerVideo', currentTime);
  172.         },
  173.         openTrialMe() {
  174.             // 弹框有问题
  175.             this.$dialog.alert({
  176.                 width: '80%',
  177.                 confirmButtonColor: '#00aeef',
  178.                 confirmButtonText: this.$t('mall_10'),
  179.                 message: this.$t('see_end')
  180.             });
  181.         },
  182.         playerMethods() { // 播放
  183.             console.log('播放============');
  184.             this.playOrPauseStatus = 'play'
  185.             this.$emit('videoPlay')
  186.         },
  187.         playerPauseMethods() { // 暂停
  188.             console.log('暂停============');
  189.             this.playOrPauseStatus = 'pause'
  190.             this.$emit('videoPause')
  191.         },
  192.         init() {
  193.             if (this.videoConfig.videoUrl) {
  194.                 if (this.type === 'VOD') {
  195.                     this.config.id = this.videoId;
  196.                     this.config.lastPlayTime = this.videoConfig.lastPlayTime;
  197.                     this.config.url = this.videoConfig.videoUrl;
  198.                     this.config.autoplay =this.videoConfig.autoplay
  199.                     this.config.ignores = this.fastForward ? [] : ['progress'];
  200.                     if (this.videoConfig.duration) {
  201.                         this.config.duration = this.videoConfig.duration;
  202.                     }
  203.                     // m3u8 格式播放
  204.                     if (this.videoConfig.videoUrl.indexOf('m3u8') !== -1) {
  205.                         this.config.preloadTime = 15; // 预加载时间15s
  206.                         this.config.minCachedTime = 5; // 最小缓存时间
  207.                         // iOS手机不兼容此项属性,故作此判断
  208.                          // 使用 uni.getSystemInfoSync() 获取系统信息
  209.                         const systemInfo = uni.getSystemInfoSync();
  210.                         const platform = systemInfo.platform;
  211.                         
  212.                         if (platform === 'android') {
  213.                             this.config.useHls = true;
  214.                         }
  215.                     }
  216.                     this.conEnd = this.config; // config赋值完成
  217.                 }
  218.             }
  219.         }
  220.     },
  221.     mounted() {
  222.         // 是否有权限观看完整视频, true: 能 , false: 禁止拖拽; 限制 10%;
  223.         this.config.disableProgress = !this.modOpenTrial;
  224.         //如果禁止拖动,后台设置的false,前端设置值得是true.如果允许拖动,后台设置的true,前端设置值得是false.
  225.         this.config.allowSeekPlayed = !this.modDrag;
  226.         // #ifdef APP-PLUS
  227.         // 监听事件 当设备的方向发生变化时触发的事件
  228.         plus.globalEvent.addEventListener('orientationchange', this.handleOrientation);
  229.         // #endif
  230.         // #ifndef  APP-PLUS
  231.         window.addEventListener('orientationchange', this.handleOrientation);
  232.         // #endif
  233.         this.init();
  234.         
  235.     },
  236.     watch: {
  237.         modOpenTrial(val) {
  238.             // 是否有权限观看完整视频, true: 能 , false: 禁止拖拽; 限制 10%;
  239.             this.config.disableProgress = !this.val;
  240.         }
  241.     }
  242. };
  243. </script>
  244. <!-- 视图层 -->
  245. <script module="xgPlayerModule" lang="renderjs">
  246.     import xgPlayer from 'xgplayer';
  247.     import HlsJsPlayer from 'xgplayer-hls.js';
  248.         export default {
  249.                 data(){
  250.                         return {
  251.                 player: null,
  252.                 renderIosTimes: null,
  253.                 renderModOpenTrial: null
  254.                         }
  255.                 },
  256.                 mounted() {
  257.                 },
  258.         beforeDestroy() {
  259.             this.player && typeof this.player.destroy === 'function' && this.player.destroy();
  260.         },
  261.                 methods: {
  262.             playOrPauseVideoRenderjs() { // 控制视频播放和暂停
  263.                 console.log('暂停视频 或者 播放', this.playOrPauseStatus);
  264.                 if (this.player) {
  265.                     if (this.playOrPauseStatus === 'play') {
  266.                         this.player.play();
  267.                     } else {
  268.                         this.player.pause();
  269.                     }
  270.                 }
  271.             },
  272.             changeTimes() {
  273.                 this.renderIosTimes = this.iosTimes
  274.             },
  275.             changeModOpenTrial() {
  276.                 this.renderModOpenTrial = this.modOpenTrial
  277.             },
  278.             initVideo(newVal,old,ownerInstance,instance) {
  279.                 let that = this
  280.                 if (that.conEnd && that.conEnd.id && that.conEnd.url && !that.player) {
  281.                     console.log('视图层的initVideo方法========');
  282.                     if (that.player) {
  283.                         that.player.destroy();
  284.                     }
  285.                     if (that.conEnd.url.indexOf('m3u8') !== -1) {
  286.                         that.player = new HlsJsPlayer(that.conEnd);
  287.                     } else { // 不是m3u8
  288.                         that.player = new xgPlayer(that.conEnd);
  289.                         if (that.renderIosTimes) {
  290.                             if (that.player) {
  291.                                 that.player.start(that.conEnd.url);
  292.                                 that.player.play();
  293.                             }
  294.                         }
  295.                     }
  296.                     console.log('that.player=======', that.player);
  297.                     
  298.                     // 播放
  299.                     that.player.on('play', function () {
  300.                         // 调用逻辑层方法
  301.                         that.$ownerInstance.callMethod('playerMethods')
  302.                     })
  303.                     // 暂停
  304.                     that.player.on('pause', function () {
  305.                         // 调用逻辑层方法
  306.                         that.$ownerInstance.callMethod('playerPauseMethods')
  307.                     })
  308.                     // 播放中
  309.                     that.player.on('timeupdate', function(resPlayer) {
  310.                         // 是否有权限观看完整视频, true: 能 , false: 禁止拖拽; 限制 10%;
  311.                         if (!that.renderModOpenTrial && (resPlayer.currentTime / resPlayer.duration) >= 0.1) {
  312.                             resPlayer.pause();
  313.                             // resPlayer.currentTime = 0;
  314.                             that.$ownerInstance.callMethod('openTrialMe')
  315.                         }
  316.                         // 调用逻辑层方法
  317.                         that.$ownerInstance.callMethod('playTimeUpdate', resPlayer.currentTime)
  318.                     });
  319.                     // 进入全屏
  320.                     that.player.on('getRotateFullscreen', function(value) {
  321.                         if (document.getElementsByClassName('water-turn')[0]) {
  322.                             document.getElementsByClassName('water-turn')[0].style.transform = 'rotate(90deg)';
  323.                         }
  324.                         that.$ownerInstance.callMethod('fullScreenMe')
  325.                     });
  326.                     // 退出全屏
  327.                     that.player.on('exitRotateFullscreen', function(value) {
  328.                         if (document.getElementsByClassName('water-turn')[0]) {
  329.                             document.getElementsByClassName('water-turn')[0].style.transform = 'rotate(0deg)';
  330.                         }
  331.                         that.$ownerInstance.callMethod('exitFullScreenMe')
  332.                     });
  333.                 }
  334.             }
  335.                 }
  336.         }
  337. </script>
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

傲渊山岳

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表