mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-12 00:06:37 +08:00
5f4b613bde
115 云 HLS 会话只存在服务端内存里:服务重新部署、会话过期(30 分钟无活动)、 上游分片地址失效,都会让播放中的客户端在后续分片上拿到 404/410。原实现此时 直接退回本地转码,而低配宿主机本地转码追不上播放速度(实测 2 vCPU 只有 0.62x),用户看到的就是播放报废。 - 云 HLS 中途 fatal 时先重建会话续播(10 分钟内最多 3 次),仍失败才退回本地 - manifestLoadingMaxRetry 1 -> 4:master.m3u8 每次都要现调 115 接口,一次抖动 不该直接判死刑 - 播放列表重写改用上游地址哈希做 key:原来用自增序号,每次重写 entries 就膨胀 一轮、分片编号漂移(实测 762 段列表重写几次后 key 涨到 e2288..e3049) - 会话条目数加上限,异常播放列表不会无限占用内存 - 客户端断开(seek / 切清晰度取消在途请求)不再记成 502,改记 499 与 nginx 对齐;会话失效返回带 code 的 404/410,便于前端判断需要重建会话 - 修正进度/时长上报:云 HLS 时间轴起点恒为 0,不应再叠加 hlsStartSec(历史上 把 7624s 的片子记成 8346s 并标成「已看完」) - 切回直连 / 原画时保住播放位置:HLS 卸载会把 currentTime 归零,必须在切换前 先记下目标位置
59 lines
2.0 KiB
Go
59 lines
2.0 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/truewhile/MeBox/internal/config"
|
|
"github.com/truewhile/MeBox/internal/service"
|
|
)
|
|
|
|
// 云 HLS 分片代理的错误映射:
|
|
// - 会话不存在/过期要给前端可判断的 code,前端据此重拉 master.m3u8 建会话续播,
|
|
// 而不是当成播放失败直接退回本地转码;
|
|
// - 客户端主动断开(seek、切清晰度、关页面取消在途请求)不是网关故障,记 499,
|
|
// 与 nginx 的口径一致。以前统一记 502,既污染监控又会让前端拿到误导性错误。
|
|
func newCloud115HLSSessionTestRouter() *gin.Engine {
|
|
gin.SetMode(gin.TestMode)
|
|
svc := &service.Container{
|
|
Cloud115: service.NewCloud115PlaybackService(&config.Config{}, zap.NewNop(), nil, nil),
|
|
}
|
|
router := gin.New()
|
|
router.GET("/api/cloud115/hls/:session/:key", cloud115HLSSessionHandler(svc))
|
|
return router
|
|
}
|
|
|
|
func TestCloud115HLSSessionUnknownSessionReturnsCodedNotFound(t *testing.T) {
|
|
router := newCloud115HLSSessionTestRouter()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/cloud115/hls/unknown-session/abc?media_id=media-1", nil)
|
|
rec := httptest.NewRecorder()
|
|
router.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusNotFound {
|
|
t.Fatalf("status = %d, want 404; body=%s", rec.Code, rec.Body.String())
|
|
}
|
|
if !strings.Contains(rec.Body.String(), "hls_session_not_found") {
|
|
t.Fatalf("expected machine-readable code in body, got %s", rec.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestCloud115HLSSessionClientAbortReturns499(t *testing.T) {
|
|
router := newCloud115HLSSessionTestRouter()
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/cloud115/hls/unknown-session/abc?media_id=media-1", nil).
|
|
WithContext(ctx)
|
|
rec := httptest.NewRecorder()
|
|
router.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != 499 {
|
|
t.Fatalf("status = %d, want 499 (client closed request); body=%s", rec.Code, rec.Body.String())
|
|
}
|
|
}
|