小程序视频组件重写

需求
视频交互:
  1. 用户wifi状态:视频自动播放(默认静音播放) 流量状态:视频界面有播放按钮,点击按钮可播放视频。在这里插入图片描述

  2. 点击视频界面则视频停止播放,下方出现播放开关、进度条、声音开关,支持调节进度条 再次点击视频界面可重新播放,重新播放时进度条隐去。![在这里插入图片描述](https://img-blog.csdnimg.cn/20210526151118335.p

  3. 页面滑动至视频下方,即完全看不见该视频界面,则视频播放停止。 视频尺寸750宽*420高。

componentWillMount () {
   // 入口判断是否wifi条件访问小程序
   let _this = this
   Taro.getNetworkType({
     success (res) {
       if (res.networkType == 'wifi') {
         _this.setState({
           isWifi: true,
         })
       } else {
         _this.setState({
           isWifi: false,
         })
       }
     }
   })
}

// 请求视频资源接口
getData() {
  let url = baseUrl + '/core-service/operation/types/list';
  request({
    url: url,
    method: "get",
    header: {
      ...getJsonHead(),
      "content-type": "application/x-www-form-urlencoded"
    },
    data: {}
  }).then(res => {
       let homePageVideo = res && Array.isArray(res.homePageVideo) ? res.homePageVideo : []
       homePageVideo.filter((row, index) => {
         row.controls = false
         row.isPlay = false
         // 返回首页如果视频存在,保持播放/暂停状态
         if (this.state.homePageVideo && this.state.homePageVideo.length) {
           this.state.homePageVideo.filter(item => {
             if (item.operationId && item.operationId === row.operationId && item.linkUrl && item.linkUrl === row.linkUrl) {
               row.controls = item.controls
               row.isPlay = item.isPlay
               row.IsExistVideo = true
             }
           })
         }
       })
       this.setState({
         homePageVideo: homePageVideo
       },()=>{
         homePageVideo.filter((row, index) => {
           // wifi条件下自动播放第一条视频
           if (index == 0 && this.state.isWifi && !row.IsExistVideo) {
             Taro.createVideoContext('pageVideo' + 0).play()
             row.controls = false
             row.isPlay = true
           }
         })
         this.setState({
           homePageVideo: homePageVideo
         })
       });
     }
   }).catch(err => {
     console.log(err);
   });
}

// 视频位视频暂停
videoPauseByPosition = (index) => {

}

// 视频位视频播放
videoPlayByPosition = (index) => {

}

// 当播放到末尾时触发 ended 事件
videoEndedByPosition = (index) => {
 if (this.state.homePageVideo[index].videoDuration) {
   Taro.createVideoContext('pageVideo'+ index).seek(this.state.homePageVideo[index].videoDuration)
 }
 let mTout = setTimeout(() => {
   this.state.homePageVideo[index].isPlay = false
   this.state.homePageVideo[index].controls = true
   this.state.homePageVideo[index].videoIsLast = true
   Taro.createVideoContext('pageVideo'+ index).pause()
   this.setState({
     homePageVideo: this.state.homePageVideo
   })
   clearTimeout(mTout)
 }, 100)
}
// 播放进度变化时触发
videoTimeupdateByPosition = (details, index) => {
 if (details && details.detail && details.detail.duration && !this.state.homePageVideo[index].videoDuration) {
   this.state.homePageVideo[index].videoDuration = Number(Math.floor(details.detail.duration))
   this.setState({
     homePageVideo: this.state.homePageVideo
   })
 }
}
// 视频点击事件
videoClickByPosition = (index) => {
 if (Array.isArray(this.state.homePageVideo)) {
   this.state.homePageVideo.filter((row, rowIndex) =>{
     // 停止播放视频位其他视频
     if (index === rowIndex) {
       if (row.isPlay) {
         row.isPlay = false
         row.controls = true
         row.videoIsLast = false
         Taro.createVideoContext('pageVideo'+ index).pause()
       } else {
         row.isPlay = true
         // row.controls = false
         if (row.videoIsLast) {
           Taro.createVideoContext('pageVideo'+ index).seek(0)
           let mTout = setTimeout(() => {
             Taro.createVideoContext('pageVideo'+ index).play()
             clearTimeout(mTout)
           }, 100)
         } else {
           Taro.createVideoContext('pageVideo'+ index).play()
         }
         row.videoIsLast = false
       }
     } else {
       row.isPlay = false
       row.controls = false
       row.videoIsLast = false
       Taro.createVideoContext('pageVideo'+ rowIndex).pause()
     }
   })
 }
 this.setState({
   bannerData: this.state.bannerData,
   homePageVideo: this.state.homePageVideo
 }, () =>{
   let myTimeout = setTimeout(() => {
     if (this.state.homePageVideo[index].isPlay) {
       this.state.homePageVideo[index].controls = false
     } else {
       // this.state.homePageVideo[index].controls = true
     }
     this.setState({
       homePageVideo: this.state.homePageVideo
     })
     clearTimeout(myTimeout)
   }, 3000)
 })
}

