Files
urbanLifeline/urbanLifelineWeb/packages/workcase_wechat/static/jitsi-wrapper.html

172 lines
6.2 KiB
HTML
Raw Normal View History

2025-12-27 13:23:07 +08:00
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>视频会议</title>
<style>
* {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
overflow: hidden;
}
#jitsi-container {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="jitsi-container"></div>
<script>
// 从URL参数获取Jitsi会议链接
function getQueryParam(name) {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
}
const jitsiUrl = getQueryParam('url');
if (!jitsiUrl) {
console.error('未提供Jitsi会议URL');
alert('会议链接无效');
} else {
console.log('加载Jitsi会议:', jitsiUrl);
// 解析Jitsi URL获取域名和房间名
try {
const url = new URL(jitsiUrl);
const domain = url.hostname;
const roomName = url.pathname.substring(1); // 去掉开头的 /
console.log('Jitsi域名:', domain);
console.log('房间名:', roomName);
// 动态加载Jitsi External API
const script = document.createElement('script');
script.src = `https://${domain}/external_api.js`;
script.onload = function() {
console.log('Jitsi API加载成功');
initJitsi(domain, roomName);
};
script.onerror = function() {
console.error('Jitsi API加载失败');
// 如果API加载失败直接用iframe加载
loadJitsiIframe(jitsiUrl);
};
document.head.appendChild(script);
} catch (e) {
console.error('解析Jitsi URL失败:', e);
// 解析失败直接用iframe加载
loadJitsiIframe(jitsiUrl);
}
}
// 使用Jitsi External API初始化会议
function initJitsi(domain, roomName) {
const options = {
roomName: roomName,
width: '100%',
height: '100%',
parentNode: document.querySelector('#jitsi-container'),
interfaceConfigOverwrite: {
SHOW_JITSI_WATERMARK: false,
SHOW_WATERMARK_FOR_GUESTS: false,
TOOLBAR_BUTTONS: [
'microphone', 'camera', 'closedcaptions', 'desktop', 'fullscreen',
'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone'
]
},
configOverwrite: {
startWithAudioMuted: false,
startWithVideoMuted: false
}
};
const api = new JitsiMeetExternalAPI(domain, options);
// 监听会议事件
api.addEventListener('videoConferenceJoined', function(event) {
console.log('用户加入会议:', event);
sendMessageToUniApp({ event: 'videoConferenceJoined', data: event });
});
api.addEventListener('videoConferenceLeft', function(event) {
console.log('用户离开会议:', event);
sendMessageToUniApp({ event: 'videoConferenceLeft', data: event });
});
api.addEventListener('participantLeft', function(event) {
console.log('参与者离开:', event);
sendMessageToUniApp({ event: 'participantLeft', data: event });
});
api.addEventListener('readyToClose', function() {
console.log('会议准备关闭');
sendMessageToUniApp({ event: 'readyToClose' });
});
// 保存API实例供外部调用
window.jitsiApi = api;
}
// 使用普通iframe加载fallback方案
function loadJitsiIframe(url) {
console.log('使用iframe加载Jitsi');
const iframe = document.createElement('iframe');
iframe.src = url;
iframe.style.width = '100%';
iframe.style.height = '100%';
iframe.style.border = 'none';
iframe.allow = 'camera; microphone; fullscreen; display-capture';
document.getElementById('jitsi-container').appendChild(iframe);
}
// 发送消息给uni-app
function sendMessageToUniApp(message) {
console.log('发送消息给uni-app:', message);
// 尝试多种方式发送消息
if (window.uni && window.uni.postMessage) {
// uni-app环境
window.uni.postMessage({
data: message
});
}
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.uni) {
// iOS环境
window.webkit.messageHandlers.uni.postMessage(message);
}
if (window.parent !== window) {
// iframe环境
window.parent.postMessage(message, '*');
}
}
// 监听来自uni-app的消息
window.addEventListener('message', function(event) {
console.log('收到消息:', event.data);
if (event.data && event.data.action) {
switch (event.data.action) {
case 'hangup':
if (window.jitsiApi) {
window.jitsiApi.executeCommand('hangup');
}
break;
}
}
});
</script>
</body>
</html>