mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-02 12:26:36 +08:00
优化360播放
This commit is contained in:
@@ -722,7 +722,9 @@ func streamHandler(svc *service.Container) gin.HandlerFunc {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
|
||||
return
|
||||
}
|
||||
if mount.ProxyPlay {
|
||||
// 远程 Emby 条目的同源转发:VR 全景需要浏览器读帧(见 stream_proxy.go),
|
||||
// 与挂载账号的 proxy_play 开关等价。
|
||||
if mount.ProxyPlay || wantSameOriginProxy(c) {
|
||||
if err := svc.Emby.ProxyRemoteVideoStream(ctx, c.Writer, c.Request, mountID, remoteID); err != nil {
|
||||
if !c.Writer.Written() {
|
||||
c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
|
||||
@@ -758,6 +760,15 @@ func streamHandler(svc *service.Container) gin.HandlerFunc {
|
||||
if !enforceScopedPlaybackToken(c, m.ID) {
|
||||
return
|
||||
}
|
||||
// ?proxy=1:把网盘/STRM 直链改为服务端同源转发(网页端读帧、VR 全景用),
|
||||
// 画质与原文件一致,不触发转码。
|
||||
if wantSameOriginProxy(c) {
|
||||
handled, proxyErr := proxySTRMStream(c, svc, m)
|
||||
if handled {
|
||||
writeProxyError(c, proxyErr)
|
||||
return
|
||||
}
|
||||
}
|
||||
err = svc.Stream.ServeFile(c.Writer, c.Request, c.Param("id"))
|
||||
if errors.Is(err, service.ErrMediaNotFound) {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// 直连流的同源转发:网页端需要读取视频帧的场景(VR 全景渲染走 WebGL 纹理)
|
||||
// 不能使用会跳到网盘 CDN 的跨域直链,这里把直链改为服务端转发。
|
||||
//
|
||||
// 只在客户端显式带上 ?proxy=1 时生效,普通播放仍走原来的 302 直连,
|
||||
// 避免把网盘流量无谓地压到服务器上。
|
||||
package handler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/truewhile/MeBox/internal/model"
|
||||
"github.com/truewhile/MeBox/internal/service"
|
||||
)
|
||||
|
||||
// wantSameOriginProxy 客户端是否要求把直连流改为服务端同源转发。
|
||||
func wantSameOriginProxy(c *gin.Context) bool {
|
||||
if c == nil {
|
||||
return false
|
||||
}
|
||||
switch strings.ToLower(strings.TrimSpace(c.Query("proxy"))) {
|
||||
case "1", "true", "yes":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// proxySTRMStream 处理 STRM/网盘媒体的同源转发请求。返回 handled=false 表示
|
||||
// 该媒体不需要(或无法)代理,调用方继续按原有逻辑处理。
|
||||
func proxySTRMStream(c *gin.Context, svc *service.Container, m *model.Media) (bool, error) {
|
||||
if c == nil || svc == nil || svc.Strm == nil || m == nil {
|
||||
return false, nil
|
||||
}
|
||||
if !service.IsStrmMediaRow(m) {
|
||||
return false, nil
|
||||
}
|
||||
if err := svc.Strm.ProxyMediaDirect(c.Request.Context(), c.Writer, c.Request, m); err != nil {
|
||||
if errors.Is(err, service.ErrStrmProxyNotApplicable) {
|
||||
return false, nil
|
||||
}
|
||||
return true, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// writeProxyError 在尚未写入任何响应内容时回一个明确的网关错误。
|
||||
func writeProxyError(c *gin.Context, err error) {
|
||||
if c == nil || err == nil || c.Writer.Written() {
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
|
||||
}
|
||||
Reference in New Issue
Block a user