Skip to content

Repository files navigation

FileServer —— 局域网文件服务器(单 exe,双击即用)

一个轻量的 Windows 局域网文件服务器:双击 FileServer.exe,控制台自动显示局域网地址(含二维码),同一 WiFi 下的手机/电脑访问该地址即可只读浏览、预览、下载 exe 所在文件夹的全部文件。

核心卖点:视频在线播放 —— 点开即播、可拖进度条;开启冷门格式支持后,MKV/HEVC/AVI/RMVB 等浏览器原生播不了的格式也能流畅观看(GPU 加速转码/无损重封装)。

特性

  • 🚀 单文件:约 8MB 的单 exe,零安装、零依赖、双击即用;发布包可捆绑 ffmpeg 组件(可选)
  • 🌐 自动出地址:启动自动检测局域网 IP 并打印访问地址(--browser 可额外自动打开浏览器)
  • 📱 终端二维码:启动即在控制台渲染每个地址的二维码,手机扫屏直达(--no-qr 关闭)
  • 📺 视频在线播放(核心)
    • 直链秒开:H.264 MP4/WebM 等浏览器原生格式直接流式播放(Range + GPU 硬解)
    • 冷门格式(可选,--ffmpeg 或前端开关开启):MKV/RMVB/AVI/WMV/HEVC 实时转 H.264(GPU 优先 NVENC → AMF → QSV → CPU),边转边播
    • 怪封装 MP4 加速:开启冷门格式支持后自动走 HLS copy 重封装流(-c copy 零画质损失),起播从直链的 30s+ 降到约 1 秒
    • 规整化(始终可用):怪封装视频卡片显示标记,可手动一键规整(mdat 合并 + moov 前置),永久秒开;规整前自动备份原文件,可恢复/删除
    • seek 收敛:转码进行中超前拖进度条不会卡死,自动落到当前已生成位置
    • 真实进度:转码期间进度条按服务端下发的真实总时长显示(不随已生成分片回跳),拖动定位准确
    • 进程安全:ffmpeg 子进程 Job Object 防孤儿、abandon 即终止(taskkill 兜底)、空闲 10 分钟自动回收
  • 🖼️ 视频缩略图
    • 常规 MP4/WebM:纯浏览器抽帧(零服务端成本)——服务端只提供截短抽帧源(≤16MB 合法 MP4),浏览器 3 路并发抽帧、绝不整段下载
    • 冷门格式(冷门格式支持开启):服务端 ffmpeg 抽帧生成 JPEG(低优先级、2 路并发、磁盘缓存)
    • 冷门格式(未开启):保持文件图标(不下载、不占用资源)
  • 🎞️ 自绘播放器:进度拖动、倍速、音量、全屏、快捷键(空格/方向键/M/F)
  • 🖼️ 相册级灯箱:缩放/旋转/键盘/触屏滑动切换
  • 📄 在线预览:视频 / 音频 / PDF / 文本 / 代码
  • 📦 目录打包下载:任意文件夹一键 zip(流式打包)
  • 🔍 文件搜索:递归搜索当前目录(带深度/数量上限)
  • 🎨 现代界面:暗色为主(可切亮色)、网格/列表视图、手机响应式(触屏布局单独优化)
  • 🧹 缓存不污染系统目录:所有缓存(缩略图/HLS/重封装/备份)都在服务目录内的隐藏文件夹 .FileServer\,删除即恢复干净
  • 🛡️ 只读 + 路径安全:无任何写接口,防目录穿越、防符号链接逃逸;可选口令保护;退出时终止全部转码子进程(关窗不留孤儿 ffmpeg)

快速开始

  1. 解压后将 FileServer.exe 放到想共享的文件夹(也可以放任意位置后用 --dir 指定)
  2. 双击运行
  3. 首次运行如弹出 Windows 防火墙提示,请勾选"专用网络"并允许(局域网访问必需)
  4. 手机/其他电脑连接同一 WiFi,在浏览器打开控制台显示的 http://192.168.x.x:8080 地址

停止服务:关闭控制台窗口,或按 Ctrl+C(优雅退出,自动终止转码进程)。

命令行参数

