Files
sundynix-radio-mp/pages/player/index.js
T
2026-03-05 09:08:21 +08:00

269 lines
7.0 KiB
JavaScript

/**
* 播放器详情页
* 大封面、进度条、倍速切换、播放控制
* 从 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()
}
})