68 lines
1.4 KiB
Go
68 lines
1.4 KiB
Go
package dvr
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"m3u8-downloader/pkg/constants"
|
|
"net/http"
|
|
"os"
|
|
)
|
|
|
|
// segmentDownloader processes segment URLs and downloads them
|
|
func SegmentDownloader(ctx context.Context, id int, segmentsChan <-chan string) {
|
|
client := &http.Client{}
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case seg, ok := <-segmentsChan:
|
|
if !ok {
|
|
return
|
|
}
|
|
if err := downloadSegment(client, seg); err != nil {
|
|
fmt.Printf("Worker %d: failed to download %s: %v\n", id, seg, err)
|
|
} else {
|
|
fmt.Printf("Worker %d: downloaded %s\n", id, seg)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func downloadSegment(client *http.Client, segmentURL string) error {
|
|
req, err := http.NewRequest("GET", segmentURL, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Header.Set("User-Agent", constants.HTTPUserAgent)
|
|
req.Header.Set("Referer", constants.REFERRER)
|
|
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return fmt.Errorf("status %d", resp.StatusCode)
|
|
}
|
|
|
|
// Save the segment (or buffer it, depending on your DVR strategy)
|
|
fileName := extractSegmentName(segmentURL)
|
|
out, err := os.Create(fileName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer out.Close()
|
|
|
|
_, err = io.Copy(out, resp.Body)
|
|
return err
|
|
}
|
|
|
|
// extractSegmentName is a placeholder that turns the URL into a local filename
|
|
func extractSegmentName(segmentURL string) string {
|
|
// TODO: Implement robust name parsing
|
|
return "segment.ts"
|
|
}
|