参数 说明
--port 9000 指定端口(默认 8080,被占用自动递增)
--dir D:\共享 指定服务目录(默认 exe 所在目录)
--browser 启动后自动打开默认浏览器(默认关闭,不打扰)
--hidden 显示隐藏文件(点开头)。默认关闭:隐藏文件在列表、搜索、直链下载、缩略图、zip 打包中均不可见/不可访问(内部缓存目录 .FileServer\ 为保留名,无论本项开关与否始终不可见/不可访问)
--auth user:pass 启用简单访问口令(Basic Auth)。口令以明文走 HTTP,仅限可信局域网使用
--ffmpeg 开启冷门格式(MKV/RMVB/AVI/WMV/HEVC 等)在线转码播放 + 服务端缩略图,以及怪封装 MP4 的 HLS copy 加速播放(需 exe 旁 ffmpeg\ 或 PATH 中有 ffmpeg;有转码的 CPU/GPU 代价,默认关闭)。也可在网页工具栏点按钮动态开关,无需重启。规整化功能不受此开关影响、始终可用
--no-qr 不在终端显示地址二维码
-v 显示访问日志

冷门格式支持可在网页上动态开关:工具栏的 🎬 按钮,开启/关闭即时生效(开关选择会记住,下次打开页面保持)。关闭时冷门格式保持图标/仅可下载,开启时即时可播。

视频在线播放(核心功能)

点开视频后前端询问 /api/video-info,服务端毫秒级决策

冷门格式支持关闭(默认,纯文件服务):

  • 浏览器原生可播的格式(H.264 MP4、WebM 等)→ 直链播放(浏览器 Range 流式 + GPU 硬解)
  • 冷门格式(MKV/RMVB/AVI/WMV/HEVC 等)→ 不可在线播放(可下载);怪封装 MP4 起播慢可手动「规整化」解决

冷门格式支持开启后:

  1. 直链播放:浏览器原生可播的常规格式(H.264 MP4、WebM 等)—— 直接流式播放,最快
  2. 无损流化(HLS copy):怪封装 MP4 —— ffmpeg -c copy(零转码、零画质损失)实时把碎片化 mdat 重封装成规整分片流,起播从直链的 30s+ 降到 约 1 秒
  3. 实时转码(HLS transcode):MKV/RMVB/AVI/WMV/HEVC 等冷门格式 —— 服务端实时转 H.264(GPU 优先,CPU 兜底),边转边播

规整化(把怪封装文件永久整理为 mdat 单块)始终是用户手动操作,不受冷门格式开关影响。

共性机制:

  • 编码器实测优选:启动时依次实测 h264_nvenc / h264_amf / h264_qsv,全部不可用回退 libx264 CPU;无显卡/驱动缺失也能播。
  • 硬件解码按需:仅 H.264/HEVC 使用 GPU 硬解(-hwaccel cuda);RMVB 等冷门编码 CUDA 无法硬解,自动回退 CPU 解码 + GPU 编码(强行硬解会卡死)。
  • 转码会话管理:分片 3 秒一片;copy 4 路并发、转码 2 路并发(互不阻塞);首片等待上限 60s;分片请求阻塞等待上限 28s(与前端 hls.js 超时对齐);停滞 60s / 空闲 10 分钟自动终止;离开播放页立即通知服务端终止(abandon,并 taskkill 强杀兜底),不浪费磁盘与 GPU。
  • 进程安全:ffmpeg 子进程挂 Job Object,服务退出/崩溃即连带终止;GPU 卡死时 abandon 会 taskkill /F /T 强杀,绝不留孤儿进程。
  • 播放列表(EVENT → VOD):转码进行中返回 EVENT 播放列表(不附加 ENDLIST)——hls.js 持续拉取新分片,不会"播完已生成部分就结束";转码完成后才附加 ENDLIST 正常结束。进度条按服务端下发的真实总时长显示,不会随已生成分片回跳。
  • seek 收敛:拖到尚未生成的位置时,前端自动收敛到当前已生成范围并提示,绝不卡死;转码赶上来后可继续往后拖。
  • 缓存复用:完整转码结果缓存 3 天,同一视频再次点开直接读缓存秒开。

