Skip to content

Commit 8754e64

Browse files
author
Taois
committed
fix: 修复 ijkplayer 无法播放以及 ExoPlayer 拖拽进度重置的问题
1 parent 983991b commit 8754e64

File tree

3 files changed

+21
-7
lines changed

3 files changed

+21
-7
lines changed

mediaProxy/custom_spider.jar

-1.32 KB
Binary file not shown.

mediaProxy/custom_spider.jar.md5

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
dc6385947115895682a99865db0ca0db
1+
4ac3e305d164a75e5af3e634268afc1f

mediaProxy/proxy.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ func handleGetMethod(w http.ResponseWriter, req *http.Request) {
478478
if matchGroup != nil {
479479
statusCode = 206
480480
rangeStart, _ = strconv.ParseInt(matchGroup[1], 10, 64)
481-
if len(matchGroup) > 2 {
481+
if len(matchGroup) > 2 && matchGroup[2] != "" {
482482
rangeEnd, _ = strconv.ParseInt(matchGroup[2], 10, 64)
483483
}
484484
} else {
@@ -582,7 +582,11 @@ func handleGetMethod(w http.ResponseWriter, req *http.Request) {
582582
} else if strings.HasSuffix(fileName, ".mp4") || strings.HasSuffix(fileName, ".m4s") || strings.Contains(urlLower, "fext=mp4") || strings.Contains(urlLower, ".mp4") {
583583
contentType = "video/mp4"
584584
} else {
585-
contentType = "video/mp4" // 默认降级为 mp4,解决播放器无法识别 octet-stream 的问题
585+
// 保留原始的 application/octet-stream 或者默认为 video/mp4
586+
// 对于 ijkplayer,最好让其自己嗅探,所以如果是 octet-stream,就保留
587+
if contentType == "" {
588+
contentType = "video/mp4"
589+
}
586590
}
587591
responseHeaders.Set("Content-Type", contentType)
588592
}
@@ -748,24 +752,34 @@ func handleGetMethod(w http.ResponseWriter, req *http.Request) {
748752

749753
logrus.Debugf("Proxy data transfer: thread=%d, splitSize=%d", numTasks, splitSize)
750754

751-
// 设置正确的Range响应头
755+
// 对于 ExoPlayer,我们必须确保返回 Content-Range 时,格式完全正确。
756+
// 之前我们使用 fmt.Sprintf("bytes %d-%d/%d", rangeStart, rangeEnd, contentSize)
757+
// 如果 rangeStart == 0 且 rangeEnd == contentSize - 1,有些播放器(特别是ExoPlayer拖拽时)
758+
// 会因为缓存和重新请求的 Range 发生冲突。
759+
// 同时,必须确保 Accept-Ranges 存在
752760
if statusCode == 206 {
761+
// ExoPlayer 非常依赖于精确的 Range 回复。如果请求的是 bytes=0-,它可能会检查长度是否一致。
762+
// 有些情况下返回 0-X/Y (X = Y - 1) 会被 ExoPlayer 认为不匹配它的期望,导致重置播放或抛出异常。
763+
// 因此我们必须确保回复格式完全合规,如果请求没有给结束位置,我们返回到文件末尾。
753764
responseHeaders.Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", rangeStart, rangeEnd, contentSize))
754765
} else {
755766
responseHeaders.Del("Content-Range")
756767
}
757768
responseHeaders.Set("Content-Length", strconv.FormatInt(rangeEnd-rangeStart+1, 10))
758769
responseHeaders.Set("Accept-Ranges", "bytes")
759770

760-
// 先设置响应头,再开始数据传输
761-
responseHeaders.Del("Transfer-Encoding") // 避免播放器因为存在 Chunked 而拒绝解析 Content-Length
771+
// 必须清理可能干扰播放器 Range 判断的头
772+
responseHeaders.Del("Transfer-Encoding")
773+
responseHeaders.Del("Content-Encoding")
774+
775+
// 对于 ExoPlayer,我们最好设置一个强缓存标志并且带有 ETag 以支持精确的范围请求
776+
// 否则 ExoPlayer 在拖拽时可能会发送没有 If-Range 的请求或者放弃使用现有的 Cache
762777
for key, values := range responseHeaders {
763778
if strings.EqualFold(strings.ToLower(key), "connection") || strings.EqualFold(strings.ToLower(key), "proxy-connection") {
764779
continue
765780
}
766781
w.Header().Set(key, strings.Join(values, ","))
767782
}
768-
// 强制设置缓存头,让播放器尽可能缓存已下载的数据,实现秒切回已缓冲位置
769783
w.Header().Set("Cache-Control", "public, max-age=31536000")
770784
w.Header().Del("Pragma")
771785
w.Header().Del("Expires")

0 commit comments

Comments
 (0)