fix(hls): improve buffering and error handling in HLS player

- Adjust Hls.js config
This commit is contained in:
tigeren 2025-10-01 17:20:21 +00:00
parent fef8f57e9b
commit 4489fc5381
3 changed files with 50 additions and 6 deletions

View File

@ -76,10 +76,12 @@ export async function GET(
const response = {
videoId,
session: session ? {
sessionId: session.sessionId,
videoId: session.videoId,
videoPath: session.videoPath,
status: session.status,
segmentCount: session.segmentCount,
totalDuration: session.totalDuration,
referenceCount: session.referenceCount,
createdAt: session.createdAt,
lastAccessed: session.lastAccessed,
tempDir: session.tempDir,

View File

@ -182,16 +182,28 @@ export default function ArtPlayerWrapper({
hlsInstance = new Hls({
debug: process.env.NODE_ENV === 'development',
enableWorker: true,
lowLatencyMode: true,
lowLatencyMode: false, // Disable for better buffering
backBufferLength: 90,
maxBufferLength: 300,
maxBufferSize: 60 * 1000 * 1000, // 60MB
maxBufferLength: 120, // Increase buffer length
maxBufferSize: 100 * 1000 * 1000, // 100MB buffer
maxBufferHole: 0.5, // Allow small holes
startLevel: -1, // Auto-select optimal quality
capLevelToPlayerSize: true,
autoStartLoad: true,
maxFragLookUpTolerance: 0.25,
liveSyncDurationCount: 3,
liveMaxLatencyDurationCount: 10,
// Aggressive preloading for better buffering
manifestLoadingTimeOut: 10000,
manifestLoadingMaxRetry: 2,
levelLoadingTimeOut: 10000,
levelLoadingMaxRetry: 2,
fragLoadingTimeOut: 20000, // Longer timeout for large segments
fragLoadingMaxRetry: 3,
// Bandwidth estimation settings
abrEwmaDefaultEstimate: 500000, // 500kbps initial estimate
abrBandWidthFactor: 0.95,
abrBandWidthUpFactor: 0.7,
});
// Set up comprehensive error handling
@ -242,8 +254,26 @@ export default function ArtPlayerWrapper({
}
});
// Monitor fragment loading for debugging
hlsInstance.on(Hls.Events.FRAG_LOADING, (event, data) => {
console.log(`Loading fragment ${data.frag.sn}: ${data.frag.url}`);
});
hlsInstance.on(Hls.Events.FRAG_LOADED, (event, data) => {
console.log(`Loaded fragment ${data.frag.sn} (${(data.payload.byteLength / 1024).toFixed(1)}KB)`);
});
hlsInstance.on(Hls.Events.ERROR, (event: string, data: any) => {
console.error('HLS error:', data);
console.error('HLS error details:', {
type: data.type,
details: data.details,
fatal: data.fatal,
url: data.url,
reason: data.reason,
level: data.level,
fragCurrent: data.fragCurrent,
response: data.response
});
if (data.fatal) {
switch (data.type) {
@ -261,6 +291,18 @@ export default function ArtPlayerWrapper({
// This will trigger fallback in the parent component
break;
}
} else {
// Handle non-fatal errors
switch (data.details) {
case Hls.ErrorDetails.FRAG_PARSING_ERROR:
console.warn('Fragment parsing error, will continue with next segment');
break;
case Hls.ErrorDetails.BUFFER_STALLED_ERROR:
console.warn('Buffer stalled, attempting to unstall');
break;
default:
console.warn('Non-fatal HLS error:', data.details);
}
}
});

View File

@ -41,7 +41,7 @@ export interface SegmentationConfig {
const DEFAULT_CONFIG: SegmentationConfig = {
tempDir: '/tmp/nextav-hls',
segmentDuration: 6,
segmentDuration: 4, // Reduce from 6 to 4 seconds for smaller segments
sessionTTL: 30 * 60 * 1000, // 30 minutes
maxConcurrentJobs: 2,
minDiskSpace: 1024 * 1024 * 1024, // 1GB