fix: ctx cancellation

This commit is contained in:
2025-11-18 13:07:24 +01:00
parent 308dd6ad6e
commit 7c331252cb

View File

@@ -24,6 +24,7 @@ import (
const ( const (
defaultClientTimeout = 30 * time.Second defaultClientTimeout = 30 * time.Second
vodSegmentTimeout = 5 * time.Minute // Longer timeout for VOD segments which can be large
maxRedirects = 5 maxRedirects = 5
playlistPollInterval = 2 * time.Second // Poll interval for livestreams playlistPollInterval = 2 * time.Second // Poll interval for livestreams
) )
@@ -193,6 +194,20 @@ func downloadPlaylist(ctx context.Context, client *http.Client, parsed *url.URL,
} }
// For VOD (Video on Demand), use temp file and convert to MP4 // For VOD (Video on Demand), use temp file and convert to MP4
// Create a context without deadline for VOD downloads to avoid premature cancellation
// Preserve cancellation from parent context but remove any deadline
vodCtx, vodCancel := context.WithCancel(context.Background())
defer vodCancel()
// If parent context is cancelled, cancel VOD context too
go func() {
<-ctx.Done()
vodCancel()
}()
// Create a client with longer timeout for VOD segments
vodClient := &http.Client{Timeout: vodSegmentTimeout}
tempTS, err := os.CreateTemp("", "sdl-*.ts") tempTS, err := os.CreateTemp("", "sdl-*.ts")
if err != nil { if err != nil {
return fmt.Errorf("create temp file: %w", err) return fmt.Errorf("create temp file: %w", err)
@@ -208,12 +223,13 @@ func downloadPlaylist(ctx context.Context, client *http.Client, parsed *url.URL,
fmt.Fprintf(os.Stderr, "Downloading %d segments...\n", totalSegments) fmt.Fprintf(os.Stderr, "Downloading %d segments...\n", totalSegments)
for i, segment := range segments { for i, segment := range segments {
if err := downloadSegment(ctx, client, finalURL, segment, tempTS); err != nil { if err := downloadSegment(vodCtx, vodClient, finalURL, segment, tempTS); err != nil {
return fmt.Errorf("download segment %d: %w", i, err) return fmt.Errorf("download segment %d: %w", i, err)
} }
// Show progress: segment number, total, and percentage // Show progress: segment number, total, and percentage
progress := float64(i+1) / float64(totalSegments) * 100 progress := float64(i+1) / float64(totalSegments) * 100
fmt.Fprintf(os.Stderr, "\rProgress: %d/%d segments (%.1f%%)", i+1, totalSegments, progress) fmt.Fprintf(os.Stderr, "\rProgress: %d/%d segments (%.1f%%)", i+1, totalSegments, progress)
os.Stderr.Sync() // Flush progress output
} }
fmt.Fprintf(os.Stderr, "\n") fmt.Fprintf(os.Stderr, "\n")
@@ -223,7 +239,7 @@ func downloadPlaylist(ctx context.Context, client *http.Client, parsed *url.URL,
mp4Name := ensureMP4Extension(name) mp4Name := ensureMP4Extension(name)
fmt.Fprintf(os.Stderr, "Converting to MP4...\n") fmt.Fprintf(os.Stderr, "Converting to MP4...\n")
if err := transmuxToMP4(ctx, tempPath, mp4Name); err != nil { if err := transmuxToMP4(vodCtx, tempPath, mp4Name); err != nil {
return err return err
} }
fmt.Fprintf(os.Stderr, "Complete: %s\n", mp4Name) fmt.Fprintf(os.Stderr, "Complete: %s\n", mp4Name)