怪封装识别与规整化

  • 怪封装判定:mdat 碎片化严重(大量小 mdat 块交错)或 moov 过大,Chrome 解析慢,起播显著变慢。服务端按「mdat 块数 > 4 且 ≥256MB」判定(带布局缓存,毫秒级)。
  • 标识:怪封装视频卡片显示红色"怪封装"badge + "规整化"按钮(列表视图同样显示)。
  • 规整化:用 ffmpeg -c copy +faststart(零转码、零画质损失)把碎片化 mdat 合并、moov 前置,永久秒开。
  • 备份:规整前自动把原文件备份到 .FileServer\backup\(同一路径结构);规整完成前任何步骤失败都能回滚,绝不留半成品。
  • 备份管理:规整化面板可查看所有备份,一键恢复(覆盖回原文件,文件重新成为怪封装)或彻底删除
  • 进度:规整全程显示真实进度(扫描→写入→校验→备份→覆盖 各阶段),完成后自动出现在备份列表。

视频缩略图

常规 MP4/WebM:纯浏览器抽帧(零服务端成本,始终如此)

浏览器用隐藏 <video>preload=metadata)加载 /api/thumb-src 返回的截短抽帧源,seek 后 canvas 截帧。关键点:

  • 为什么不能直接给原文件:Chromium 对 video 源发出开区间 Range(bytes=0-),整段回源会把 1.4GB 视频全传一遍——磁盘/网络/内存全被打爆。
  • 抽帧源(/api/thumb-src:服务端只返回一个"截短的合法 MP4"——头部样本区 + moov(≤16MB):
    • moov 在头部的怪封装片:直接截取头部 16MB(moov + 开头 1~2s 样本都在其中);
    • moov 在尾部的正常片:头部 16MB 样本区 + 尾部 moov 拼接(样本偏移不变,仍是合法 MP4);
    • 浏览器把它当完整文件解析:元数据秒读、seek 1s 命中样本,抽帧毫秒级完成
  • 3 路并发懒加载:卡片进入视口才抽(IntersectionObserver),20 秒超时;解码不支持(HEVC 等)/损坏文件保持图标,绝不硬拉。
  • 播放绝对优先:点开视频的瞬间前端中止所有在途抽帧(释放连接与磁盘 IO)并暂停新任务;返回列表自动恢复。

冷门格式(MKV/RMVB/AVI/WMV/HEVC 等):

  • 冷门格式支持开启:服务端用 ffmpeg 抽一帧 JPEG(跳过片头黑场,取 1s 处),缓存到 .FileServer\thumb\(7 天清理),2 路并发限制 + 低优先级运行,不抢播放。
  • 冷门格式支持关闭:保持文件图标(不下载、不占用任何服务端资源)。

实测(146 个视频的大目录,有头浏览器):首张缩略图约 1 秒、2 秒 15 张、首屏 12 张几秒铺满;抽帧正忙时点开视频起播 1 秒出头、播放全程零抽帧任务。

缓存目录

所有缓存都在服务目录内的隐藏文件夹:

服务目录\.FileServer\
├── thumb\      图片缩略图 + 冷门格式服务端抽帧缩略图(jpg,7 天清理)
├── hls\        视频转码/重封装会话(index.m3u8 + seg_*.m4s,3 天清理)
├── faststart\  小文件 moov 前置重封装缓存(7 天清理)
└── backup\     规整化前的原文件备份(可恢复/删除)
  • 不写入系统目录(服务目录不可写时才回退系统临时目录);
  • 删除 .FileServer 文件夹即可清空全部缓存,不影响任何功能;
  • 对客户端完全不可见:无论是否开启 --hidden.FileServer 都不会出现在列表、搜索、zip 打包中,也无法通过直链/缩略图/抽帧源等任何接口访问(含大小写变体);
  • 已在 .gitignore 中排除,不会污染仓库。

从源码构建

需要 Windows + 网络(首次自动下载 Go 工具链到 .tools\,免安装):

build.bat

产物在 dist\FileServer.exe。手动构建:

.tools\go\bin\go build -trimpath -ldflags "-s -w" -o dist\FileServer.exe ./cmd/fileserver

发布包(捆绑 ffmpeg):release.ps1(输出 release\ 目录)。

测试

# 后端单元/集成测试(无需 ffmpeg)
.tools\go\bin\go test ./...

# 前端 Playwright 测试(需要 Python + playwright)
# 先启动服务:dist\FileServer.exe --dir .\testdata --port 8099 --no-qr
python scripts\smoke_test.py        # 冒烟
python scripts\regression_test.py   # 回归(面包屑/缩略图/播放器释放)
python scripts\mobile_test.py       # 移动端 + 灯箱 + zip
python scripts\nav_test.py          # 导航/历史
python scripts\special_e2e_test.py  # 特殊文件端到端
python scripts\hls_e2e_test.py      # HLS 端到端(生成 HEVC/MKV 实测转码播放)
python scripts\frontthumb_test.py   # 前端抽帧模式(无 ffmpeg 时)
python scripts\mobile_ui_check.py   # 移动端 UI 全面检查(多视口/溢出/控制条)

项目结构

├── cmd/fileserver/      入口:参数解析、优雅退出、控制台输出、二维码
├── internal/
│   ├── server/          核心服务
│   │   ├── server.go    Server、路由、认证、文件直链、播放决策、冷门格式开关
│   │   ├── path.go      路径安全(防穿越/符号链接逃逸)
│   │   ├── list.go      目录列表、排序、分页、怪封装标记
│   │   ├── thumb.go     图片缩略图缓存、冷门格式服务端抽帧
│   │   ├── ffmpeg.go    ffmpeg 集成:查找、GPU 探测、抽帧、faststart、媒体探测
│   │   ├── hls.go       HLS 会话管理(转码/重封装/分片服务/EVENT→VOD)
│   │   ├── normalize.go 怪封装规整化(队列/备份/恢复/删除/进度)
│   │   ├── zip.go       目录打包下载
│   │   ├── search.go    递归搜索
│   │   ├── lanip.go     局域网 IP 检测
│   │   └── web/         前端资源(嵌入 exe:index.html/style.css/app.js/hls.min.js)
│   ├── qrcode/          二维码生成(终端渲染,零依赖)
│   └── platform/        平台适配(UTF-8 控制台、打开浏览器、子进程回收)
├── scripts/             Playwright 测试脚本
├── testdata/            测试数据(gitignore 中不含 mp4 样例,测试自行生成)
├── doc/                 项目文档
├── build.bat            一键构建
├── fetch-tools.ps1      下载 Go 工具链
├── release.ps1          发布包打包
└── README.md

常见问题

Q: 手机打不开? 确认手机与电脑在同一网络;确认防火墙已允许(首次运行弹窗勾选"专用网络");部分路由器开启"AP 隔离"会阻止设备互访,需在路由器设置中关闭。

Q: 端口被占用? 程序会自动尝试 8080 之后的端口,控制台会显示实际地址。

Q: 什么视频能直接播,什么要走转码? 浏览器原生能播的(H.264 MP4、WebM、MP3 等)直接流式播放;MKV/RMVB/AVI/WMV/HEVC 等需要开启冷门格式支持(--ffmpeg 或网页工具栏 🎬 按钮)在线转码播放,否则仅可下载。

Q: 冷门格式支持开着但点开还是提示不可播? 确认服务端能找到 ffmpeg(exe 旁 ffmpeg\ 目录或 PATH 中)。无 ffmpeg 时该开关无效(按钮会显示不可用)。

Q: 杀毒软件报警? Go 编译的静态程序误报率极低;若个别杀软误报,添加信任即可。

Q: 想换个端口/目录? 创建快捷方式,在目标后加参数,如:"D:\FileServer.exe" --port 9000 --dir "D:\共享"

Q: 大视频第一次点开还要等几秒? 分为两种情况:

  • 常规 MP4:机械硬盘上 moov 区域碎片化的文件冷读一次需要几秒到十几秒(物理寻道)。服务已尽力跳过探测、分片缓存 3 天——第一次完整播完后,之后点开都是秒开。固态硬盘上无此问题。
  • 怪封装 MP4(起播十几秒~三十秒):点卡片上的「规整化」按钮整理一次,之后永久秒开(零画质损失);或开启冷门格式支持后自动走 HLS copy 流(起播约 1 秒)。

Q: hevc/mkv 视频没有缩略图? 关闭冷门格式支持时,浏览器无法解码这些容器,保持图标是正常的。开启冷门格式支持后,服务端 ffmpeg 会为它们生成缩略图。

About

适用于Windows平台的轻量级文件服务器

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages