2025-07-22 00:34:04 -05:00

71 lines
1.6 KiB
Go

package downloader
import (
"context"
"fmt"
"m3u8-downloader/pkg/media"
"net/url"
"sync"
"time"
)
func resolveURL(baseURL string, segmentURL string) (string, error) {
base, err := url.Parse(baseURL)
if err != nil {
return "", err
}
segment, err := url.Parse(segmentURL)
if err != nil {
return "", err
}
return base.ResolveReference(segment).String(), nil
}
func (s *DownloadService) DownloadWorker(id int, segmentChan <-chan media.Segment, wg *sync.WaitGroup, baseURL string) (int, int) {
defer wg.Done()
numErrors := 0
numDownloads := 0
for segment := range segmentChan {
cleanedURL, err := resolveURL(baseURL, segment.URL)
if err != nil {
fmt.Printf("[Worker %d] Error: %s\n", id, err)
return -1, -1
}
fmt.Printf("[Worker %d] Downloading: %s\n", id, cleanedURL)
downloadErr := s.DownloadFile(cleanedURL)
if downloadErr != nil {
if downloadErr.Error() == "HTTP 403: 403 Forbidden" {
fmt.Printf("[Worker %d] URL Forbidden: %s\n", id, cleanedURL)
numErrors++
continue
}
fmt.Printf("[Worker %d] Error: %s\n", id, downloadErr)
numErrors++
return -1, -1
}
numDownloads++
}
return numErrors, numDownloads
}
func PlaylistRefreshWorker(ctx context.Context, playlistURL string, segmentsChan chan<- string, seen *sync.Map) {
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
segments, err := GetSegmentURLs(playlistURL)
if err != nil {
fmt.Println(err)
continue
}
for _, segment := range segments {
if _, ok := seen.Load(segment); !ok {
seen.Store(segment, true)
}