优化播放

This commit is contained in:
truewhile
2026-09-30 11:20:27 +08:00
parent 8136e6ecb1
commit 1e6909ddbf
10 changed files with 244 additions and 37 deletions
+68
View File
@@ -5,6 +5,8 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"os"
"path/filepath"
"strings"
"testing"
@@ -251,6 +253,72 @@ func TestServeFilePassesThroughForeignInstanceSTRMURL(t *testing.T) {
// 本机自己生成的 .strm 在换了域名/IP 之后仍要认领:host 对不上,但 acct 是本机
// 网盘账号,于是按当前请求 host 相对化,保持可播放。
// 扫描时 .strm 内容解析失败会产生 Container=strm 但 STRMURL 为空的行:
// 播放路径必须回读 .strm 文件内容兜底(与 MediaPlaybackProvider 等一致),
// 而不是把 .strm 文本文件当视频流返回。
func TestServeFileFallsBackToStrmFileContentWhenSTRMURLEmpty(t *testing.T) {
repos := newStreamTestRepo(t)
dir := t.TempDir()
strmPath := filepath.Join(dir, "Movie.strm")
target := "https://cdn.example.test/Movie.mkv?sign=direct"
if err := os.WriteFile(strmPath, []byte(target+"\n"), 0o600); err != nil {
t.Fatal(err)
}
if err := repos.DB.Create(&model.Media{
Base: model.Base{ID: "strm-empty-url"},
Title: "STRM Empty URL",
Path: strmPath,
Container: "strm",
STRMURL: "",
}).Error; err != nil {
t.Fatal(err)
}
svc := NewStreamService(&config.Config{}, zap.NewNop(), repos, nil)
req := httptest.NewRequest(http.MethodGet, "http://nas.local:18080/api/stream/strm-empty-url?token=jwt123", nil)
w := httptest.NewRecorder()
if err := svc.ServeFile(w, req, "strm-empty-url"); err != nil {
t.Fatalf("empty-STRMURL .strm row should fall back to file content: %v", err)
}
if w.Code != http.StatusFound {
t.Fatalf("status = %d, want 302", w.Code)
}
if loc := w.Header().Get("Location"); loc != target {
t.Fatalf("Location = %q, want %q", loc, target)
}
}
// .strm 内容完全解析不出播放目标时,返回明确的 502 错误,绝不把 .strm 文本
// 文件本身当视频流吐给播放器。
func TestServeFileRejectsStrmRowWithUnresolvableTarget(t *testing.T) {
repos := newStreamTestRepo(t)
dir := t.TempDir()
strmPath := filepath.Join(dir, "Broken.strm")
if err := os.WriteFile(strmPath, []byte("# 只有注释,没有可用播放地址\n"), 0o600); err != nil {
t.Fatal(err)
}
if err := repos.DB.Create(&model.Media{
Base: model.Base{ID: "strm-broken"},
Title: "STRM Broken",
Path: strmPath,
Container: "strm",
STRMURL: "",
}).Error; err != nil {
t.Fatal(err)
}
svc := NewStreamService(&config.Config{}, zap.NewNop(), repos, nil)
req := httptest.NewRequest(http.MethodGet, "http://nas.local:18080/api/stream/strm-broken", nil)
w := httptest.NewRecorder()
err := svc.ServeFile(w, req, "strm-broken")
if !errors.Is(err, ErrCloudPlaybackUnavailable) {
t.Fatalf("error = %v, want ErrCloudPlaybackUnavailable", err)
}
if w.Code != http.StatusOK {
t.Fatalf("no bytes should be written on error, status = %d", w.Code)
}
}
func TestServeFileRealignsOwnSTRMURLOtherHost(t *testing.T) {
repos := repository.New(newServiceTestDB(t, &model.Media{}, &model.Setting{}, &model.StrmAccount{}))
if err := repos.StrmAccount.Create(t.Context(), &model.StrmAccount{