123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- Component({
- options: {
- addGlobalClass: true,
- // 指定所有 _ 开头的数据字段为纯数据字段
- pureDataPattern: /^_/
- },
- properties: {
- duration: {
- type: Number,
- value: 500
- },
- easingFunction: {
- type: String,
- value: 'default'
- },
- loop: {
- type: Boolean,
- value: true
- },
- targetPlayIndex: {
- type: Number,
- value: -1,
- observer: function (newVal) {
- if (newVal >= 0) {
- this.targetPlay(newVal)
- }
- }
- },
- // {id, url, objectFit}
- videoList: {
- type: Array,
- value: [],
- observer: function (newVal = []) {
- this._videoListChanged(newVal)
- }
- }
- },
- data: {
- nextQueue: [], // 待播放列表
- prevQueue: [], // 已播放列表
- curQueue: [], // 当前播放列表
- circular: false, // 是否循环
- _last: 0, // 上一次显示
- _maxCount: -1,
- _dataIdx: 0,
- initIndex: 0,
- playerIdx: 0,
- playing: false,
- _change: -1,
- _invalidUp: 0,
- _invalidDown: 0,
- _videoContexts: []
- },
- lifetimes: {
- attached() {
- this.data._videoContexts = [
- wx.createVideoContext('video_0', this),
- wx.createVideoContext('video_1', this),
- wx.createVideoContext('video_2', this)
- ]
- }
- },
- created() {
- this._swipering = false
- },
- methods: {
- // 添加新的视频源
- _videoListChanged(newVal) {
- const data = this.data
- newVal.forEach(item => {
- data.nextQueue.push(item)
- })
- const maxCount = newVal.length
- if (data.curQueue.length === 0) {
- this.setData({
- curQueue: data.nextQueue.splice(0, 3),
- _maxCount: maxCount
- }, () => {
- this.playCurrent(0)
- })
- }
- },
- animationfinish(e) {
- const {
- _last,
- _change,
- curQueue,
- prevQueue,
- nextQueue,
- _dataIdx
- } = this.data
- const current = e.detail.current
- const diff = current - _last
- this._swipering = false
- this.playCurrent(current)
- const change = current !== this.data._last
- if (diff === 0 || !change) {
- return
- }
- const direction = (diff === 1 || diff === -2) ? 'up' : 'down'
- console.log('direction', direction)
- if (direction === 'up') {
- if (this.data._invalidDown === 0) {
- this.data._dataIdx++
- if (this.data._dataIdx >= this.data._maxCount) {
- this.data._dataIdx = 0
- }
- this.loadCurQueue(this.data._dataIdx, current)
- } else {
- this.data._invalidDown -= 1
- }
- }
- if (direction === 'down') {
- if (this.data._invalidUp === 0) {
- this.data._dataIdx--
- if (this.data._dataIdx < 0) {
- this.data._dataIdx = this.data._maxCount - 1
- }
- this.loadCurQueue(this.data._dataIdx, current)
- } else {
- this.data._invalidUp -= 1
- }
- }
- this.triggerEvent('change', {
- activeId: curQueue[current].id
- })
- let circular = true
- this.data._last = current
- // if (_dataIdx === 0) {
- // circular = false
- // }
- // if (prevQueue.length === 0 && current !== 2) {
- // circular = false
- // }
- this.setData({
- curQueue,
- circular,
- })
- },
- loadCurQueue(dataIdx, playerIdx) {
- const {
- _maxCount,
- curQueue,
- videoList
- } = this.data
- const current = playerIdx;
- let curDataIdx = dataIdx;
- if (curDataIdx > _maxCount) {
- curDataIdx = _maxCount;
- }
- let pre = 0,
- next = 0,
- preV, nextV, curVideo;
- pre = current - 1;
- if (pre < 0) {
- pre = 2;
- }
- next = current + 1;
- if (next > 2) {
- next = 0;
- }
- if (curDataIdx - 1 >= 0) {
- preV = videoList[curDataIdx - 1];
- } else {
- preV = videoList[_maxCount - 1];
- }
- console.log('curDataIdx + 1 ', curDataIdx + 1)
- if (curDataIdx + 1 < _maxCount) {
- nextV = videoList[curDataIdx + 1];
- } else {
- nextV = videoList[0];
- }
- curVideo = videoList[curDataIdx];
- curQueue[pre] = preV
- curQueue[next] = nextV
- curQueue[current] = curVideo
- },
- /**
- * 指定视频播放
- * @param {videoList(index)} dataIdx
- */
- targetPlay(dataIdx) {
- let curQueue = this.data.videoList.slice();
- if (dataIdx >= this.data._maxCount) {
- this._dataIdx = dataIdx = this.data._maxCount - 1
- }
- if (this.data._maxCount - dataIdx < 3) {
- if (this.data._maxCount - dataIdx === 2) {
- const last = this.data.videoList.slice().shift();
- curQueue = curQueue.splice(dataIdx, 2).concat(last)
- }
- if (this.data._maxCount - dataIdx === 1) {
- const first = this.data.videoList.slice().pop();
- curQueue = [first].concat(curQueue.splice(0, 2));
- }
- } else {
- curQueue = curQueue.splice(dataIdx, 3)
- }
- this.setData({
- curQueue: curQueue,
- _dataIdx: dataIdx,
- playerIdx: 0
- }, () => {
- this.playCurrent(0)
- })
- },
- // 避免卡顿
- playCurrent(current) {
- this.data._videoContexts.forEach((ctx, index) => {
- index !== current ? ctx.pause() : ctx.play()
- })
- this.setData({
- playing: true,
- playerIdx: current
- }, () => {
- this.data._videoContexts.forEach((ctx, index) => {
- index !== current ? ctx.seek(0) : null
- })
- })
- // // 重置所有视频pause时重置时间
- // setTimeout(() => {
- // this.data._videoContexts.forEach((ctx, index) => {
- // index !== current ? ctx.seek(0) : null
- // })
- // }, 100)
- },
- onPlay(e) {
- this.trigger(e, 'play')
- },
- onPause(e) {
- this.trigger(e, 'pause')
- },
- onEnded(e) {
- this.trigger(e, 'ended')
- },
- onError(e) {
- this.trigger(e, 'error')
- },
- onTimeUpdate(e) {
- this.trigger(e, 'timeupdate')
- },
- onWaiting(e) {
- this.trigger(e, 'wait')
- },
- onProgress(e) {
- this.trigger(e, 'progress')
- },
- onLoadedMetaData(e) {
- this.trigger(e, 'loadedmetadata')
- },
- trigger(e, type, ext = {}) {
- const detail = e.detail
- const activeId = e.target.dataset.id
- this.triggerEvent(type, Object.assign({
- ...detail,
- activeId
- }, ext))
- },
- onVideoOverlayTap() {
- if (this.data.playing) {
- this.data._videoContexts.forEach((ctx, index) => {
- ctx.pause()
- })
- this.setData({
- playing: false
- })
- } else {
- this.data._videoContexts.forEach((ctx, index) => {
- index !== this.data.playerIdx ? ctx.pause() : ctx.play()
- })
- this.setData({
- playing: true
- })
- }
- },
- onSwiping() {
- this._swipering = true
- }
- }
- })
|