与牧同行-小程序用户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

381 lines
8.4 KiB

// pages/training/videoDetail/videoDetail.js
import http from '../../../utils/api'
const baseUrl = require('../../../utils/baseUrl')
Page({
data: {
baseUrl: baseUrl,
video: {},
videoUrl: '',
loading: true,
fullScreen: false,
isPlaying: false,
isMuted: false,
loop: false,
playbackRate: 1,
currentTime: 0,
duration: 0,
videoTags: [],
videoError: false,
autoplay: false,
controlsVisible: true,
controlsTimer: null,
lastTouchTime: 0,
},
onLoad(options) {
console.log('页面参数:', options)
this.getVideoDetails(options.id)
},
onReady() {
this.videoContext = wx.createVideoContext('videoPlayer', this)
console.log('视频上下文创建成功')
},
onUnload() {
// 清除定时器
if (this.data.controlsTimer) {
clearTimeout(this.data.controlsTimer)
}
// 页面卸载时停止播放
if (this.videoContext) {
this.videoContext.pause()
}
},
// 获取视频详情
getVideoDetails(id) {
this.setData({
loading: true,
videoError: false
})
http.videoDetails({
data: { id },
success: res => {
console.log('视频详情响应:', res)
if (res.code === 200 && res.data) {
const video = res.data
console.log('视频数据:', video)
// 处理视频URL
let videoUrl = ''
if (video.videoUrl) {
videoUrl = this.data.baseUrl + video.videoUrl
console.log('视频完整URL:', videoUrl)
}
// 处理视频标签
const tags = video.tags ? video.tags.split(',').filter(tag => tag.trim()) : []
this.setData({
video: video,
videoUrl: videoUrl,
videoTags: tags,
loading: false
})
// 设置页面标题
wx.setNavigationBarTitle({
title: video.title.substring(0, 12) + (video.title.length > 12 ? '...' : '')
})
} else {
wx.showToast({
title: res.msg || '视频不存在',
icon: 'none',
duration: 2000
})
setTimeout(() => {
wx.navigateBack()
}, 2000)
}
},
fail: err => {
console.error('获取视频详情失败:', err)
this.setData({
loading: false,
videoError: true
})
wx.showToast({
title: '加载失败,请重试',
icon: 'none',
duration: 2000
})
}
})
},
// 返回上一页
goBack() {
wx.navigateBack()
},
// 视频加载完成
onVideoLoaded(e) {
console.log('视频元数据加载完成:', e.detail)
this.setData({
duration: e.detail.duration || 0,
videoError: false
})
},
// 视频播放错误
onVideoError(e) {
console.error('视频播放错误详情:', e.detail)
this.setData({
videoError: true,
isPlaying: false
})
wx.showModal({
title: '播放错误',
content: '视频加载失败,请检查网络或视频链接',
showCancel: true,
confirmText: '重试',
success: (res) => {
if (res.confirm) {
this.retryVideo()
}
}
})
},
// 视频播放事件
onVideoPlay(e) {
console.log('视频开始播放')
this.setData({
isPlaying: true,
videoError: false
})
// 播放时隐藏控制栏
if (this.data.fullScreen) {
this.hideControls()
}
},
// 视频暂停事件
onVideoPause(e) {
console.log('视频暂停')
this.setData({
isPlaying: false
})
// 暂停时显示控制栏
if (this.data.fullScreen) {
this.showControls()
}
},
// 视频播放结束
onVideoEnded(e) {
console.log('视频播放结束')
this.setData({
isPlaying: false,
currentTime: 0
})
// 结束播放时显示控制栏
if (this.data.fullScreen) {
this.showControls()
}
},
// 时间更新事件
onTimeUpdate(e) {
const currentTime = e.detail.currentTime
const duration = e.detail.duration
// 更新当前时间和总时长
this.setData({
currentTime: currentTime,
duration: duration > 0 ? duration : this.data.duration
})
},
// 全屏切换事件
onFullScreenChange(e) {
const fullScreen = e.detail.fullScreen
console.log('全屏状态变化:', fullScreen)
this.setData({
fullScreen: fullScreen,
controlsVisible: !fullScreen
})
if (fullScreen) {
wx.setKeepScreenOn({ keepScreenOn: true })
// 进入全屏后自动播放
setTimeout(() => {
this.videoContext.play()
}, 300)
} else {
wx.setKeepScreenOn({ keepScreenOn: false })
// 退出全屏时暂停
this.videoContext.pause()
}
},
// 进入全屏
enterFullScreen() {
this.videoContext.requestFullScreen({ direction: 90 })
},
// 退出全屏
exitFullScreen() {
this.videoContext.exitFullScreen()
},
// 切换播放状态
togglePlay() {
console.log('切换播放状态,当前状态:', this.data.isPlaying)
if (this.data.videoError) {
this.retryVideo()
return
}
if (this.data.isPlaying) {
this.videoContext.pause()
} else {
this.videoContext.play()
}
},
// 切换静音
toggleMute() {
const isMuted = !this.data.isMuted
this.setData({ isMuted: isMuted })
this.videoContext.muted(isMuted)
wx.showToast({
title: isMuted ? '已静音' : '已取消静音',
icon: 'none',
duration: 800
})
},
// 切换循环
toggleLoop() {
const loop = !this.data.loop
this.setData({ loop: loop })
this.videoContext.loop(loop)
wx.showToast({
title: loop ? '开启循环播放' : '关闭循环播放',
icon: 'none',
duration: 800
})
},
// 切换播放速度
toggleSpeed() {
const speeds = [0.5, 0.75, 1, 1.25, 1.5, 2]
const currentIndex = speeds.indexOf(this.data.playbackRate)
const nextIndex = (currentIndex + 1) % speeds.length
const nextSpeed = speeds[nextIndex]
this.setData({ playbackRate: nextSpeed })
this.videoContext.playbackRate(nextSpeed)
wx.showToast({
title: `播放速度 ${nextSpeed}x`,
icon: 'none',
duration: 800
})
},
// 重试播放
retryVideo() {
console.log('重试播放视频')
this.setData({
videoError: false,
loading: true
})
// 重新加载视频
setTimeout(() => {
this.setData({ loading: false })
if (this.videoContext) {
this.videoContext.seek(0)
this.videoContext.play()
}
}, 500)
},
// 触摸控制
onTouchControl(e) {
const type = e.currentTarget.dataset.type
const currentTime = this.data.currentTime
const duration = this.data.duration
if (type === 'backward') {
const newTime = Math.max(0, currentTime - 10)
this.setData({ currentTime: newTime })
this.videoContext.seek(newTime)
wx.showToast({
title: '-10秒',
icon: 'none',
duration: 500
})
} else if (type === 'forward') {
const newTime = Math.min(duration, currentTime + 10)
this.setData({ currentTime: newTime })
this.videoContext.seek(newTime)
wx.showToast({
title: '+10秒',
icon: 'none',
duration: 500
})
}
},
// 触摸移动
onTouchMove() {
if (this.data.fullScreen) {
this.showControls()
this.hideControls()
}
},
// 显示控制栏
showControls() {
this.setData({ controlsVisible: true })
// 清除之前的定时器
if (this.data.controlsTimer) {
clearTimeout(this.data.controlsTimer)
}
// 3秒后自动隐藏控制栏
const timer = setTimeout(() => {
if (this.data.isPlaying && this.data.fullScreen) {
this.setData({ controlsVisible: false })
}
}, 3000)
this.setData({ controlsTimer: timer })
},
// 隐藏控制栏
hideControls() {
if (this.data.controlsTimer) {
clearTimeout(this.data.controlsTimer)
}
const timer = setTimeout(() => {
if (this.data.isPlaying && this.data.fullScreen) {
this.setData({ controlsVisible: false })
}
}, 3000)
this.setData({ controlsTimer: timer })
},
})