chen3861229/embyExternalUrl

关于Web播放Strm直链的新想法

Closed this issue · 1 comments

思路

通过6.115 内容无法 Web 端播放(htmlvideoplayer 跨域)?bpking1#236 的修改方法,我发现主要受到Emby容器内/system/dashboard-ui/modules/htmlvideoplayer/plugin.js这个JS脚本的控制,于是我抓包发现/web/modules/htmlvideoplayer/basehtmlplayer.js这个地址会请求类似内容

{cast.framework.CastReceiverContext.getInstance().getPlayerManager().setMessageInterceptor(cast.framework.messages.MessageType.LOAD,null)},BaseHtmlPlayer.prototype.getCrossOriginValue=function(mediaSource,playMethod){return mediaSource.IsRemote&&"DirectPlay"===playMethod?null:"anonymous"};_exports.default=BaseHtmlPlayer});

具体实现

我在Golong的Gin框架下路由该API已到达拦截请求的效果,并将mediaSource.IsRemote&&"DirectPlay"===playMethod?null:"anonymous"替换为null

// 运行Web播放Strm跨域请求
func WebCROSHandler(ctx *gin.Context) {
	fmt.Println("匹配路由:/web/modules/htmlvideoplayer/basehtmlplayer.js\t请求方法:", ctx.Request.Method)
	version := ctx.Query("v")
	fmt.Println("请求basehtmlplayer.js版本:", version)
	resp, err := http.Get(config.Target + ctx.Request.URL.Path + "?" + ctx.Request.URL.RawQuery)
	if err != nil {
		fmt.Println("请求失败,使用回源策略,错误信息:", err)
		ReverseProxyHandler(ctx)
		return
	}

	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("读取响应体失败,使用回源策略,错误信息:", err)
		ReverseProxyHandler(ctx)
		return
	}
	modifiedBody := strings.ReplaceAll(string(body), `mediaSource.IsRemote&&"DirectPlay"===playMethod?null:"anonymous"`, "null")

	for key, values := range resp.Header {
		for _, value := range values {
			if key != "Content-Length" {
				ctx.Writer.Header().Add(key, value)
			}
		}
	}
	// 返回修改后的内容
	ctx.Data(resp.StatusCode, resp.Header.Get("Content-Type"), []byte(modifiedBody))

}

经测试,在Edge和Safari下均可正常播放(跨域请求成功)
image

优点

  1. 无需修改Emby服务端即可实现操作
  2. Web的请求会携带版本号,通过查询参数获得,目前我的测试环境是v=4.8.8.0,若以后Emby策略改动,可以通过判断版本号实现不同行为

注意事项

记得屏蔽resp中的Content-Length手动计算或者让客户端重新计算,否则Web会卡在Emby那个banner页那里
计算方法:

for key, values := range resp.Header {
	for _, value := range values {
		if key != "Content-Length" {
			ctx.Writer.Header().Add(key, value)
		} else {
			ctx.Header("Content-Length", fmt.Sprintf("%d", len(modifiedBody)))
		}
	}
}

感谢 PR ,已经合并和做了对接,且测试为正常工作,目前是默认配置