first commit
This commit is contained in:
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* 播放器详情页
|
||||
* 大封面、进度条、倍速切换、播放控制
|
||||
* 从 globalData.activeContent 获取当前节目
|
||||
*/
|
||||
const app = getApp()
|
||||
const api = require('../../utils/api')
|
||||
const util = require('../../utils/util')
|
||||
|
||||
Page({
|
||||
data: {
|
||||
domain: {},
|
||||
activeContent: null,
|
||||
isPlaying: false,
|
||||
isVip: false,
|
||||
currentTime: 0,
|
||||
duration: 0,
|
||||
currentTimeText: '00:00',
|
||||
durationText: '00:00',
|
||||
displayDate: '',
|
||||
playbackRate: 1.0,
|
||||
statusBarHeight: 0,
|
||||
showTranscript: false, // 封面 ⇔ 文案切换
|
||||
showSpeedSheet: false,
|
||||
speedItems: [
|
||||
{ label: '0.5x' },
|
||||
{ label: '0.75x' },
|
||||
{ label: '1.0x' },
|
||||
{ label: '1.25x' },
|
||||
{ label: '1.5x' },
|
||||
{ label: '2.0x' }
|
||||
]
|
||||
},
|
||||
|
||||
_isSeeking: false,
|
||||
|
||||
|
||||
onLoad() {
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this._syncState()
|
||||
|
||||
// 监听播放状态
|
||||
this._onPlayerChange = (state) => {
|
||||
if (this._isSeeking) return
|
||||
this.setData({
|
||||
activeContent: state.activeContent,
|
||||
isPlaying: state.isPlaying,
|
||||
playbackRate: state.playbackRate
|
||||
})
|
||||
this._updateDomain()
|
||||
}
|
||||
|
||||
// 监听时间更新
|
||||
this._onTimeUpdate = (data) => {
|
||||
if (this._isSeeking) return
|
||||
this.setData({
|
||||
currentTime: data.currentTime,
|
||||
duration: data.duration || this.data.duration,
|
||||
currentTimeText: util.formatTime(data.currentTime),
|
||||
durationText: util.formatTime(data.duration || this.data.duration)
|
||||
})
|
||||
}
|
||||
|
||||
app.on('playerStateChange', this._onPlayerChange)
|
||||
app.on('timeUpdate', this._onTimeUpdate)
|
||||
},
|
||||
|
||||
onHide() {
|
||||
if (this._onPlayerChange) app.off('playerStateChange', this._onPlayerChange)
|
||||
if (this._onTimeUpdate) app.off('timeUpdate', this._onTimeUpdate)
|
||||
},
|
||||
|
||||
/**
|
||||
* 同步当前状态
|
||||
*/
|
||||
_syncState() {
|
||||
const gd = app.globalData
|
||||
const content = gd.activeContent
|
||||
|
||||
if (!content) {
|
||||
wx.navigateBack()
|
||||
return
|
||||
}
|
||||
|
||||
var dateStr = ''
|
||||
if (content.createdAt) {
|
||||
dateStr = content.createdAt.substring(0, 10).replace(/-/g, '.')
|
||||
} else if (content.date) {
|
||||
dateStr = util.dateToDot(content.date)
|
||||
}
|
||||
|
||||
this.setData({
|
||||
activeContent: content,
|
||||
isPlaying: gd.isPlaying,
|
||||
isVip: gd.isVip,
|
||||
currentTime: gd.currentTime,
|
||||
duration: gd.duration || content.duration,
|
||||
currentTimeText: util.formatTime(gd.currentTime),
|
||||
durationText: util.formatTime(gd.duration || content.duration),
|
||||
displayDate: dateStr,
|
||||
playbackRate: gd.playbackRate,
|
||||
statusBarHeight: gd.statusBarHeight || 0
|
||||
})
|
||||
|
||||
this._updateDomain()
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取频道信息 — 从后端 API 获取
|
||||
*/
|
||||
_updateDomain() {
|
||||
const content = this.data.activeContent
|
||||
if (!content) return
|
||||
|
||||
var channelId = content.channelId || (content.channel && content.channel.id)
|
||||
if (!channelId) {
|
||||
// 如果节目数据中直接包含 channel 信息
|
||||
if (content.channel) {
|
||||
this.setData({ domain: content.channel })
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 如果已经加载过且 channelId 没变,跳过
|
||||
if (this.data.domain && this.data.domain.id === channelId) return
|
||||
|
||||
var self = this
|
||||
api.getChannelDetail(channelId).then(function (res) {
|
||||
if (res.code === 200 && res.data) {
|
||||
self.setData({ domain: res.data })
|
||||
}
|
||||
}).catch(function (err) {
|
||||
console.error('[Player] 获取频道信息失败:', err)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 播放/暂停
|
||||
*/
|
||||
onTogglePlay() {
|
||||
app.togglePlay()
|
||||
},
|
||||
|
||||
/**
|
||||
* 进度条拖动中
|
||||
*/
|
||||
onSliderChanging(e) {
|
||||
this._isSeeking = true
|
||||
this.setData({
|
||||
currentTime: e.detail.value,
|
||||
currentTimeText: util.formatTime(e.detail.value)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 进度条拖动完成 → 跳转播放
|
||||
*/
|
||||
onSliderChange(e) {
|
||||
this._isSeeking = false
|
||||
app.seekTo(e.detail.value)
|
||||
},
|
||||
|
||||
/**
|
||||
* 快退 15 秒
|
||||
*/
|
||||
onBackward() {
|
||||
const newTime = Math.max(0, this.data.currentTime - 15)
|
||||
app.seekTo(newTime)
|
||||
},
|
||||
|
||||
/**
|
||||
* 快进 15 秒
|
||||
*/
|
||||
onForward() {
|
||||
const newTime = Math.min(this.data.duration, this.data.currentTime + 15)
|
||||
app.seekTo(newTime)
|
||||
},
|
||||
|
||||
/**
|
||||
* 倍速设置(VIP 功能)
|
||||
*/
|
||||
onSpeed() {
|
||||
if (!this.data.isVip) {
|
||||
wx.showModal({
|
||||
title: '会员提示',
|
||||
content: '倍速播放是会员专属功能,是否前往开通?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
wx.navigateTo({ url: '/pages/vip/index' })
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.setData({ showSpeedSheet: true })
|
||||
}
|
||||
},
|
||||
|
||||
onSpeedSelect(e) {
|
||||
const label = this.data.speedItems[e.detail.index].label
|
||||
const rate = parseFloat(label)
|
||||
app.setPlaybackRate(rate)
|
||||
this.setData({ showSpeedSheet: false, playbackRate: rate })
|
||||
},
|
||||
|
||||
onSpeedCancel() {
|
||||
this.setData({ showSpeedSheet: false })
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载(VIP 功能)
|
||||
*/
|
||||
onDownload() {
|
||||
if (!this.data.isVip) {
|
||||
wx.showModal({
|
||||
title: '会员提示',
|
||||
content: '音频下载是会员专属功能,是否前往开通?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
wx.navigateTo({ url: '/pages/vip/index' })
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
wx.showToast({ title: '下载功能开发中', icon: 'none' })
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 查看文案
|
||||
*/
|
||||
onTranscript() {
|
||||
const content = this.data.activeContent
|
||||
if (content && content.content) {
|
||||
wx.showModal({
|
||||
title: '完整文案',
|
||||
content: content.content,
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击中央 Banner:封面 ⇔ 文案切换
|
||||
*/
|
||||
onBannerTap() {
|
||||
this.setData({ showTranscript: !this.data.showTranscript })
|
||||
},
|
||||
|
||||
onLike() {
|
||||
const content = this.data.activeContent
|
||||
if (!content) return
|
||||
api.toggleLike({ contentId: content.id }).then(function (res) {
|
||||
wx.showToast({ title: res.code === 200 ? '已收藏 ♥' : '操作失败', icon: 'none' })
|
||||
}).catch(function () {
|
||||
wx.showToast({ title: '网络异常', icon: 'none' })
|
||||
})
|
||||
},
|
||||
|
||||
onShare() {
|
||||
wx.showToast({ title: '分享功能开发中', icon: 'none' })
|
||||
},
|
||||
|
||||
goBack() {
|
||||
wx.navigateBack()
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user