fix: preserve authenticated HLS session redirects
This commit is contained in:
@@ -595,7 +595,18 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
r = conn.getresponse()
|
r = conn.getresponse()
|
||||||
if r.status >= 400:
|
if r.status >= 400:
|
||||||
raise Problem('暂时没有可播放画面,请确认设备网络、账号、码流路径和录像时间', 503)
|
raise Problem('暂时没有可播放画面,请确认设备网络、账号、码流路径和录像时间', 503)
|
||||||
|
location = None
|
||||||
|
if 300 <= r.status < 400:
|
||||||
|
# MediaMTX starts an HLS session with a relative redirect. The
|
||||||
|
# browser must keep that session query on subsequent playlists.
|
||||||
|
target = url.urlsplit(url.urljoin(path, r.getheader('Location', '')))
|
||||||
|
if (port != HLS_PORT or target.scheme or target.netloc
|
||||||
|
or not re.fullmatch(r'/cam_[a-f0-9]{16}_(main|sub)/[a-zA-Z0-9_.-]+', target.path)):
|
||||||
|
raise Problem('视频服务返回了无效的播放跳转', 502)
|
||||||
|
location = '/media/live' + target.path + ('?' + target.query if target.query else '')
|
||||||
self.send_response(r.status)
|
self.send_response(r.status)
|
||||||
|
if location:
|
||||||
|
self.send_header('Location', location)
|
||||||
for k in ('Content-Type', 'Content-Length', 'Content-Range', 'Accept-Ranges'):
|
for k in ('Content-Type', 'Content-Length', 'Content-Range', 'Accept-Ranges'):
|
||||||
if r.getheader(k):
|
if r.getheader(k):
|
||||||
self.send_header(k, r.getheader(k))
|
self.send_header(k, r.getheader(k))
|
||||||
|
|||||||
+6
-1
@@ -65,7 +65,12 @@ function renderLive() {
|
|||||||
video.onerror=()=>error('浏览器无法解码此码流。可尝试切换清晰度,或将摄像头设为 H.264。');
|
video.onerror=()=>error('浏览器无法解码此码流。可尝试切换清晰度,或将摄像头设为 H.264。');
|
||||||
if (window.Hls?.isSupported()) {
|
if (window.Hls?.isSupported()) {
|
||||||
const hls = new Hls({maxBufferLength:10,backBufferLength:5,liveSyncDurationCount:3,manifestLoadingMaxRetry:2,levelLoadingMaxRetry:2});
|
const hls = new Hls({maxBufferLength:10,backBufferLength:5,liveSyncDurationCount:3,manifestLoadingMaxRetry:2,levelLoadingMaxRetry:2});
|
||||||
hls.on(Hls.Events.ERROR,(_,data)=>{if(data.fatal){error('画面暂未接通,请检查设备账号、路径、网络或编码。点击刷新状态可重试。');hls.destroy();}});
|
hls.on(Hls.Events.ERROR,(_,data)=>{if(data.fatal){
|
||||||
|
const codecError = /codec|bufferAddCodec|manifestIncompatible/i.test(data.details || '');
|
||||||
|
error(codecError ? '浏览器不支持当前视频编码,需要服务器提供兼容码流。' : '画面加载失败('+(data.details || data.type)+')。点击刷新状态可重试。');
|
||||||
|
console.warn('Video playback failed', c.id, data.type, data.details);
|
||||||
|
hls.destroy();
|
||||||
|
}});
|
||||||
hls.on(Hls.Events.MANIFEST_PARSED,()=>video.play().catch(()=>{}));
|
hls.on(Hls.Events.MANIFEST_PARSED,()=>video.play().catch(()=>{}));
|
||||||
hls.loadSource(src);hls.attachMedia(video);players.push(hls);
|
hls.loadSource(src);hls.attachMedia(video);players.push(hls);
|
||||||
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {video.src=src;video.play().catch(()=>{});}
|
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {video.src=src;video.play().catch(()=>{});}
|
||||||
|
|||||||
Reference in New Issue
Block a user