mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 11:36:36 +08:00
fix(web): STRM 直连失败后回退 HLS 转码
不再把 STRM/云盘媒体锁死为直连,解析远端源后允许 ffmpeg 转码播放。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -28,7 +28,8 @@ import { mediaVersionsOf } from '../utils/mediaVersion'
|
||||
//
|
||||
// We pick a sensible default based on the source codec: H.264 + AAC in
|
||||
// MP4 / WebM containers play directly; everything else (HEVC, MKV, AV1,
|
||||
// AC3 audio, …) gets routed through ffmpeg → HLS.
|
||||
// AC3 audio, …) gets routed through ffmpeg → HLS. STRM / 云盘直链默认直连,
|
||||
// 浏览器播不了时再切 HLS。远程 Emby 挂载只能直连。
|
||||
//
|
||||
// External subtitles next to the source file are auto-discovered and
|
||||
// attached as <track> elements.
|
||||
@@ -208,7 +209,7 @@ export function PlayerPage() {
|
||||
setMedia(m)
|
||||
const isDirect = isDirectStreamMedia(m)
|
||||
const auto = pickPlayerMode(m)
|
||||
// 直连解码模式以及 STRM / Emby 挂载等直连媒体,忽略 ?mode=hls,始终 direct play。
|
||||
// 直连解码模式以及远程 Emby 挂载忽略 ?mode=hls。STRM 默认直连,但允许手动/失败后切 HLS。
|
||||
setMode(directOnly || isDirect ? 'direct' : (modeParam ?? auto))
|
||||
setPlayerError('')
|
||||
setLoadError('')
|
||||
@@ -539,12 +540,9 @@ export function PlayerPage() {
|
||||
// 浏览器对 <video src> 的错误描述非常有限,把详细原因
|
||||
// 转给开发者控制台 + 一条 toast;常见原因是 codec 不支持。
|
||||
if (mode === 'direct') {
|
||||
if (isRemoteEmbyID(media?.id)) {
|
||||
if (isRemoteEmbyID(media?.id) || isDirectStreamMedia(media)) {
|
||||
setPlayerError('直接播放失败。该媒体为远程 Emby 挂载直连播放(不进行转码);当前浏览器可能不支持该视频编码或音频格式,建议使用外部播放器(如 PotPlayer / VLC / IINA)播放。')
|
||||
toast.error('直接播放失败,建议使用外部播放器')
|
||||
} else if (isDirectStreamMedia(media)) {
|
||||
setPlayerError('直接播放失败。该媒体为 STRM 远程直连播放(不进行转码);当前浏览器可能不支持该视频编码或音频格式,建议使用外部播放器播放。')
|
||||
toast.error('直接播放失败,建议使用外部播放器')
|
||||
} else if (directOnly) {
|
||||
setPlayerError('直接播放失败。当前为「客户端直连解码」模式,宿主机不转码;请使用支持该编码/封装的播放器(如 Infuse / VLC / Emby 客户端)播放,或关闭直连解码模式。')
|
||||
toast.error('直接播放失败(客户端直连解码模式)')
|
||||
@@ -575,13 +573,7 @@ export function PlayerPage() {
|
||||
<PlayerTopBar
|
||||
directOnly={directOnly}
|
||||
isDirectStream={isDirectStream}
|
||||
directStreamLabel={
|
||||
isRemoteEmbyID(media?.id)
|
||||
? 'Emby 直连播放'
|
||||
: isDirectStream
|
||||
? 'STRM 直连播放'
|
||||
: undefined
|
||||
}
|
||||
directStreamLabel={isRemoteEmbyID(media?.id) ? 'Emby 直连播放' : undefined}
|
||||
mode={mode}
|
||||
onBack={goBack}
|
||||
onToggleMode={toggleMode}
|
||||
|
||||
@@ -8,13 +8,18 @@ const directVideoCodecs = ['h264', 'avc', 'avc1']
|
||||
const directAudioCodecs = ['aac', 'mp3', 'opus']
|
||||
|
||||
/**
|
||||
* 判断媒体是否为远程直链或挂载直连流媒体(STRM 或 Emby 远程挂载)。
|
||||
* 这类媒体服务端 302 重定向到直链或进行原生流中继,本地不具备原始文件,
|
||||
* 无法也不应该进行 ffmpeg 转码,恒走直连播放。
|
||||
* 远程 Emby 挂载:本地没有原始文件,网页端只能直连,不能转码。
|
||||
*/
|
||||
export function isDirectStreamMedia(media?: Media | null): boolean {
|
||||
if (!media) return false
|
||||
if (isRemoteEmbyID(media.id)) return true
|
||||
return isRemoteEmbyID(media.id)
|
||||
}
|
||||
|
||||
/**
|
||||
* STRM / 云盘直链:默认仍走直连;浏览器解不了时再回退 HLS 转码。
|
||||
*/
|
||||
export function isStrmMedia(media?: Media | null): boolean {
|
||||
if (!media) return false
|
||||
const container = (media.container ?? '').toLowerCase()
|
||||
return container.includes('strm') || String(media.strm_url ?? '').trim() !== ''
|
||||
}
|
||||
@@ -24,8 +29,8 @@ export function pickPlayerMode(media: Media): PlayerMode {
|
||||
}
|
||||
|
||||
export function needsTranscodeForBrowser(media: Media): boolean {
|
||||
// Emby 远程挂载与 .strm 媒体一样,均为直连流,无法进行本地转码,恒走 direct play。
|
||||
if (isDirectStreamMedia(media)) return false
|
||||
// Emby 远程挂载无法本地转码。STRM 先直连,失败后再由播放器切 HLS。
|
||||
if (isDirectStreamMedia(media) || isStrmMedia(media)) return false
|
||||
|
||||
const container = (media.container ?? '').toLowerCase()
|
||||
const videoCodec = (media.video_codec ?? '').toLowerCase()
|
||||
|
||||
Reference in New Issue
Block a user