在开发 HLS(HTTP Live Streaming)应用时,很多人会遇到这样的问题:
"TS 文件在本地播放正常,推到服务器后却只能下载几 KB,播放器报错或无法播放。"
本文深入分析这种问题的根源:Git 提交/拉取过程中的二进制文件处理错误,并给出完整解决方案。
一、问题现象
典型表现:
-
本地 TS 文件大小正常(几 MB/几十 MB)
-
上传服务器后通过 Nuxt 或 HTTP 静态服务访问:
- TS 文件只有几 KB
- 浏览器或播放器无法播放
- HLS 播放器卡在加载 TS 段
-
m3u8 文件本身没问题
-
直接通过
scp拷贝 TS 文件到服务器即可播放正常
二、问题原因分析
1. TS 文件本质
- TS(MPEG Transport Stream)是二进制视频切片
- 绝不能被文本处理
- 文件内容每个字节都必须原样保留
2. Git 默认行为
Git 默认会对文件做自动文本识别与换行处理:
arduino
* text=auto
后果:
-
如果 Git 认为 TS 是文本文件:
- CRLF → LF 或 LF → CRLF 转换
- diff/merge 会损坏二进制结构
-
HLS TS packet 被破坏 → 播放器无法解析
-
文件大小明显变小 → 只拉到几 KB
3. 常见踩坑场景
| 场景 | 典型表现 |
|---|---|
.gitattributes 配置 *.ts text eol=lf |
TS 文件被 Git 当文本处理,推送服务器后损坏 |
直接 git add TS 文件 |
Git 自动识别二进制/文本可能出错,跨平台 CRLF 转换可能破坏 TS |
| 服务器拉取 Git | 损坏 TS 文件的结果在服务器才出现 |
三、验证方法
1. 文件类型验证
file output0.ts
- 正常:
MPEG transport stream data - 损坏:显示
ASCII text或大小明显变小
2. 文件哈希对比
bash
# 本地
md5sum output0.ts
# 服务器
md5sum output0.ts
- 如果不一致 → Git 损坏文件
四、正确解决方案
1. 修正 .gitattributes
核心原则:
TS 视频切片必须二进制处理,绝对不能被文本模式干预
ini
# 默认文本文件
* text=auto eol=lf
# 代码文件
*.js text eol=lf
*.ts # 如果是 TypeScript 源码,需要 text eol=lf
*.m3u8 text eol=lf
# HLS 视频切片
*.ts binary
注意:HLS TS 文件和 TypeScript 文件同扩展名
.ts时必须区分路径或改名(例如segment0.ts),否则 Git 无法区分
2. 清理 Git 缓存并重新提交
sql
git rm --cached -r .
git add .
git commit -m "Fix binary TS files"
git push
确保服务器重新拉取时获取的是原始二进制 TS
3. 生产环境最佳实践
-
TS 文件不要直接进 Git
- 太大且二进制容易损坏
- 使用 LFS 或 对象存储/CDN 保存
-
m3u8 文件可以进 Git
-
TS 文件在服务器或 CDN 上提供静态访问
- MIME 类型:
video/mp2t - 支持 Range 请求
- 禁用浏览器缓存(避免 304 干扰)
- MIME 类型:
五、实战经验
-
Git 损坏 TS 文件是最容易忽略的问题
很多人以为 Nuxt / HLS 播放器有问题,其实是二进制文件在 Git 处理链被破坏
-
确认本地和服务器文件哈希,可以快速判断问题来源
-
使用测试流验证播放器:
- Apple 官方 HLS:devstreaming-cdn.apple.com/videos/stre...
- Mux 测试流:test-streams.mux.dev/test_001/st...
-
强烈建议 TS 文件走 CDN 或 LFS,避免 Git 损坏
六、总结
- TS 文件是二进制切片,绝不能被 Git 当文本处理
.gitattributes配置不当是导致 HLS 播放失败的常见根源- 通过设置
*.ts binary并清理缓存,可彻底解决问题 - 生产环境最佳做法:TS 文件不入 Git → CDN / LFS → Nuxt / HLS 播放器
本文部分内容借助 AI 辅助生成,并由作者整理审核。