mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-08-04 07:42:47 +00:00
Better error messaging for unsupported codecs in the web player. Also don't block controls with error messages.
This commit is contained in:
parent
0a994bbe3f
commit
ae01440a15
1 changed files with 115 additions and 87 deletions
|
|
@ -73,72 +73,109 @@ export default function FloatingVideo() {
|
|||
console.log("Attempting to play stream:", streamUrl);
|
||||
|
||||
try {
|
||||
// If the browser supports MSE for live playback, initialize mpegts.js
|
||||
if (mpegts.getFeatureList().mseLivePlayback) {
|
||||
// Set loading flag
|
||||
setIsLoading(true);
|
||||
|
||||
const player = mpegts.createPlayer({
|
||||
type: 'mpegts', // MPEG-TS format
|
||||
url: streamUrl,
|
||||
isLive: true,
|
||||
enableWorker: true,
|
||||
enableStashBuffer: false, // Try disabling stash buffer for live streams
|
||||
liveBufferLatencyChasing: true,
|
||||
liveSync: true,
|
||||
cors: true, // Enable CORS for cross-domain requests
|
||||
// Add error recovery options
|
||||
autoCleanupSourceBuffer: true,
|
||||
autoCleanupMaxBackwardDuration: 10,
|
||||
autoCleanupMinBackwardDuration: 5,
|
||||
reuseRedirectedURL: true,
|
||||
});
|
||||
|
||||
player.attachMediaElement(videoRef.current);
|
||||
|
||||
// Add events to track loading state
|
||||
player.on(mpegts.Events.LOADING_COMPLETE, () => {
|
||||
setIsLoading(false);
|
||||
});
|
||||
|
||||
player.on(mpegts.Events.METADATA_ARRIVED, () => {
|
||||
setIsLoading(false);
|
||||
});
|
||||
|
||||
// Add error event handler
|
||||
player.on(mpegts.Events.ERROR, (errorType, errorDetail) => {
|
||||
setIsLoading(false);
|
||||
|
||||
// Filter out aborted errors
|
||||
if (errorType !== 'NetworkError' || !errorDetail?.includes('aborted')) {
|
||||
console.error('Player error:', errorType, errorDetail);
|
||||
setLoadError(`Error: ${errorType}${errorDetail ? ` - ${errorDetail}` : ''}`);
|
||||
}
|
||||
});
|
||||
|
||||
player.load();
|
||||
|
||||
// Don't auto-play until we've loaded properly
|
||||
player.on(mpegts.Events.MEDIA_INFO, () => {
|
||||
setIsLoading(false);
|
||||
try {
|
||||
player.play().catch(e => {
|
||||
console.log("Auto-play prevented:", e);
|
||||
setLoadError("Auto-play was prevented. Click play to start.");
|
||||
});
|
||||
} catch (e) {
|
||||
console.log("Error during play:", e);
|
||||
setLoadError(`Playback error: ${e.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Store player instance so we can clean up later
|
||||
playerRef.current = player;
|
||||
// Check for MSE support first
|
||||
if (!mpegts.getFeatureList().mseLivePlayback) {
|
||||
setIsLoading(false);
|
||||
setLoadError("Your browser doesn't support live video streaming. Please try Chrome or Edge.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for basic codec support
|
||||
const video = document.createElement('video');
|
||||
const h264Support = video.canPlayType('video/mp4; codecs="avc1.42E01E"');
|
||||
const aacSupport = video.canPlayType('audio/mp4; codecs="mp4a.40.2"');
|
||||
|
||||
console.log("Browser codec support - H264:", h264Support, "AAC:", aacSupport);
|
||||
|
||||
// If the browser supports MSE for live playback, initialize mpegts.js
|
||||
setIsLoading(true);
|
||||
|
||||
const player = mpegts.createPlayer({
|
||||
type: 'mpegts',
|
||||
url: streamUrl,
|
||||
isLive: true,
|
||||
enableWorker: true,
|
||||
enableStashBuffer: false,
|
||||
liveBufferLatencyChasing: true,
|
||||
liveSync: true,
|
||||
cors: true,
|
||||
autoCleanupSourceBuffer: true,
|
||||
autoCleanupMaxBackwardDuration: 10,
|
||||
autoCleanupMinBackwardDuration: 5,
|
||||
reuseRedirectedURL: true,
|
||||
});
|
||||
|
||||
player.attachMediaElement(videoRef.current);
|
||||
|
||||
// Add events to track loading state
|
||||
player.on(mpegts.Events.LOADING_COMPLETE, () => {
|
||||
setIsLoading(false);
|
||||
});
|
||||
|
||||
player.on(mpegts.Events.METADATA_ARRIVED, () => {
|
||||
setIsLoading(false);
|
||||
});
|
||||
|
||||
// Enhanced error event handler with codec-specific messages
|
||||
player.on(mpegts.Events.ERROR, (errorType, errorDetail) => {
|
||||
setIsLoading(false);
|
||||
|
||||
// Filter out aborted errors
|
||||
if (errorType !== 'NetworkError' || !errorDetail?.includes('aborted')) {
|
||||
console.error('Player error:', errorType, errorDetail);
|
||||
|
||||
// Provide specific error messages based on error type
|
||||
let errorMessage = `Error: ${errorType}`;
|
||||
|
||||
if (errorType === 'MediaError') {
|
||||
// Try to determine if it's an audio or video codec issue
|
||||
const errorString = errorDetail?.toLowerCase() || '';
|
||||
|
||||
if (errorString.includes('audio') || errorString.includes('ac3') || errorString.includes('ac-3')) {
|
||||
errorMessage = "Audio codec not supported by your browser. Try Chrome or Edge for better audio codec support.";
|
||||
} else if (errorString.includes('video') || errorString.includes('h264') || errorString.includes('h.264')) {
|
||||
errorMessage = "Video codec not supported by your browser. Try Chrome or Edge for better video codec support.";
|
||||
} else if (errorString.includes('mse')) {
|
||||
errorMessage = "Your browser doesn't support the codecs used in this stream. Try Chrome or Edge for better compatibility.";
|
||||
} else {
|
||||
errorMessage = "Media codec not supported by your browser. This may be due to unsupported audio (AC3) or video codecs. Try Chrome or Edge.";
|
||||
}
|
||||
} else if (errorDetail) {
|
||||
errorMessage += ` - ${errorDetail}`;
|
||||
}
|
||||
|
||||
setLoadError(errorMessage);
|
||||
}
|
||||
});
|
||||
|
||||
player.load();
|
||||
|
||||
// Don't auto-play until we've loaded properly
|
||||
player.on(mpegts.Events.MEDIA_INFO, () => {
|
||||
setIsLoading(false);
|
||||
try {
|
||||
player.play().catch(e => {
|
||||
console.log("Auto-play prevented:", e);
|
||||
setLoadError("Auto-play was prevented. Click play to start.");
|
||||
});
|
||||
} catch (e) {
|
||||
console.log("Error during play:", e);
|
||||
setLoadError(`Playback error: ${e.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Store player instance so we can clean up later
|
||||
playerRef.current = player;
|
||||
} catch (error) {
|
||||
setIsLoading(false);
|
||||
setLoadError(`Initialization error: ${error.message}`);
|
||||
console.error("Error initializing player:", error);
|
||||
|
||||
// Provide helpful error message based on the error
|
||||
if (error.message?.includes('codec') || error.message?.includes('format')) {
|
||||
setLoadError("Codec not supported by your browser. Please try a different browser (Chrome/Edge recommended).");
|
||||
} else {
|
||||
setLoadError(`Initialization error: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup when component unmounts or streamUrl changes
|
||||
|
|
@ -191,7 +228,7 @@ export default function FloatingVideo() {
|
|||
style={{ width: '100%', height: '180px', backgroundColor: '#000' }}
|
||||
/>
|
||||
|
||||
{/* Loading overlay */}
|
||||
{/* Loading overlay - only show when loading */}
|
||||
{isLoading && (
|
||||
<Box
|
||||
style={{
|
||||
|
|
@ -214,31 +251,22 @@ export default function FloatingVideo() {
|
|||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Error message overlay */}
|
||||
{!isLoading && loadError && (
|
||||
<Box
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.7)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
zIndex: 5,
|
||||
padding: '0 10px',
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
<Text color="red" size="sm">
|
||||
{loadError}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{/* Error message below video - doesn't block controls */}
|
||||
{!isLoading && loadError && (
|
||||
<Box
|
||||
style={{
|
||||
padding: '10px',
|
||||
backgroundColor: '#2d1b2e',
|
||||
borderTop: '1px solid #444',
|
||||
}}
|
||||
>
|
||||
<Text color="red" size="xs" style={{ textAlign: 'center' }}>
|
||||
{loadError}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</div>
|
||||
</Draggable>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue