// pages/video/detail.js import {getVideoDetail, getRealVideoUrl, postWithCommonParams, getRelatedVideos, getUuid} from '../../api/api' import {rnd, SendEvent} from '../../utils/util' import {apple} from "../../config/config"; const app = getApp(); let interstitialAd = null let insertAdInterval = null Page({ data: { videoId: '', videoInfo: null, videoDetail: null, episodeList: [], currentEpisodeIndex: 0, currentEpisode: null, // 当前播放的剧集 isPlaying: false, isLoading: true, title: '', scrollHeight: 0, windowHeight: 0, realVideoUrl: '', // 存储真实的视频播放地址 videoStatus: 0, // 0 未播放 1 播放中 2 暂停 duration: 0, // 视频总时长 currentTime: 0, // 当前播放时间 relatedVideos: [], tagId: 0, share_count: 1, scene: 0, // 场景值 }, onLoad: function (options) { const videoId = parseInt(options.id); const videoTitle = options.title ? decodeURIComponent(options.title) : ''; const tagId = parseInt(options.tag_id); this.setData({ scene: wx.getStorageSync('scene') || 1001 }) SendEvent('show_video', { "video_id": videoId, "tag_id": tagId, "scene": this.data.scene, "uuid": app.globalData.uuid }); console.log('加载视频详情页,ID:', videoId, '标题:', videoTitle); // 获取系统信息 this.getSystemInfo(); // 如果有传递标题,则直接使用 if (videoTitle) { this.setData({ title: videoTitle, videoId: videoId, isLoading: true, tagId: tagId }); } else { this.setData({ videoId: videoId, isLoading: true, tagId: tagId }); } this.rewardVideoLoad(); this.interstitalLoad(); this.loadVideoDetail(videoId); app.globalData.isEnterVideoDetail = true; }, onShow() { const pages = getCurrentPages(); const currentPage = pages[pages.length - 1]; const options = currentPage.options; console.log('scene', this.data.scene) if (+options.share_count === 1 && this.data.share_count === 1) { this.setData({ share_count: 2 }) if ((this.data.scene === 1007 || this.data.scene === 1008)) { console.log('准备跳转novel') this.goToBookDetail() } else { console.log('没有跳转novel') } } else if (+options.share_count === 1 && this.data.share_count === 2) { this.setData({ share_count: 3 }) } }, /** * 获取uuid */ getUUID() { return new Promise((resolve, reject) => { wx.login({ success: res => { let body = { code: res.code, source_type: 1, source_id: '' } getUuid(body).then(async res => { resolve(res.uuid) }).catch((err) => { reject(err) }) } }) }) }, // 获取系统信息 getSystemInfo() { const systemInfo = wx.getSystemInfoSync(); this.setData({ windowHeight: systemInfo.windowHeight }); }, // 加载视频详情 async loadVideoDetail(id) { try { wx.showLoading({ title: '加载中...', mask: true }); //getUuid if (!getApp().globalData.uuid) { await this.getUUID().then(uuid => { getApp().globalData.uuid = uuid }) } // 构建请求参数 const params = { id, tag_id: this.data.tagId, uuid: getApp().globalData.uuid }; const videoDetail = await getVideoDetail(params); console.log('视频详情数据:', videoDetail); if (videoDetail) { // 处理视频信息 const formattedVideoInfo = { id: videoDetail.id, title: videoDetail.title || this.data.title, cover: videoDetail.cover_image, playCount: videoDetail.views || '0', playUV: videoDetail.play_uv || '0', videoUrl: '', // 暂时为空,等待获取真实播放地址 description: videoDetail.description || '暂无简介', tags: videoDetail.tag_ids || [], likeCount: videoDetail.like || '0', shareCount: videoDetail.share || '0', isCollect: videoDetail.is_collect === 1, video_type: videoDetail.video_type, // 保存原始视频类型 tag_ids: videoDetail.tag_ids // 保存标签ID列表 }; this.setData({ videoInfo: formattedVideoInfo, title: formattedVideoInfo.title, isLoading: false }); // 获取真实播放地址 this.getVideoPlayUrl(videoDetail); this.interstitalEnterPageShow() // 加载相关视频 this.loadRelatedVideos(videoDetail.tag_ids); } else { this.setData({ isLoading: false }); wx.showToast({ title: '获取视频详情失败', icon: 'none' }); } } catch (error) { console.error('获取视频详情失败:', error); this.setData({ isLoading: false }); wx.showToast({ title: '获取视频详情失败', icon: 'none' }); } finally { wx.hideLoading(); } }, // 获取视频播放地址 async getVideoPlayUrl(videoDetail) { console.log(`videoDetail`, videoDetail) try { // 根据视频类型进行处理 switch (videoDetail.video_type) { case 3: // OAS视频 // 获取真实播放地址 const tagId = videoDetail.tag_ids && videoDetail.tag_ids.length > 0 ? videoDetail.tag_ids[0] : 2072; let parseRes = await getRealVideoUrl(videoDetail.id, this.data.tagId); // 此处需要使用传入的tag_id,否则视频有多个tag_id时,会无法获取到真实播放地址 console.log('parseRes', parseRes) // 默认视频为免费视频 videoDetail.lock = false // 标记暂停插屏是否显示过 videoDetail.pauseInsertAd = false // 默认视频不显示插屏 videoDetail.insertAd = false videoDetail.adType = 'video' videoDetail.likeNum = rnd(101, 209) / 10 videoDetail.like = false videoDetail.shareNum = rnd(51, 99) / 10 if (videoDetail.video_type !== 4) { videoDetail.playUrl = parseRes.url_info[0].url } if (videoDetail.is_top === 1) { videoDetail.top = true } this.setData({ isLoading: false, videoDetail: videoDetail }) break; case 4: // 微信视频 // 直接使用video_vid this.setData({ 'videoInfo.videoUrl': videoDetail.video_vid }); break; default: // 默认使用url字段 if (videoDetail.url) { this.setData({ 'videoInfo.videoUrl': videoDetail.url }); } else { throw new Error('不支持的视频类型'); } } } catch (error) { console.error('获取视频播放地址失败:', error); wx.showToast({ title: '无法获取视频播放地址', icon: 'none' }); } }, // 切换剧集 switchEpisode(e) { const index = e.currentTarget.dataset.index; if (index === this.data.currentEpisodeIndex) return; const episode = this.data.episodeList[index]; if (!episode) return; this.setData({ currentEpisodeIndex: index, currentEpisode: episode, isPlaying: true }); // 获取视频实例并播放 const videoContext = wx.createVideoContext('myVideo'); videoContext.play(); }, // 视频播放事件 onVideoPlay() { this.setData({ isPlaying: true, videoStatus: 1 }); // 可以添加播放埋点 console.log('视频开始播放:', this.data.videoInfo.id); }, // 视频暂停事件 onVideoPause() { this.setData({ isPlaying: false, videoStatus: 2 }); console.log('视频暂停:', this.data.videoInfo.id) }, // 视频播放结束事件 onVideoEnd() { this.setData({ isPlaying: false, videoStatus: 0 }); // 可以添加结束埋点 console.log('视频播放结束:', this.data.videoInfo.id); }, // 视频时间更新事件 onVideoUpdate(e) { const {currentTime, duration} = e.detail; this.setData({ currentTime, duration }); }, // 视频元数据加载完成 onVideoLoaded(e) { console.log('视频元数据加载完成', e.detail); }, // 视频播放 makeVideoPlay() { if (!this.data.videoInfo.lock && this.data.videoStatus == 2) { let video = this.getCurrentVideoContext() video.play() } }, // 视频暂停 makeVideoPause() { if (this.data.videoStatus == 1) { let video = this.getCurrentVideoContext() video.pause() } }, // 获取当前视频播放器实例 getCurrentVideoContext() { return wx.createVideoContext(`myVideo`, this) }, // 点击视频控制区 onClickVideoControls() { if (this.data.videoStatus === 1) { // 当前正在播放,暂停视频 const videoContext = wx.createVideoContext('myVideo'); videoContext.pause(); this.insertAdType = 1; this.interstitalPlayFn(); } else { // 当前已暂停,开始播放 const videoContext = wx.createVideoContext('myVideo'); videoContext.play(); } }, // 点击相关推荐视频 onRelatedVideoTap(e) { console.log(e.currentTarget.dataset) const videoId = e.currentTarget.dataset.id; const video = this.data.relatedVideos.find(item => item.id === videoId); // console.log('video',video) if (!video) { wx.showToast({ title: '视频信息获取失败', icon: 'none' }); return; } const tag_id = video.tag_ids[0]; // console.log('tag_id',tag_id) // 显示加载中提示 wx.showLoading({ title: '加载中...', mask: true }); // 将标题进行URI编码处理 const encodedTitle = encodeURIComponent(video.title || ''); this.unlockUrl = `/pages/video/detail?id=${videoId}&title=${encodedTitle}&tag_id=${tag_id}`; SendEvent('click_recommend_video', {"video_id": videoId, "tag_id": tag_id, "uuid": app.globalData.uuid}); if (!video.lock) { // 跳转到视频详情页 wx.navigateTo({ url: this.unlockUrl, success: () => { wx.hideLoading(); }, fail: (err) => { console.error('跳转失败:', err); wx.hideLoading(); wx.showToast({ title: '跳转失败', icon: 'none' }); } }); } else { this.rewardType = 2 this.rewardVideoPlayFn() } }, // 跳转到书籍详情 goToBookDetail() { getApp().globalData.isShowDialog = true goToBookDetail({ bookId: 10745, wxBookId: 'A1L2D5CPFHZW6Gzr9VdypmijDJ', chapterId: null }); }, // 返回上一页 goBack() { wx.navigateBack({ delta: 1 } ); // wx.redirectTo({ // url: '/pages/video/video', // }); console.log('返回上一页') SendEvent('click_return_list', { "video_id": this.data.videoId, "tag_id": this.data.tagId, "uuid": app.globalData.uuid }); }, // 分享按钮点击事件 onShareTap(e) { // 阻止事件冒泡 e.stopPropagation(); }, // 分享给朋友 onShareAppMessage(e) { const jump = wx.getStorageSync('jump'); // 是否跳转阅读器 let url = ''; // 如果是从推荐视频分享 if (e.target && e.target.dataset.video) { const video = e.target.dataset.video; url = `/pages/video/video?shared_video_id=${video.id}&title=${encodeURIComponent(video.title)}&tag_id=${video.tag_ids[0]}&share_count=1&type=share`; if (jump === 1) { url += '&jump=1'; } SendEvent('click_share', {"video_id": video.id, "tag_id": video.tag_ids[0]}); return { title: video.title, path: url, imageUrl: video.cover_image, success: function (res) { wx.showToast({ title: '分享成功', icon: 'success', duration: 1500 }); }, fail: function (res) { wx.showToast({ title: '分享失败', icon: 'none', duration: 1500 }); } }; } // 默认分享当前视频 const videoInfo = this.data.videoInfo; url = `/pages/video/video?shared_video_id=${videoInfo.id}&title=${encodeURIComponent(videoInfo.title)}&tag_id=${videoInfo.tag_ids[0]}&share_count=1&type=share`; if (jump === 1) { url += '&jump=1'; } SendEvent('click_share', {"video_id": videoInfo.id, "tag_id": videoInfo.tag_ids[0]}); return { title: videoInfo.title, path: url, imageUrl: videoInfo.cover, success: function (res) { wx.showToast({ title: '分享成功', icon: 'success', duration: 1500 }); }, fail: function (res) { wx.showToast({ title: '分享失败', icon: 'none', duration: 1500 }); } }; }, // 分享到朋友圈 onShareTimeline() { const videoInfo = this.data.videoInfo; const jump = wx.getStorageSync('jump'); // 是否跳转阅读器 let params = `shared_video_id=${videoInfo.id}&title=${encodeURIComponent(videoInfo.title)}&tag_id=${videoInfo.tag_ids[0]}&share_count=1&type=share`; if (jump === 1) { params += '&jump=1'; } SendEvent('click_share_moment', {"video_id": videoInfo.id, "tag_id": videoInfo.tag_ids[0]}); return { title: videoInfo.title, query: params, imageUrl: videoInfo.cover }; }, // 收藏视频 toggleCollect() { const isCollect = !this.data.videoInfo.isCollect; this.setData({ 'videoInfo.isCollect': isCollect }); wx.showToast({ title: isCollect ? '收藏成功' : '已取消收藏', icon: 'success' }); }, // 点赞视频 likeVideo() { const currentLikes = parseInt(this.data.videoInfo.likeCount) || 0; this.setData({ 'videoInfo.likeCount': (currentLikes + 1).toString() }); wx.showToast({ title: '点赞成功', icon: 'success' }); }, // 滚动事件 onScroll(e) { this.setData({ scrollHeight: e.detail.scrollTop }); }, // 加载相关视频 async loadRelatedVideos(tagIds) { try { // 使用第一个标签ID获取相关视频 const tagId = tagIds && tagIds.length > 0 ? tagIds[0] : 2072; console.log("原始ID:", apple.ghid) const relatedVideos = await getRelatedVideos({tag_id: tagId, gh_id: apple.ghid}); // 需要播放激励视频的索引 let rewardIndexList = [] console.log('详情激励配置', app.globalData.ads_config) if (app.globalData.ads_config.detailListLockIndex) { rewardIndexList = app.globalData.ads_config.detailListLockIndex.split(' ').map(i => { return i - 1 }) } console.log('详情激励顺序', rewardIndexList) // 处理相关视频数据 // const formattedVideos = relatedVideos.map((video,index) => ({ // id: video.id, // title: video.title, // adType:'video', // tag_id: video.tag_ids[0], // cover_image: video.cover_image, // playCount: video.views || '0', // likeCount: video.like || '0', // shareCount: video.share || '0', // })); const formattedVideos = relatedVideos.map((video, index) => { video.adType = 'video' video.lock = rewardIndexList.includes(index); return video }); this.setData({ relatedVideos: formattedVideos }); console.log('相关视频', formattedVideos) } catch (error) { console.error('获取相关视频失败:', error); } }, // 激励视频加载 rewardVideoLoad() { if (wx.createRewardedVideoAd) { let that = this this.videoAd = wx.createRewardedVideoAd({ adUnitId: apple.ads.rewardAdId }) this.videoAd.onLoad(() => { console.log('详情页激励load success') }) this.videoAd.onError((err) => { console.log('详情页激励load error', err) }) this.videoAd.onClose((res) => { // 用户点击了【关闭广告】按钮 this.setData({ isLoadingVideo: false }); console.log('详情页激励close', res) if (res && res.isEnded) { // 发放奖励 if (this.rewardType === 1) { this.setData({ [`videoInfo.lock`]: false, }) const video = this.getCurrentVideoContext() video.play() } else { wx.redirectTo({ url: this.unlockUrl }) } } else { // 未看完整视频 // wx.showModal({ // title: '提示', // content: '您需要观看完毕才能进行文章查看,重新播放广告吗?', // success (res) { // if (res.confirm) { // that.rewardVideoPlayFn() // } else if (res.cancel) { // console.log('用户点击取消') // } // } // }) } }) } }, // 激励视频展示 rewardVideoPlayFn() { wx.showLoading({ title: '解锁视频中', }) setTimeout(function () { wx.hideLoading() }, 2000) this.videoAd.show().catch((err) => { console.log('激励视频播放失败', err) wx.showToast({ title: '激励视频广告播放失败,请稍后再试', icon: 'none' }) }) }, // 进入页面插屏 interstitalEnterPageShow() { insertAdInterval = setTimeout(() => { console.log('详情页进入页面插屏调用') this.insertAdType = 2 this.interstitalPlayFn() }, 2000) }, // 插屏广告加载 interstitalLoad() { // const _this = this interstitialAd = wx.createInterstitialAd({ adUnitId: apple.ads.insertAdId }) interstitialAd.onLoad(() => { console.log('详情视频页插屏广告 load success') }) interstitialAd.onError((err) => { console.log('详情视频页插屏广告onError', err) }) interstitialAd.onClose(() => { console.log('详情视频页插屏广告onClose') this.makeVideoPlay() }) }, // 插屏广告展示 interstitalPlayFn() { // const _this = this if (interstitialAd) { interstitialAd.show().then(() => { console.log('插屏显示,视频暂停') if (this.insertAdType !== 1) { setTimeout(() => { this.makeVideoPause() }, 500) } }).catch((err) => { if (this.insertAdType !== 1) { setTimeout(() => { this.makeVideoPlay() }, 1000) } console.error('详情页插屏显示错误', err) }) } }, })