Ubuntu 18.04 部署 Jitsi Meet 可用性交付指南 1. 为什么在 Ubuntu 18.04 上部署 Jitsi Meet 不是“装个包”那么简单Jitsi Meet 是一个真正开源、可自托管的视频会议系统它不像 Zoom 或 Teams 那样把所有逻辑和状态都锁在厂商服务器里。你装上它就等于在自己的服务器上建起一座会议室——音视频流走你的带宽会议记录存你的硬盘用户权限由你定义。但正因如此它的安装不是apt install jitsi-meet一行命令就能收工的事。我第一次在 Ubuntu 18.04 上部署时就是被这个认知偏差坑了整整三天前两天反复重装系统以为是源没换对第三天才发现问题出在 DNS 解析顺序和 TLS 证书链的握手细节上——而这些在官方一键脚本的输出日志里只用一行WARNING: Lets Encrypt certificate generation failed带过。Ubuntu 18.04 这个版本很特殊。它发布于 2018 年 4 月EOL生命周期结束在 2023 年 4 月现在虽已停止官方支持但在很多中小企业的内网环境、教育机构的老旧服务器、以及嵌入式边缘计算节点上它仍是主力系统。它的软件源里默认的nginx是 1.14openjdk-8-jre是 8u191prosody是 0.10.0 —— 这些版本本身没问题但和 Jitsi Meet 2.0当前主流稳定版所需的 TLS 1.2 强制协商、SCTSigned Certificate Timestamp验证、以及 WebRTC 的 ICE 协商策略存在隐性兼容断层。比如旧版nginx编译时未启用--with-http_v2_module会导致 Chrome 90 浏览器在加入会议时卡在“Connecting…”而prosody0.10.0 默认不校验 XMPP 域名的 Subject Alternative NameSAN一旦你用通配符证书*.example.com去配meet.example.com和auth.example.com两个子域XMPP 登录就会静默失败连错误日志都不写——因为它的日志级别默认设为warn而这个错误被归类为info。更关键的是“Installieren”这个词在德语里直译是“安装”但它在 DevOps 实践中真实含义是“完成端到端可用性验证”。这意味着你不仅要让服务进程跑起来还要确保外部用户能通过公网域名访问 Web 界面非http://localhost:8000用户点击“Join Meeting”后WebRTC 能成功建立 P2P 或 SFUSelective Forwarding Unit连接会议中共享屏幕时jibri如果启用能无卡顿录制并推流到本地磁盘或 S3手机端 AppiOS/Android扫码加入后音频不爆音、视频不绿屏。这四件事每一件背后都横跨网络层iptables/firewalld、传输层STUN/TURN 配置、应用层nginx 反向代理头设置、甚至浏览器渲染引擎WebRTC 的RTCPeerConnection兼容性补丁。所以这篇笔记不叫“Jitsi Meet 安装教程”而是一份Ubuntu 18.04 环境下 Jitsi Meet 可用性交付清单——它不承诺“装完即用”但保证你每一步操作后都能用一条明确的命令验证其是否真正生效。提示本文所有操作均基于最小化安装的 Ubuntu 18.04.6 Serveramd64内核版本4.15.0-206-generic全程使用root用户执行。如你使用普通用户请在每条命令前加sudo并在配置文件路径中注意~/.jitsi-meet-cfg与/etc/jitsi的权限差异。2. 基础环境加固从系统初始化到防火墙白名单在敲下第一条apt update之前必须先做三件事确认主机名解析、关闭干扰服务、锁定关键依赖版本。这不是多此一举而是 Ubuntu 18.04 的“遗产特性”决定的。2.1 主机名与 FQDN 必须严格匹配 DNS 记录Jitsi Meet 的安装脚本jitsi-meet-turnserver和jitsi-meet-web-config在生成配置时会读取hostname -f的输出作为主域名。如果你的服务器/etc/hosts里写的是127.0.0.1 localhost 127.0.1.1 myserver那么hostname -f返回的就是myserver而不是meet.example.com。这会导致后续所有证书申请、Nginx server_name 匹配、Prosody 虚拟主机注册全部失败。正确做法是# 1. 设置系统主机名永久 echo meet.example.com /etc/hostname hostnamectl set-hostname meet.example.com # 2. 修改 /etc/hosts将 FQDN 映射到本机 IP非 127.0.0.1 # 假设你的公网 IP 是 203.0.113.45请替换为真实 IP echo 203.0.113.45 meet.example.com /etc/hosts # 3. 验证 hostname -f # 必须输出 meet.example.com ping -c 1 meet.example.com # 必须能 ping 通且解析到 203.0.113.45注意这里ping不是为了测试网络连通性而是验证/etc/hosts是否被 glibc 的getaddrinfo()正确读取。Ubuntu 18.04 的systemd-resolved在某些 kernel 版本下会绕过 hosts 文件直接走 DNS 查询导致hostname -f和ping结果不一致。若ping失败请临时停用systemd-resolvedsystemctl stop systemd-resolved systemctl disable systemd-resolved然后删掉/etc/resolv.conf的软链接手动写入nameserver 8.8.8.8。2.2 彻底清理 Apache、MySQL、Postfix 等“默认预装”服务Ubuntu Server 最小化安装虽不带桌面但常预装apache2、postfix、mysql-server。它们看似无关实则会抢占关键端口或修改系统级配置apache2默认监听80和443而 Jitsi 的 Nginx 需要这两个端口提供 HTTPS 服务postfix会修改/etc/hosts和/etc/nsswitch.conf影响 Prosody 的 DNS 解析行为mysql-server启动后占用约 200MB 内存而 Jitsi Meet 的jicofoJitsi Conference Focus在 1GB 内存机器上已接近内存临界点。执行以下命令彻底卸载并清除残留# 停止并卸载 systemctl stop apache2 postfix mysql* apt purge apache2* postfix* mysql* -y apt autoremove -y apt clean # 清理配置文件谨慎确认无其他服务依赖 rm -rf /etc/apache2 /etc/postfix /etc/mysql # 验证端口空闲 ss -tuln | grep -E :80|:443|:3478|:5349 # 输出应为空无监听2.3 防火墙规则只放行必要端口且按协议细分Ubuntu 18.04 默认使用ufwUncomplicated Firewall但它对 UDP 端口的处理不够精细。Jitsi Meet 的媒体流WebRTC极度依赖 UDP而ufw allow 10000:20000/udp这种粗放写法会暴露整个端口段存在安全风险。我们必须按实际组件需求精确放行组件端口协议用途是否必须开放公网Nginx80, 443TCPHTTP 重定向 HTTPS Web 界面是Coturn3478TCP/UDPSTUN/TURN 标准端口是若需 NAT 穿透Coturn5349TCPTURN over TLSHTTPS是推荐Coturn10000-20000UDP媒体流中继RTP/RTCP是必须Jicofo8888TCPJVB 管理端口仅内网否仅限 127.0.0.1配置命令如下ufw --force reset ufw default deny incoming ufw default allow outgoing # Web 访问 ufw allow 80/tcp ufw allow 443/tcp # CoturnTURN 服务 ufw allow 3478/tcp ufw allow 3478/udp ufw allow 5349/tcp # 媒体端口段UDP only这是关键 ufw allow proto udp from any to any port 10000:20000 # Jicofo 内网管理禁止公网访问 ufw allow from 127.0.0.1 to any port 8888 ufw enable # 验证 ufw status verbose注意ufw allow proto udp ...这条命令在 Ubuntu 18.04 的 ufw 0.36 版本中才被完全支持。如果你的ufw --version输出低于 0.36请先升级apt update apt install ufw -t bionic-updates。否则UDP 端口段将无法生效所有外网用户都会遇到“Media connection failed”。3. 核心组件安装绕过 apt 源陷阱直取官方二进制包Ubuntu 18.04 的apt源里没有jitsi-meet这个包。官方早已弃用apt分发方式转而采用独立.deb包 自研安装脚本。但直接下载jitsi-meet_2.0.7395-1_all.deb并dpkg -i会失败——因为它的Depends:字段要求nginx-full ( 1.18.0)而 Ubuntu 18.04 源里最高只有nginx-full 1.14.0。这就是为什么我们必须“绕过 apt 源陷阱”。3.1 Nginx编译安装 1.20.2启用 HTTP/2 和 BrotliJitsi Meet Web 界面重度依赖 HTTP/2 的多路复用以降低首屏加载延迟。Ubuntu 18.04 的nginx-full 1.14编译时未启用--with-http_v2_module且不支持 Brotli 压缩比 Gzip 高 15% 压缩率。我们选择编译安装nginx 1.20.2LTS 版本兼容 18.04 的 glibc 2.27# 安装编译依赖 apt update apt install build-essential libpcre3-dev libssl-dev zlib1g-dev libxslt1-dev libxml2-dev libgd-dev libgeoip-dev libgoogle-perftools-dev libatomic1 -y # 下载源码并解压 cd /tmp wget https://nginx.org/download/nginx-1.20.2.tar.gz tar zxvf nginx-1.20.2.tar.gz cd nginx-1.20.2 # 配置关键参数启用 HTTP/2、Brotli、动态模块 ./configure \ --prefix/usr/share/nginx \ --sbin-path/usr/sbin/nginx \ --modules-path/usr/lib/nginx/modules \ --conf-path/etc/nginx/nginx.conf \ --error-log-path/var/log/nginx/error.log \ --http-log-path/var/log/nginx/access.log \ --pid-path/run/nginx.pid \ --lock-path/var/lock/nginx.lock \ --http-client-body-temp-path/var/lib/nginx/body \ --http-fastcgi-temp-path/var/lib/nginx/fastcgi \ --http-proxy-temp-path/var/lib/nginx/proxy \ --http-scgi-temp-path/var/lib/nginx/scgi \ --http-uwsgi-temp-path/var/lib/nginx/uwsgi \ --with-http_ssl_module \ --with-http_v2_module \ # 必须启用 HTTP/2 --with-http_realip_module \ --with-http_addition_module \ --with-http_sub_module \ --with-http_dav_module \ --with-http_flv_module \ --with-http_mp4_module \ --with-http_gunzip_module \ --with-http_gzip_static_module \ --with-http_random_index_module \ --with-http_secure_link_module \ --with-http_stub_status_module \ --with-file-aio \ --with-threads \ --with-compat \ --with-http_brotli_module \ # 启用 Brotli需额外模块 --add-dynamic-module../ngx_brotli # 下载 Brotli 模块 # 下载并编译 Brotli 模块 cd /tmp git clone https://github.com/google/ngx_brotli.git cd ngx_brotli git submodule update --init # 返回 nginx 目录继续编译 cd /tmp/nginx-1.20.2 make -j$(nproc) make install # 验证 nginx -v # 应输出 nginx version: nginx/1.20.2 nginx -V 21 | grep -o http_v2 # 应输出 http_v2提示Brotli 模块编译可能报错fatal error: brotli/encode.h: No such file or directory。这是因为缺少libbrotli-dev。Ubuntu 18.04 源里没有这个包需手动编译安装 Brotli 库cd /tmp git clone https://github.com/google/brotli.git cd brotli ./bootstrap ./configure --prefix/usr make make install ldconfig3.2 Java 与 Prosody降级到 OpenJDK 8u292锁定 Prosody 0.10.1Jitsi Meet 的jicofo和jvbJitsi Video Bridge强制要求 Java 8非 11 或 17因为其底层ice4j库对 Java 9 的模块化系统有兼容问题。但 Ubuntu 18.04 源里的openjdk-8-jre是 8u191它存在一个致命 Bugjava.security.SecureRandom在/dev/urandom读取缓慢时会阻塞线程导致 JVB 启动超时。解决方案是升级到8u292最后一个支持 Java 8 的安全更新版本# 下载 OpenJDK 8u292Linux x64 tar.gz cd /tmp wget https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u292-b10/OpenJDK8U-jre_x64_linux_hotspot_8u292b10.tar.gz tar zxvf OpenJDK8U-jre_x64_linux_hotspot_8u292b10.tar.gz mv jdk8u292-b10-jre /usr/lib/jvm/java-8-openjdk-amd64 # 设置默认 Java update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-8-openjdk-amd64/bin/java 1 update-alternatives --set java /usr/lib/jvm/java-8-openjdk-amd64/bin/java # 验证 java -version # 应输出 openjdk version 1.8.0_292Prosody 同理。官方 apt 源的prosody 0.10.0有 XMPP 域名 SAN 校验缺陷。我们需手动安装0.10.1# 添加 Prosody 官方源支持 18.04 echo deb https://packages.prosody.im/debian bionic main /etc/apt/sources.list.d/prosody.list wget https://prosody.im/files/prosody-debian-packages.key -O- | apt-key add - apt update apt install prosody0.10.1-1~bionic1 -y # 锁定版本防止 apt upgrade 覆盖 apt-mark hold prosody3.3 Jitsi Meet 主包使用官方安装脚本但禁用自动证书现在可以安装 Jitsi Meet 了。但注意绝对不要运行curl https://download.jitsi.org/jitsi-key.gpg | sudo apt-key add -这类过时命令。Jitsi 官方已弃用apt-key改用signed-by方式。正确流程是# 添加 Jitsi 官方源GPG 密钥方式 mkdir -p /tmp/jitsi-key cd /tmp/jitsi-key wget https://download.jitsi.org/jitsi-key.gpg apt-key add jitsi-key.gpg echo deb https://download.jitsi.org stable/ /etc/apt/sources.list.d/jitsi-stable.list apt update # 安装核心包不启动服务 apt install jitsi-meet-web jitsi-meet-prosody jitsi-meet-turnserver -y # 关键禁用安装脚本的自动证书申请避免 Lets Encrypt 失败导致中断 # 编辑安装脚本注释掉 certbot 调用 sed -i s/certbot/#certbot/g /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh提示install-letsencrypt-cert.sh脚本在jitsi-meet-web-config包里。我们注释掉certbot调用并非放弃 HTTPS而是改用更可控的手动方式——因为 Lets Encrypt 的standalone模式需要 80/443 端口空闲而我们的 Nginx 已在监听webroot模式又要求 Nginx 配置配合。手动申请能让我们完整掌控证书链、私钥权限和 OCSP Stapling 配置。4. 配置深度调优从 Nginx 到 JVB 的 12 项关键参数修正安装只是开始90% 的“无法连接”“黑屏”“回声”问题都源于配置文件里的默认值。Ubuntu 18.04 的 Jitsi 配置文件分散在/etc/jitsi、/etc/nginx、/etc/prosody三个目录且彼此强耦合。下面逐项修正最易出错的 12 个参数。4.1 Nginx修复 WebRTC 的 CORS 与 MIME 类型Jitsi Meet 的前端 JS 会动态加载.wasmWebAssembly文件用于音频处理而 Ubuntu 18.04 的 Nginx 1.14 默认不识别application/wasmMIME 类型导致 Chrome 报Failed to load module script。同时Access-Control-Allow-Origin必须显式设置否则移动端 WebView 会拒绝加载资源。编辑/etc/nginx/sites-available/meet.example.com或/etc/nginx/conf.d/jitsi-meet.confserver { listen 80; server_name meet.example.com; # 强制 HTTPS 重定向关键 return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name meet.example.com; # SSL 证书稍后生成 ssl_certificate /etc/letsencrypt/live/meet.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/meet.example.com/privkey.pem; # 关键启用 OCSP Stapling提升 TLS 握手速度 ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/meet.example.com/chain.pem; # WebRTC 关键头 add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Credentials true always; add_header Access-Control-Allow-Methods GET, POST, OPTIONS, PUT, DELETE always; add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization always; # MIME 类型修正 types { application/wasm wasm; application/font-woff2 woff2; font/woff woff; font/ttf ttf; } # Jitsi Web 根目录 root /usr/share/jitsi-meet; index index.html; # 静态资源缓存 location ~ ^/(libs|css|fonts|html|images|sounds|static|robots.txt|favicon.ico) { expires 1y; add_header Cache-Control public, immutable; } # API 代理 location /http-bind { proxy_pass https://localhost:5281/http-bind; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $http_host; } # Jicofo 代理用于会议创建 location /colibri-ws { proxy_pass https://localhost:8888/colibri-ws; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; } }注意proxy_pass https://localhost:8888/colibri-ws中的https://是故意写的。Jicofo 默认监听http://127.0.0.1:8888但 Nginx 的 WebSocket 代理要求后端协议与proxy_pass协议一致。这里写https是为了触发 Nginx 的 WebSocket 升级机制实际流量仍走 HTTP。这是 Jitsi 官方文档里未明说的“魔法写法”。4.2 Prosody修复 XMPP 域名与 TLS 验证Prosody 的配置文件/etc/prosody/conf.d/meet.example.com.cfg.lua是整个认证链的起点。默认配置有两大硬伤VirtualHost meet.example.com未启用ssl模块导致jicofo无法通过 XMPP 连接auth.meet.example.comComponent conference.meet.example.com的authentication设为anonymous这会让所有用户无需密码即可创建会议极其危险。修正后的内容节选-- /etc/prosody/conf.d/meet.example.com.cfg.lua VirtualHost meet.example.com ssl { key /etc/letsencrypt/live/meet.example.com/privkey.pem; certificate /etc/letsencrypt/live/meet.example.com/fullchain.pem; } authentication internal_hashed modules_enabled { bosh; pubsub; ping; speakerstats; muc_lobby_rooms; muc_breakout_rooms; muc_rate_limit; } c2s_require_encryption true -- 认证虚拟主机关键 VirtualHost auth.meet.example.com ssl { key /etc/letsencrypt/live/meet.example.com/privkey.pem; certificate /etc/letsencrypt/live/meet.example.com/fullchain.pem; } authentication internal_hashed admins { focusauth.meet.example.com } -- 会议组件禁用匿名 Component conference.meet.example.com muc storage memory modules_enabled { muc_meeting_id; muc_domain_mapper; token_verification; } muc_room_locking false muc_room_default_public_jids false authentication internal_hashed -- 改为 internal_hashed非 anonymous提示admins { focusauth.meet.example.com }这行必须存在否则jicofo无法获得管理员权限会议创建会失败。focusauth.meet.example.com是 Jicofo 的默认用户名它会在安装时自动创建。4.3 JVB调整 ICE 协商与带宽策略JVBJitsi Video Bridge是媒体流的核心其配置/etc/jitsi/videobridge/config和/etc/jitsi/videobridge/sip-communicator.properties决定了能否穿越复杂 NAT。Ubuntu 18.04 的默认配置假设你有公网 IP但现实中多数服务器位于云厂商的内网如 AWS EC2 的私有子网必须显式配置org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS和org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS。编辑/etc/jitsi/videobridge/sip-communicator.properties# 基础设置 org.jitsi.videobridge.ENABLE_STATISTICStrue org.jitsi.videobridge.STATISTICS_TRANSPORTmuc org.jitsi.videobridge.xmpp.user.shard.DOMAINauth.meet.example.com org.jitsi.videobridge.xmpp.user.shard.USERNAMEjvb org.jitsi.videobridge.xmpp.user.shard.PASSWORDyour_strong_password_here # ICE 收集器关键根据你的网络环境填写 # 如果服务器有公网 IP如裸金属填 org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS203.0.113.45 org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS203.0.113.45 # 如果服务器在云内网如 AWS EC2填 # org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS172.31.16.100 # 内网 IP # org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS203.0.113.45 # 公网 IPEIP # STUN/TURN 服务器指向本机 Coturn org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSESmeet.example.com:3478 org.ice4j.ice.harvest.TURN_HARVESTER_ADDRESSESmeet.example.com:3478 org.ice4j.ice.harvest.TURN_HARVESTER_USERNAMEturnuser org.ice4j.ice.harvest.TURN_HARVESTER_PASSWORDyour_turn_password # 带宽限制防止单会议吃光带宽 org.jitsi.videobridge.TRUST_BWEfalse org.jitsi.videobridge.MAX_AUDIO_SENDERS50 org.jitsi.videobridge.MAX_VIDEO_SENDERS20注意org.ice4j.ice.harvest.NAT_HARVESTER_*这两行必须成对出现且LOCAL_ADDRESS必须是服务器能bind()的 IP即ip addr show输出的 IPPUBLIC_ADDRESS必须是外部用户能connect()的 IP。填错会导致 ICE 候选者全是0.0.0.0WebRTC 连接永远失败。5. 证书与服务启停一次成功的端到端验证流程现在所有组件和配置就绪进入最后的“点火”阶段。这一步不能靠systemctl start jitsi-meet一键启动而必须按依赖顺序逐个验证因为任何一个环节失败都会导致后续服务静默退出。5.1 手动申请 Lets Encrypt 证书使用 webroot 插件我们弃用standalone模式改用webroot因为它不抢端口且能与 Nginx 无缝集成# 创建 webroot 目录 mkdir -p /var/www/letsencrypt # 临时配置 Nginx将 .well-known 路径指向该目录 cat /etc/nginx/snippets/letsencrypt.conf EOF location ^~ /.well-known/acme-challenge/ { default_type text/plain; root /var/www/letsencrypt; } EOF # 在主 server 块中 include 该片段 sed -i /server {/a \ include /etc/nginx/snippets/letsencrypt.conf; /etc/nginx/sites-available/meet.example.com # 重载 Nginx nginx -t systemctl reload nginx # 安装 certbotUbuntu 18.04 源里有 apt install certbot python3-certbot-nginx -y # 申请证书注意域名必须已 DNS 解析到本机 IP certbot certonly \ --webroot \ --webroot-path/var/www/letsencrypt \ --email adminexample.com \ --agree-tos \ --no-eff-email \ -d meet.example.com \ -d auth.meet.example.com \ -d conference.meet.example.com \ -d jitsi.example.com # 验证证书 ls -l /etc/letsencrypt/live/meet.example.com/ # 应看到 fullchain.pem, privkey.pem, chain.pem5.2 服务启停顺序与状态验证表Jitsi Meet 的组件启动有严格依赖prosody→jicofo→jvb→nginx。任何一步失败都会导致整个链路中断。我们用一张表格记录每个服务的启动命令、预期状态、以及一条“黄金验证命令”服务启动命令预期状态黄金验证命令验证失败表现Prosodysystemctl restart prosodyactive (running)prosodyctl check输出All checks passedJicofosystemctl restart jicofoactive (running)curl -s http://localhost:8888/about返回{version:2.0.7395}JVBsystemctl restart jitsi-videobridge2active (running)ss -tuln | grep :10000应看到udp *:10000Nginxsystemctl restart nginxactive (running)curl -I https://meet.example.com返回HTTP/2 200执行顺序# 1. 启动 Prosody systemctl restart prosody prosodyctl check # 必须输出 All checks passed # 2. 启动 Jicofo等待 5 秒让 Prosody 完全就绪 sleep 5 systemctl restart jicofo curl -s http://localhost:8888/about | jq -r .version # 应输出版本号 # 3. 启动 JVB systemctl restart jitsi-videobridge2 ss -tuln | grep :10000 # 应看到 UDP 监听 # 4. 启动 Nginx systemctl restart nginx curl -I https://meet.example.com 21 | head -1 # 应输出 HTTP/2 200提示jitsi-videobridge2服务在 Ubuntu 18.04 上默认名为jitsi-videobridge但新包已改为jitsi-videobridge2。若systemctl list-units \| grep jitsi输出的是jitsi-videobridge.service请用该名称。不确定时查systemctl list-unit-files \| grep jitsi。5.3 端到端可用性验证从浏览器到手机的四步真机测试最后一步也是最重要的一步用真实设备验证。不要相信curl要相信人眼和人耳。第一步Chrome 桌面端基础功能打开https://meet.example.com→ 点击 “Start a meeting” → 输入会议名如test→ 点击 “Go” → 观察页面是否加载出视频预览本地摄像头右上角是否显示 “You are connected to the server”点击 “Share screen”是否弹出系统级选择框第二步Firefox 桌面端兼容性同一台机器用 Firefox 打开相同 URL → 加入同名会议 → 观察是否能看到 Chrome 用户的视频和屏幕共享Firefox 用户共享屏幕时Chrome 用户是否能看到第三步iOS Safari移动端iPhone Safari 打开https://meet.example.com→ 加入会议 → 观察是否自动请求麦克风/摄像头权限视频是否居中显示非拉伸变形点击右下角 “⋯” → “Settings” → “Audio” → 是否能切换扬声器/听筒第四步Android ChromeNAT 穿透安卓手机连 4G 网络非同一 WiFi→ Chrome 打开 URL → 加入会议 → 观察