detail.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. // pages/video/detail.js
  2. import {getVideoDetail, getRealVideoUrl, postWithCommonParams, getRelatedVideos, getUuid} from '../../api/api'
  3. import {rnd} from '../../utils/util'
  4. import {apple} from "../../config/config";
  5. Page({
  6. data: {
  7. videoId: '',
  8. videoInfo: null,
  9. videoDetail: null,
  10. episodeList: [],
  11. currentEpisodeIndex: 0,
  12. currentEpisode: null, // 当前播放的剧集
  13. isPlaying: false,
  14. isLoading: true,
  15. title: '',
  16. scrollHeight: 0,
  17. windowHeight: 0,
  18. realVideoUrl: '', // 存储真实的视频播放地址
  19. videoStatus: 0, // 0 未播放 1 播放中 2 暂停
  20. duration: 0, // 视频总时长
  21. currentTime: 0, // 当前播放时间
  22. relatedVideos: [],
  23. tagId: 0,
  24. share_count: 1,
  25. scene: 0, // 场景值
  26. },
  27. onLoad: function (options) {
  28. const videoId = parseInt(options.id);
  29. const videoTitle = options.title ? decodeURIComponent(options.title) : '';
  30. const tagId = parseInt(options.tag_id);
  31. this.setData({
  32. scene: wx.getStorageSync('scene') || 1001
  33. })
  34. console.log('加载视频详情页,ID:', videoId, '标题:', videoTitle);
  35. // 获取系统信息
  36. this.getSystemInfo();
  37. // 如果有传递标题,则直接使用
  38. if (videoTitle) {
  39. this.setData({
  40. title: videoTitle,
  41. videoId: videoId,
  42. isLoading: true,
  43. tagId: tagId
  44. });
  45. } else {
  46. this.setData({
  47. videoId: videoId,
  48. isLoading: true,
  49. tagId: tagId
  50. });
  51. }
  52. this.loadVideoDetail(videoId);
  53. },
  54. onShow() {
  55. const pages = getCurrentPages();
  56. const currentPage = pages[pages.length - 1];
  57. const options = currentPage.options;
  58. console.log('scene', this.data.scene)
  59. if (+options.share_count === 1 && this.data.share_count === 1) {
  60. this.setData({
  61. share_count: 2
  62. })
  63. if(this.data.scene === 1007 || this.data.scene === 1008){
  64. this.goToBookDetail()
  65. }
  66. } else if (+options.share_count === 1 && this.data.share_count === 2) {
  67. this.setData({
  68. share_count: 3
  69. })
  70. }
  71. },
  72. /**
  73. * 获取uuid
  74. */
  75. getUUID() {
  76. return new Promise((resolve, reject) => {
  77. wx.login({
  78. success: res => {
  79. let body = {
  80. code: res.code,
  81. source_type: 1,
  82. source_id: ''
  83. }
  84. getUuid(body).then(async res => {
  85. resolve(res.uuid)
  86. }).catch((err) => {
  87. reject(err)
  88. })
  89. }
  90. })
  91. })
  92. },
  93. // 获取系统信息
  94. getSystemInfo() {
  95. const systemInfo = wx.getSystemInfoSync();
  96. this.setData({
  97. windowHeight: systemInfo.windowHeight
  98. });
  99. },
  100. // 加载视频详情
  101. async loadVideoDetail(id) {
  102. try {
  103. wx.showLoading({
  104. title: '加载中...',
  105. mask: true
  106. });
  107. //getUuid
  108. if (!getApp().globalData.uuid) {
  109. await this.getUUID().then(uuid => {
  110. getApp().globalData.uuid = uuid
  111. })
  112. }
  113. // 构建请求参数
  114. const params = {
  115. id,
  116. tag_id: this.data.tagId,
  117. uuid: getApp().globalData.uuid
  118. };
  119. const videoDetail = await getVideoDetail(params);
  120. console.log('视频详情数据:', videoDetail);
  121. if (videoDetail) {
  122. // 处理视频信息
  123. const formattedVideoInfo = {
  124. id: videoDetail.id,
  125. title: videoDetail.title || this.data.title,
  126. cover: videoDetail.cover_image,
  127. playCount: videoDetail.views || '0',
  128. playUV: videoDetail.play_uv || '0',
  129. videoUrl: '', // 暂时为空,等待获取真实播放地址
  130. description: videoDetail.description || '暂无简介',
  131. tags: videoDetail.tag_ids || [],
  132. likeCount: videoDetail.like || '0',
  133. shareCount: videoDetail.share || '0',
  134. isCollect: videoDetail.is_collect === 1,
  135. video_type: videoDetail.video_type, // 保存原始视频类型
  136. tag_ids: videoDetail.tag_ids // 保存标签ID列表
  137. };
  138. this.setData({
  139. videoInfo: formattedVideoInfo,
  140. title: formattedVideoInfo.title,
  141. isLoading: false
  142. });
  143. // 获取真实播放地址
  144. this.getVideoPlayUrl(videoDetail);
  145. // 加载相关视频
  146. this.loadRelatedVideos(videoDetail.tag_ids);
  147. } else {
  148. this.setData({
  149. isLoading: false
  150. });
  151. wx.showToast({
  152. title: '获取视频详情失败',
  153. icon: 'none'
  154. });
  155. }
  156. } catch (error) {
  157. console.error('获取视频详情失败:', error);
  158. this.setData({
  159. isLoading: false
  160. });
  161. wx.showToast({
  162. title: '获取视频详情失败',
  163. icon: 'none'
  164. });
  165. } finally {
  166. wx.hideLoading();
  167. }
  168. },
  169. // 获取视频播放地址
  170. async getVideoPlayUrl(videoDetail) {
  171. console.log(`videoDetail`, videoDetail)
  172. try {
  173. // 根据视频类型进行处理
  174. switch (videoDetail.video_type) {
  175. case 3: // OAS视频
  176. // 获取真实播放地址
  177. const tagId = videoDetail.tag_ids && videoDetail.tag_ids.length > 0 ? videoDetail.tag_ids[0] : 2072;
  178. let parseRes = await getRealVideoUrl(videoDetail.id, tagId);
  179. console.log('parseRes', parseRes)
  180. // 默认视频为免费视频
  181. videoDetail.lock = false
  182. // 标记暂停插屏是否显示过
  183. videoDetail.pauseInsertAd = false
  184. // 默认视频不显示插屏
  185. videoDetail.insertAd = false
  186. videoDetail.adType = 'video'
  187. videoDetail.likeNum = rnd(101, 209) / 10
  188. videoDetail.like = false
  189. videoDetail.shareNum = rnd(51, 99) / 10
  190. if (videoDetail.video_type !== 4) {
  191. videoDetail.playUrl = parseRes.url_info[0].url
  192. }
  193. if (videoDetail.is_top === 1) {
  194. videoDetail.top = true
  195. }
  196. this.setData({
  197. isLoading: false,
  198. videoDetail: videoDetail
  199. })
  200. break;
  201. case 4: // 微信视频
  202. // 直接使用video_vid
  203. this.setData({
  204. 'videoInfo.videoUrl': videoDetail.video_vid
  205. });
  206. break;
  207. default:
  208. // 默认使用url字段
  209. if (videoDetail.url) {
  210. this.setData({
  211. 'videoInfo.videoUrl': videoDetail.url
  212. });
  213. } else {
  214. throw new Error('不支持的视频类型');
  215. }
  216. }
  217. } catch (error) {
  218. console.error('获取视频播放地址失败:', error);
  219. wx.showToast({
  220. title: '无法获取视频播放地址',
  221. icon: 'none'
  222. });
  223. }
  224. },
  225. // 切换剧集
  226. switchEpisode(e) {
  227. const index = e.currentTarget.dataset.index;
  228. if (index === this.data.currentEpisodeIndex) return;
  229. const episode = this.data.episodeList[index];
  230. if (!episode) return;
  231. this.setData({
  232. currentEpisodeIndex: index,
  233. currentEpisode: episode,
  234. isPlaying: true
  235. });
  236. // 获取视频实例并播放
  237. const videoContext = wx.createVideoContext('myVideo');
  238. videoContext.play();
  239. },
  240. // 视频播放事件
  241. onVideoPlay() {
  242. this.setData({
  243. isPlaying: true,
  244. videoStatus: 1
  245. });
  246. // 可以添加播放埋点
  247. console.log('视频开始播放:', this.data.videoInfo.id);
  248. },
  249. // 视频暂停事件
  250. onVideoPause() {
  251. this.setData({
  252. isPlaying: false,
  253. videoStatus: 2
  254. });
  255. },
  256. // 视频播放结束事件
  257. onVideoEnd() {
  258. this.setData({
  259. isPlaying: false,
  260. videoStatus: 0
  261. });
  262. // 可以添加结束埋点
  263. console.log('视频播放结束:', this.data.videoInfo.id);
  264. },
  265. // 视频时间更新事件
  266. onVideoUpdate(e) {
  267. const {currentTime, duration} = e.detail;
  268. this.setData({
  269. currentTime,
  270. duration
  271. });
  272. },
  273. // 视频元数据加载完成
  274. onVideoLoaded(e) {
  275. console.log('视频元数据加载完成', e.detail);
  276. },
  277. // 点击视频控制区
  278. onClickVideoControls() {
  279. if (this.data.videoStatus === 1) {
  280. // 当前正在播放,暂停视频
  281. const videoContext = wx.createVideoContext('myVideo');
  282. videoContext.pause();
  283. } else {
  284. // 当前已暂停,开始播放
  285. const videoContext = wx.createVideoContext('myVideo');
  286. videoContext.play();
  287. }
  288. },
  289. // 点击相关推荐视频
  290. onRelatedVideoTap(e) {
  291. console.log(e.currentTarget.dataset)
  292. const videoId = e.currentTarget.dataset.id;
  293. const video = this.data.relatedVideos.find(item => item.id === videoId);
  294. // console.log('video',video)
  295. if (!video) {
  296. wx.showToast({
  297. title: '视频信息获取失败',
  298. icon: 'none'
  299. });
  300. return;
  301. }
  302. const tag_id = video.tag_id;
  303. // console.log('tag_id',tag_id)
  304. // 显示加载中提示
  305. wx.showLoading({
  306. title: '加载中...',
  307. mask: true
  308. });
  309. // 将标题进行URI编码处理
  310. const encodedTitle = encodeURIComponent(video.title || '');
  311. // 跳转到视频详情页
  312. wx.navigateTo({
  313. url: `/pages/video/detail?id=${videoId}&title=${encodedTitle}&tag_id=${tag_id}`,
  314. success: () => {
  315. wx.hideLoading();
  316. },
  317. fail: (err) => {
  318. console.error('跳转失败:', err);
  319. wx.hideLoading();
  320. wx.showToast({
  321. title: '跳转失败',
  322. icon: 'none'
  323. });
  324. }
  325. });
  326. },
  327. // 跳转到书籍详情
  328. goToBookDetail() {
  329. getApp().globalData.isShowDialog = true
  330. goToBookDetail({
  331. bookId: 7266,
  332. wxBookId: 'A1Hcfv456vGtMYxQjxUm8KNdJ8',
  333. chapterId: null
  334. });
  335. },
  336. // 返回上一页
  337. goBack() {
  338. wx.navigateBack({
  339. delta: 1
  340. }
  341. );
  342. // wx.redirectTo({
  343. // url: '/pages/video/video',
  344. // });
  345. console.log('返回上一页')
  346. },
  347. // 分享按钮点击事件
  348. onShareTap(e) {
  349. // 阻止事件冒泡
  350. e.stopPropagation();
  351. },
  352. // 分享给朋友
  353. onShareAppMessage(e) {
  354. // 如果是从推荐视频分享
  355. if (e.target && e.target.dataset.video) {
  356. const video = e.target.dataset.video;
  357. return {
  358. title: video.title,
  359. path: `/pages/video/video?shared_video_id=${video.id}&title=${encodeURIComponent(video.title)}&tag_id=${video.tag_ids[0]}&share_count=1&type=share`,
  360. imageUrl: video.cover_image,
  361. success: function (res) {
  362. wx.showToast({
  363. title: '分享成功',
  364. icon: 'success',
  365. duration: 1500
  366. });
  367. },
  368. fail: function (res) {
  369. wx.showToast({
  370. title: '分享失败',
  371. icon: 'none',
  372. duration: 1500
  373. });
  374. }
  375. };
  376. }
  377. // 默认分享当前视频
  378. const videoInfo = this.data.videoInfo;
  379. return {
  380. title: videoInfo.title,
  381. path: `/pages/video/video?shared_video_id=${videoInfo.id}&title=${encodeURIComponent(videoInfo.title)}&tag_id=${videoInfo.tag_ids[0]}&share_count=1&type=share`,
  382. imageUrl: videoInfo.cover,
  383. success: function (res) {
  384. wx.showToast({
  385. title: '分享成功',
  386. icon: 'success',
  387. duration: 1500
  388. });
  389. },
  390. fail: function (res) {
  391. wx.showToast({
  392. title: '分享失败',
  393. icon: 'none',
  394. duration: 1500
  395. });
  396. }
  397. };
  398. },
  399. // 分享到朋友圈
  400. onShareTimeline() {
  401. const videoInfo = this.data.videoInfo;
  402. return {
  403. title: videoInfo.title,
  404. query: `shared_video_id=${videoInfo.id}&title=${encodeURIComponent(videoInfo.title)}&tag_id=${videoInfo.tag_ids[0]}&share_count=1&type=share`,
  405. imageUrl: videoInfo.cover
  406. };
  407. },
  408. // 收藏视频
  409. toggleCollect() {
  410. const isCollect = !this.data.videoInfo.isCollect;
  411. this.setData({
  412. 'videoInfo.isCollect': isCollect
  413. });
  414. wx.showToast({
  415. title: isCollect ? '收藏成功' : '已取消收藏',
  416. icon: 'success'
  417. });
  418. },
  419. // 点赞视频
  420. likeVideo() {
  421. const currentLikes = parseInt(this.data.videoInfo.likeCount) || 0;
  422. this.setData({
  423. 'videoInfo.likeCount': (currentLikes + 1).toString()
  424. });
  425. wx.showToast({
  426. title: '点赞成功',
  427. icon: 'success'
  428. });
  429. },
  430. // 滚动事件
  431. onScroll(e) {
  432. this.setData({
  433. scrollHeight: e.detail.scrollTop
  434. });
  435. },
  436. // 加载相关视频
  437. async loadRelatedVideos(tagIds) {
  438. try {
  439. // 使用第一个标签ID获取相关视频
  440. const tagId = tagIds && tagIds.length > 0 ? tagIds[0] : 2250;
  441. console.log("原始ID:", apple.ghid)
  442. const relatedVideos = await getRelatedVideos({tag_id: tagId, gh_id: apple.ghid});
  443. // console.log('推荐视频',relatedVideos)
  444. // 处理相关视频数据
  445. const formattedVideos = relatedVideos.map(video => ({
  446. id: video.id,
  447. title: video.title,
  448. tag_id: video.tag_ids[0],
  449. cover_image: video.cover_image,
  450. playCount: video.views || '0',
  451. likeCount: video.like || '0',
  452. shareCount: video.share || '0'
  453. }));
  454. this.setData({
  455. relatedVideos: formattedVideos
  456. });
  457. } catch (error) {
  458. console.error('获取相关视频失败:', error);
  459. }
  460. }
  461. })