onPageScroll(e) {
  let query = Taro.createSelectorQuery();
  let wh = Taro.getSystemInfoSync().windowHeight;//可视区域高度
  if (this.state.homePageVideo && this.state.homePageVideo.length) {
    this.state.homePageVideo.filter((row, index) => {
      query
        .select('#pageVideo' + index)
        .boundingClientRect(rect => { // 我查询的是包裹视频的元素,可根据需求
          if (rect) {
            let top = rect.top;//距离顶部高度
            let bottom = rect.bottom;
            let vh = rect.height;//元素高度

            // console.log('pageVideo' + index + '\t\ttop:' + top + '\t\tbottom:' + bottom + '\t\tvh:' + vh+ '\t\twh:' + wh)
            if ((top < 0 && (top + bottom) <= 0) || top >= wh) { //当视频不在可视范围内,停止播放
              row.isPlay = false
              row.controls = false
              Taro.createVideoContext('pageVideo'+ index).pause()
              this.setState({
                homePageVideo: this.state.homePageVideo
              })
            }
          }
        })
        .exec();
    })
  }
}
{/*首页视频位*/}
{Array.isArray(this.state.homePageVideo) && this.state.homePageVideo.length > 0 ?
  <View className={classnames('page-video-content')}>
    {this.state.homePageVideo.map((item, itemIndex) => (
      <View key={itemIndex} className='page-video-item'>
        <Video
          id={`pageVideo${itemIndex}`}
          preload={"auto"}
          style={{width: '750rpx', height: '420rpx'}}
          src={item.linkUrl}
          controls={item.controls}
          autoplay={false}
          showshowPlayBtnPlayBtn={true}
          showCenterPlayBtn={false}
          showFullscreenBtn={false}
          showMuteBtn={true}
          enableProgressGesture={false}
          playBtnPosition={'bottom'}
          direction={90}
          initialTime={0}
          loop={false}
          muted={true}
          objectFit={'cover'}
          onPause={
            this.videoPauseByPosition.bind(this, itemIndex)
          }
          onPlay={
            this.videoPlayByPosition.bind(this, itemIndex)
          }
          onEnded={
            this.videoEndedByPosition.bind(this, itemIndex)
          }
          onTimeUpdate={
            (details) =>{
              this.videoTimeupdateByPosition(details, itemIndex)
            }
          }
        >
          { !item.isPlay && !item.controls ?
            <View className='page-video-control' onClick={this.videoClickByPosition.bind(this, itemIndex, 'play')}>
              <Image className='video-play-icon' src={`${imgCdn}/wowcolour/index/video-play-white.png`} />
            </View> : '' }
          { item.isPlay || item.controls ?
            <View className='play-video-control' onClick={this.videoClickByPosition.bind(this, itemIndex, 'hide')}>
            </View> : '' }
        </Video>
      </View>
    ))}
  </View> : ''
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在微信小程序中,父组件调用子组件的方法需要通过子组件的 `ref` 属性来实现。同时,如果需要在父组件重写组件的方法,可以通过在子组件中定义一个回调函数,并在父组件中传入该回调函数来实现。下面是一个示例: 在子组件中(ChildComponent)定义一个方法,并在需要触发的地方调用该方法: ```javascript // 子组件 ChildComponent Component({ methods: { childMethod() { console.log('子组件方法被调用'); } } }) ``` 在父组件中(ParentComponent),通过 `ref` 属性获取子组件实例,并调用子组件的方法。同时,可以通过 `data` 属性将一个回调函数传递给子组件: ```html <!-- 父组件 ParentComponent 的 wxml 文件 --> <child-component ref="child" bind:parentMethod="parentMethod"></child-component> ``` ```javascript // 父组件 ParentComponent Page({ parentMethod() { console.log('父组件方法被调用,可以在这里重写组件的方法'); }, onReady() { const childComponent = this.selectComponent('#child'); childComponent.childMethod(); // 调用子组件的方法 } }) ``` 在上述示例中,通过 `ref="child"` 给子组件指定了一个引用标识符,在父组件的 `onReady` 生命周期钩子中使用 `this.selectComponent('#child')` 来获取子组件实例。然后就可以通过 `childComponent` 调用子组件的方法 `childMethod()`。 同时,通过 `bind:parentMethod="parentMethod"` 将父组件的回调函数 `parentMethod` 传递给子组件,在需要重写组件方法的地方,可以在父组件中定义 `parentMethod` 方法来覆盖子组件的方法。 希望以上示例对您有所帮助!如有更多问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值