下面这段可以直接补到博客里,建议放在前面那篇的「为什么远程开发机上的视频能在本地浏览器打开?」后面,作为详细版解释。
VS Code Remote SSH、端口转发、本地浏览器访问远程视频的完整流程
在 Remote SSH 场景下,一个很容易让人困惑的问题是:
视频文件在远程开发机上,
video_player.html也在远程开发机上,为什么我点击 VS Code 里的链接后,本地浏览器却能打开并播放远程视频?
本质原因是:
text
VS Code Remote SSH 帮我们建立了一条从本地电脑到远程开发机的端口转发隧道。
也就是说,本地浏览器访问的虽然是:
text
http://127.0.0.1:5500/video_player.html
但这个 127.0.0.1:5500 背后并不一定是本地真实文件,而是 VS Code 通过 SSH 隧道转发到了远程开发机上的服务。
1. 首先,视频文件在哪里?
视频文件实际在远程开发机磁盘上,例如:
text
远程开发机:
/horizon-bucket/perception-dataprocess/static/test/xxx/videos_h264_preview/
播放器页面也在远程开发机上:
text
远程开发机:
video_player.html
video_manifest_h264_preview.json
本地电脑上并没有这些视频文件。
2. 远程开发机上启动了一个 HTTP 服务
当我们用 VS Code 的 Live Server,或者手动运行:
bash
python -m http.server 5500
其实是在远程开发机上启动了一个 HTTP 服务。
这个服务可以理解为:
text
远程开发机上有一个小型网站服务器
它负责把当前目录下的文件通过 HTTP 暴露出来。
比如远程开发机上实际有:
text
video_player.html
video_manifest_h264_preview.json
videos_h264_preview/0001.xxx.mp4
远程 HTTP 服务就可以响应:
text
/video_player.html
/video_manifest_h264_preview.json
/videos_h264_preview/0001.xxx.mp4
如果你在远程开发机本机访问,它可能是:
text
http://127.0.0.1:5500/video_player.html
注意,这里的 127.0.0.1 是远程开发机自己的 localhost。
3. 本地浏览器为什么能访问远程 127.0.0.1?
正常情况下,本地浏览器访问:
text
http://127.0.0.1:5500
访问的是:
text
本地电脑自己的 5500 端口
它不可能天然访问到远程开发机的 127.0.0.1:5500。
因为:
text
本地 127.0.0.1 = 本地电脑自己
远程 127.0.0.1 = 远程开发机自己
这两个 127.0.0.1 不是同一个机器。
所以如果没有额外机制,本地浏览器是不可能直接访问远程开发机 localhost 服务的。
这里起作用的就是:
text
VS Code Remote SSH 端口转发
4. VS Code 做了什么?
当 VS Code 发现远程开发机上有服务监听了某个端口,比如:
text
远程开发机 127.0.0.1:5500
它会通过 Remote SSH 建立一条隧道,把远程端口映射到本地端口。
可以理解成:
text
本地电脑 127.0.0.1:5500
↓
VS Code / SSH 隧道
↓
远程开发机 127.0.0.1:5500
所以本地浏览器访问:
text
http://127.0.0.1:5500/video_player.html
实际上会变成:
text
本地浏览器请求本地 5500
↓
请求进入 VS Code 创建的本地端口监听
↓
VS Code 通过 SSH 隧道把请求转发到远程开发机 5500
↓
远程 Live Server 读取远程磁盘文件
↓
文件内容通过 SSH 隧道返回本地
↓
本地浏览器显示页面或播放视频
5. 完整链路图
可以画成这样:
text
┌──────────────────────┐
│ 本地浏览器 │
│ Chrome / Edge / etc. │
└──────────┬───────────┘
│
│ 访问 http://127.0.0.1:5500/video_player.html
↓
┌──────────────────────┐
│ 本地 127.0.0.1:5500 │
│ VS Code 创建的转发入口 │
└──────────┬───────────┘
│
│ SSH Tunnel
↓
┌────────────────────────────┐
│ 远程开发机 127.0.0.1:5500 │
│ Live Server / HTTP Server │
└──────────┬─────────────────┘
│
│ 读取远程磁盘文件
↓
┌────────────────────────────┐
│ 远程开发机文件系统 │
│ video_player.html │
│ video_manifest_h264...json │
│ videos_h264_preview/*.mp4 │
└────────────────────────────┘
返回数据时,方向反过来:
text
远程磁盘文件
↓
远程 HTTP 服务
↓
SSH 隧道
↓
本地 127.0.0.1:5500
↓
本地浏览器
6. VS Code 知道我用哪个浏览器吗?
不知道。
VS Code 不需要知道你用 Chrome、Edge、Firefox 还是 Safari。
VS Code 做的只是:
text
在本地开一个端口,比如 127.0.0.1:5500
并把这个端口转发到远程开发机
只要这个本地端口存在,本地任何浏览器访问它都可以。
所以你复制这个链接:
text
http://127.0.0.1:5500/video_player.html
然后粘贴到另一个浏览器里,也能打开。
因为这些浏览器访问的是同一个本地端口:
text
Chrome -> 127.0.0.1:5500
Edge -> 127.0.0.1:5500
Firefox -> 127.0.0.1:5500
而这个端口背后已经被 VS Code 接到了远程开发机。
所以:
text
VS Code 不关心是谁访问这个端口。
只要请求打到本地 127.0.0.1:5500,它就会通过 SSH 隧道转到远程。
7. 为什么复制链接到另一个浏览器也能打开?
因为这个链接本质上是本地地址:
text
127.0.0.1
127.0.0.1 表示:
text
当前这台电脑自己
你在本地 Chrome 里打开:
text
Chrome -> 本地电脑 127.0.0.1:5500
你在本地 Edge 里打开:
text
Edge -> 本地电脑 127.0.0.1:5500
你在本地 Firefox 里打开:
text
Firefox -> 本地电脑 127.0.0.1:5500
它们都是访问本地电脑的同一个端口。
只是这个端口背后由 VS Code Remote SSH 负责转发到了远程开发机。
所以不是"浏览器知道远程开发机在哪里",而是:
text
浏览器只知道访问本地 127.0.0.1:5500。
VS Code 负责把这个请求转发到远程。
8. 如果关闭 VS Code,还能访问吗?
如果你依赖的是 VS Code Remote SSH 自动端口转发,那么关闭 VS Code 后,大概率不能继续访问。
因为链路会断掉:
text
VS Code 关闭
↓
SSH 隧道断开
↓
本地 127.0.0.1:5500 不再转发到远程
↓
浏览器刷新页面失败
浏览器里已经缓冲的一点视频数据可能还能播放几秒,但只要刷新页面、切换视频、拖动到未缓存位置,就会失败。
9. 不用 VS Code 能不能实现同样效果?
可以。
VS Code Remote SSH 做的事情,本质上就是 SSH 端口转发。我们可以手动做。
假设远程开发机是:
text
10.34.8.75
用户名是:
text
qingsong.sun
远程服务监听:
text
远程 127.0.0.1:5500
那么可以在本地电脑终端执行:
bash
ssh -L 5500:127.0.0.1:5500 qingsong.sun@10.34.8.75
含义是:
text
把本地电脑的 5500 端口
转发到远程开发机的 127.0.0.1:5500
然后在远程开发机上启动 HTTP 服务:
bash
python -m http.server 5500
本地浏览器访问:
text
http://127.0.0.1:5500/video_player.html
这时即使不用 VS Code,也可以访问远程视频。
链路变成:
text
本地浏览器
↓
本地 127.0.0.1:5500
↓
手动 ssh -L 隧道
↓
远程 127.0.0.1:5500
↓
远程 HTTP 服务
↓
远程磁盘视频文件
所以 VS Code 不是唯一方式,它只是帮我们自动做了这套端口转发。
10. 视频数据是一次性下载到本地吗?
不是。
浏览器播放视频时,一般会使用 HTTP Range 请求。
也就是说,浏览器不会一开始就把整个视频文件下载完,而是按需请求片段。
例如:
text
先请求 0MB - 5MB
再请求 5MB - 10MB
拖动进度条后,请求 200MB - 205MB
这些请求都会经过同一条链路:
text
本地浏览器
↓
本地端口 127.0.0.1:5500
↓
VS Code / SSH 隧道
↓
远程 HTTP 服务
↓
远程视频文件
远程服务读取对应的视频片段,再通过 SSH 隧道传回本地浏览器。
所以实际播放时更像是:
text
远程视频通过 SSH 隧道流式传输到本地浏览器播放
而不是完整复制一份到本地。
11. 端口转发解决的是"访问问题",不解决"解码问题"
这里还有一个关键点:
text
能访问文件 ≠ 能播放视频
VS Code Remote SSH / Live Server / HTTP 服务 / 端口转发只负责把视频文件的字节流传到本地浏览器。
但浏览器拿到这些字节后,能不能播放,取决于本地浏览器是否支持视频编码。
比如原始视频是:
text
MP4 + mpeg4/mp4v
端口转发可以把它传到本地浏览器,但浏览器不一定能解码,所以会出现:
text
0:00
一直转圈
无法播放
转码后视频是:
text
MP4 + H.264/avc1 + yuv420p
浏览器支持这个编码,所以才能正常播放。
所以这里有两个层面:
text
1. 网络/访问层面:
VS Code Remote SSH 端口转发负责让本地浏览器访问远程文件。
2. 解码/播放层面:
浏览器的视频解码器负责播放 H.264/H.265/mpeg4 等编码。
端口转发只能解决第一个问题,不能解决第二个问题。
12. 整体总结
可以把整个过程总结成一句话:
text
视频文件在远程开发机上,HTTP 服务也在远程开发机上;
VS Code Remote SSH 在本地开了一个端口,并通过 SSH 隧道转发到远程服务;
本地浏览器访问本地 127.0.0.1:5500,请求被 VS Code 转发到远程;
远程服务读取远程视频文件,再通过 SSH 隧道把数据返回给本地浏览器;
最后由本地浏览器负责解码和播放视频。
更短一点就是:
text
远程存文件,远程跑服务;
VS Code 做隧道;
本地浏览器访问本地端口;
请求被转到远程;
视频数据流式传回本地;
本地浏览器解码播放。
这也是为什么:
text
复制 http://127.0.0.1:5500/video_player.html 到另一个本地浏览器也能打开。
因为只要 VS Code 的端口转发还在,本地任何浏览器访问这个本地端口,都会走同一条 SSH 隧道到远程开发机。