// pages/stationMonitor/stationMonitor.js const { get } = require('../../api/request.js'); Page({ /** * 页面的初始数据 */ data: { activeTab: 'weather', // 默认选中气象站 cameraList: [], isLoading: false }, /** * 生命周期函数--监听页面加载 */ onLoad(options) { // 页面加载时获取摄像头信息 this.getCameraList(); }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady() { }, /** * 生命周期函数--监听页面显示 */ onShow() { }, /** * 生命周期函数--监听页面隐藏 */ onHide() { }, /** * 生命周期函数--监听页面卸载 */ onUnload() { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh() { // 下拉刷新时重新获取摄像头列表 if (this.data.activeTab === 'camera') { this.getCameraList(); } wx.stopPullDownRefresh(); }, /** * 页面上拉触底事件的处理函数 */ onReachBottom() { }, /** * 用户点击右上角分享 */ onShareAppMessage() { }, /** * 切换选项卡 */ switchTab(e) { const tab = e.currentTarget.dataset.tab; console.log('切换到:', tab); this.setData({ activeTab: tab }); // 如果切换到摄像头选项卡,确保有数据 if (tab === 'camera' && this.data.cameraList.length === 0) { this.getCameraList(); } }, /** * 获取摄像头列表 */ getCameraList() { const app = getApp(); // 检查登录状态 if (!app.globalData.isLoggedIn) { wx.showToast({ title: '请先登录', icon: 'error' }); return; } this.setData({ isLoading: true }); // 模拟接口返回数据 setTimeout(() => { const mockResponse = { "code": "0001", "content": { "itemTotal": 4, "obj": [ { "id": "2025070715040300007", "name": "民勤01", "videoUrl4PcLive": "https://open.ys7.com/console/jssdk/pc.html?url=ezopen://open.ys7.com/FX6737162/1.live&accessToken=at.2o04glgs0q36cjugbvddqujz7tqrghx1-1ovr6lmf3k-03pij3c-304ziif7e&themeId=pcLive&env=&date=", "videoUrl4Security": "https://open.ys7.com/console/jssdk/pc.html?accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&url=ezopen://open.ys7.com/FY4056878/1.live&themeId=security&date=", "videoUrl4Simple": "https://open.ys7.com/console/jssdk/pc.html?accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&url=ezopen://open.ys7.com/FY4056878/1.live&themeId=simple&date=", "videoUrl4Standard": "https://open.ys7.com/console/jssdk/pc.html?accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&url=ezopen://open.ys7.com/FY4056878/1.live&themeId=standard&date=" }, { "id": "2025070715040300008", "name": "民勤02", "videoUrl4PcLive": "https://open.ys7.com/console/jssdk/pc.html?url=ezopen://open.ys7.com/FY4056879/1.live&accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&themeId=pcLive&env=&date=", "videoUrl4Security": "https://open.ys7.com/console/jssdk/pc.html?accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&url=ezopen://open.ys7.com/FY4056879/1.live&themeId=security&date=", "videoUrl4Simple": "https://open.ys7.com/console/jssdk/pc.html?accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&url=ezopen://open.ys7.com/FY4056879/1.live&themeId=simple&date=", "videoUrl4Standard": "https://open.ys7.com/console/jssdk/pc.html?accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&url=ezopen://open.ys7.com/FY4056879/1.live&themeId=standard&date=" }, { "id": "2025070715040300009", "name": "民勤03", "videoUrl4PcLive": "https://open.ys7.com/console/jssdk/pc.html?url=ezopen://open.ys7.com/FY4056880/1.live&accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&themeId=pcLive&env=&date=", "videoUrl4Security": "https://open.ys7.com/console/jssdk/pc.html?accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&url=ezopen://open.ys7.com/FY4056880/1.live&themeId=security&date=", "videoUrl4Simple": "https://open.ys7.com/console/jssdk/pc.html?accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&url=ezopen://open.ys7.com/FY4056880/1.live&themeId=simple&date=", "videoUrl4Standard": "https://open.ys7.com/console/jssdk/pc.html?accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&url=ezopen://open.ys7.com/FY4056880/1.live&themeId=standard&date=" }, { "id": "2025070715040300010", "name": "民勤04", "videoUrl4PcLive": "https://open.ys7.com/console/jssdk/pc.html?url=ezopen://open.ys7.com/FY4056881/1.live&accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&themeId=pcLive&env=&date=", "videoUrl4Security": "https://open.ys7.com/console/jssdk/pc.html?accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&url=ezopen://open.ys7.com/FY4056881/1.live&themeId=security&date=", "videoUrl4Simple": "https://open.ys7.com/console/jssdk/pc.html?accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&url=ezopen://open.ys7.com/FY4056881/1.live&themeId=simple&date=", "videoUrl4Standard": "https://open.ys7.com/console/jssdk/pc.html?accessToken=at.87a8u4z04s3gom0o6i0cpgz35kuhu8xh-67xrfkiy90-0nnbl6z-r0v9mckp3&url=ezopen://open.ys7.com/FY4056881/1.live&themeId=standard&date=" } ], "pageCurr": 1, "pageSize": 4, "pageTotal": 1 }, "msg": "请求成功", "success": true }; console.log('模拟接口返回数据:', mockResponse); if (mockResponse.success && mockResponse.code === '0001') { // 处理返回的摄像头数据 const cameraList = mockResponse.content.obj.map(item => { // 从萤石云URL中提取设备信息并生成RTMP地址 let rtmpUrl = ''; if (item.videoUrl4PcLive) { // 提取设备序列号和通道号 const ezopenMatch = item.videoUrl4PcLive.match(/ezopen:\/\/open\.ys7\.com\/([^\/]+)\/(\d+)\.live/); const tokenMatch = item.videoUrl4PcLive.match(/accessToken=([^&]+)/); if (ezopenMatch && tokenMatch) { const deviceSerial = ezopenMatch[1]; // 设备序列号 const channelNo = ezopenMatch[2]; // 通道号 const accessToken = tokenMatch[1]; // 访问令牌 // 生成RTMP地址 rtmpUrl = `rtmp://open.ys7.com:1935/live/${deviceSerial}/${channelNo}?accessToken=${accessToken}`; // 备用HLS地址 const hlsUrl = `https://open.ys7.com:443/live/${deviceSerial}/${channelNo}.m3u8?accessToken=${accessToken}`; console.log('生成的RTMP地址:', rtmpUrl); console.log('生成的HLS地址:', hlsUrl); } } return { id: item.id, name: item.name, online: true, // 默认在线,实际项目中可能需要额外的状态检查 thumbnail: '/images/camera-thumb1.jpg', // 默认缩略图 lastUpdate: new Date().toLocaleString(), // 当前时间作为最后更新时间 isPlaying: false, // 视频播放状态 rtmpUrl: rtmpUrl, // RTMP流地址 videoUrl4PcLive: item.videoUrl4PcLive, // 原始PC播放地址 videoUrl4Security: item.videoUrl4Security, videoUrl4Simple: item.videoUrl4Simple, videoUrl4Standard: item.videoUrl4Standard }; }); this.setData({ cameraList: cameraList, isLoading: false }); console.log('处理后的摄像头列表:', cameraList); } else { console.error('获取摄像头列表失败:', mockResponse.msg); this.setData({ isLoading: false }); wx.showToast({ title: mockResponse.msg || '获取摄像头列表失败', icon: 'none' }); } }, 1000); // 模拟网络延迟1秒 }, /** * 播放视频 */ playVideo(e) { const camera = e.currentTarget.dataset.camera; console.log('播放摄像头:', camera.name); if (!camera.online) { wx.showToast({ title: '摄像头离线', icon: 'error' }); return; } // 检查视频URL是否有效 if (!camera.videoUrl4PcLive) { wx.showToast({ title: '视频地址无效', icon: 'error' }); return; } console.log('视频URL:', camera.videoUrl4PcLive); // 更新视频播放状态 const cameraList = this.data.cameraList.map(item => { if (item.id === camera.id) { return { ...item, isPlaying: true }; } return item; }); this.setData({ cameraList: cameraList }); // 延迟一下让live-player组件更新 setTimeout(() => { console.log('开始播放直播:', camera.videoUrl4PcLive); }, 100); }, /** * 暂停视频 */ pauseVideo(e) { const camera = e.currentTarget.dataset.camera; console.log('暂停摄像头:', camera.name); // 更新视频播放状态 const cameraList = this.data.cameraList.map(item => { if (item.id === camera.id) { return { ...item, isPlaying: false }; } return item; }); this.setData({ cameraList: cameraList }); }, /** * 停止视频 */ stopVideo(e) { const camera = e.currentTarget.dataset.camera; console.log('停止摄像头:', camera.name); // 更新视频播放状态 const cameraList = this.data.cameraList.map(item => { if (item.id === camera.id) { return { ...item, isPlaying: false }; } return item; }); this.setData({ cameraList: cameraList }); }, /** * 测试视频URL */ testVideoUrl(e) { const camera = e.currentTarget.dataset.camera; console.log('测试视频URL:', camera.name); console.log('原始URL:', camera.videoUrl4PcLive); console.log('RTMP URL:', camera.rtmpUrl); // 显示URL信息 wx.showModal({ title: '视频URL信息', content: `摄像头: ${camera.name}\n原始URL: ${camera.videoUrl4PcLive}\nRTMP URL: ${camera.rtmpUrl}`, showCancel: false, confirmText: '确定' }); }, /** * 直播播放器状态变化 */ onLivePlayerStateChange(e) { const camera = e.currentTarget.dataset.camera; console.log('直播播放器状态变化:', camera.name, e.detail); const { code } = e.detail; // 显示状态信息给用户 let statusText = ''; let isPlaying = false; switch (code) { case 2001: statusText = '已经连接服务器'; break; case 2002: statusText = '已经连接 RTMP 服务器,开始拉流'; isPlaying = true; break; case 2003: statusText = '网络接收到首个视频数据包(IDR)'; isPlaying = true; break; case 2004: statusText = '视频播放开始'; isPlaying = true; break; case 2005: statusText = '视频播放进度'; isPlaying = true; break; case 2006: statusText = '视频播放结束'; isPlaying = false; break; case 2007: statusText = '视频播放Loading'; isPlaying = true; break; case 2008: statusText = '解码器启动'; isPlaying = true; break; case 2009: statusText = '视频分辨率改变'; isPlaying = true; break; case 2101: statusText = '网络断连,且经多次重连抢救无效'; isPlaying = false; break; case 2102: statusText = '获取加速拉流地址失败'; isPlaying = false; break; case 2103: statusText = '当前视频帧解码失败'; isPlaying = false; break; case 2104: statusText = '网络断连, 已启动自动重连'; isPlaying = false; break; case 2105: statusText = '网络来断连, 且经多次重连抢救无效'; isPlaying = false; break; case 2106: statusText = '网络来断连, 且经多次重连抢救无效'; isPlaying = false; break; default: statusText = `未知状态码: ${code}`; break; } console.log(`摄像头 ${camera.name} 状态: ${statusText}`); // 更新播放状态 const cameraList = this.data.cameraList.map(item => { if (item.id === camera.id) { return { ...item, isPlaying: isPlaying }; } return item; }); this.setData({ cameraList: cameraList }); }, /** * 直播播放器网络状态 */ onLivePlayerNetStatus(e) { const camera = e.currentTarget.dataset.camera; console.log('直播播放器网络状态:', camera.name, e.detail); }, /** * 直播播放器错误 */ onLivePlayerError(e) { const camera = e.currentTarget.dataset.camera; console.error('直播播放器错误:', camera.name, e.detail); wx.showToast({ title: '直播播放失败', icon: 'error' }); // 更新播放状态 const cameraList = this.data.cameraList.map(item => { if (item.id === camera.id) { return { ...item, isPlaying: false }; } return item; }); this.setData({ cameraList: cameraList }); }, /** * 全屏播放视频 */ fullscreenVideo(e) { const camera = e.currentTarget.dataset.camera; console.log('全屏播放:', camera.name); if (!camera.online) { wx.showToast({ title: '摄像头离线', icon: 'error' }); return; } // 使用PC直播URL进行全屏播放 if (camera.videoUrl4PcLive) { console.log('全屏视频URL:', camera.videoUrl4PcLive); wx.showModal({ title: '全屏播放', content: `即将全屏播放 ${camera.name} 的视频流`, confirmText: '开始播放', success: (res) => { if (res.confirm) { // 这里可以跳转到全屏视频播放页面 wx.showToast({ title: '正在加载全屏视频...', icon: 'loading' }); // 模拟全屏视频加载 setTimeout(() => { wx.showToast({ title: '全屏播放中', icon: 'success' }); }, 1500); } } }); } else { wx.showToast({ title: '全屏视频地址无效', icon: 'error' }); } }, /** * 摄像头设置 */ cameraSettings(e) { const camera = e.currentTarget.dataset.camera; console.log('摄像头设置:', camera.name); wx.showActionSheet({ itemList: ['云台控制', '录像设置', '画质调节', '报警设置'], success: (res) => { const actions = ['云台控制', '录像设置', '画质调节', '报警设置']; wx.showToast({ title: `${actions[res.tapIndex]}功能开发中`, icon: 'none' }); } }); } })