package main import ( "encoding/base64" "encoding/json" "fmt" "io" "net/http" "os" "os/exec" "path/filepath" "strings" ) func processInputFile(inputFile string) error { jsonFile, err := os.Open(inputFile) if err != nil { return fmt.Errorf("error opening file %s: %v", inputFile, err) } defer jsonFile.Close() byteValue, err := io.ReadAll(jsonFile) if err != nil { return fmt.Errorf("error reading file %s: %v", inputFile, err) } byteValue = removeBOM(byteValue) var items Items err = json.Unmarshal(byteValue, &items) if err != nil { return fmt.Errorf("error unmarshaling JSON: %v", err) } for i, item := range items.Items { updateProgress(filepath.Base(inputFile), float64(i)/float64(len(items.Items))*100, item.Filename) err := downloadFile(item) if err != nil { fmt.Printf("Error downloading file: %v\n", err) } } updateProgress(filepath.Base(inputFile), 100, "") return nil } func removeBOM(input []byte) []byte { if len(input) >= 3 && input[0] == 0xEF && input[1] == 0xBB && input[2] == 0xBF { return input[3:] } return input } func downloadFile(item Item) error { fmt.Println("Downloading:", item.Filename) mpdPath := item.MPD if !isValidURL(item.MPD) { decodedMPD, err := base64.StdEncoding.DecodeString(item.MPD) if err != nil { return fmt.Errorf("error decoding base64 MPD: %v", err) } tempFile, err := os.CreateTemp("", "temp_mpd_*.mpd") if err != nil { return fmt.Errorf("error creating temporary MPD file: %v", err) } defer os.Remove(tempFile.Name()) if _, err := tempFile.Write(decodedMPD); err != nil { return fmt.Errorf("error writing to temporary MPD file: %v", err) } if err := tempFile.Close(); err != nil { return fmt.Errorf("error closing temporary MPD file: %v", err) } mpdPath = tempFile.Name() } else if strings.HasPrefix(item.MPD, "https://pubads.g.doubleclick.net") { resp, err := http.Get(item.MPD) if err != nil { return fmt.Errorf("error downloading MPD: %v", err) } defer resp.Body.Close() mpdContent, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("error reading MPD content: %v", err) } fixedMPDContent, err := fixGoPlay(string(mpdContent)) if err != nil { return fmt.Errorf("error fixing MPD content: %v", err) } tempFile, err := os.CreateTemp("", "fixed_mpd_*.mpd") if err != nil { return fmt.Errorf("error creating temporary MPD file: %v", err) } defer os.Remove(tempFile.Name()) if _, err := tempFile.WriteString(fixedMPDContent); err != nil { return fmt.Errorf("error writing to temporary MPD file: %v", err) } if err := tempFile.Close(); err != nil { return fmt.Errorf("error closing temporary MPD file: %v", err) } mpdPath = tempFile.Name() } command := getDownloadCommand(item, mpdPath) if item.Subtitles != "" { subtitlePaths, err := downloadAndConvertSubtitles(item.Subtitles) if err != nil { fmt.Printf("Error processing subtitles: %v\n", err) } else { for _, path := range subtitlePaths { fmt.Println("Adding subtitle:", path) command += fmt.Sprintf(" --mux-import \"path=%s:lang=nl:name=Nederlands\"", path) } } } cmd := exec.Command("bash", "-c", command) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err := cmd.Run() if err != nil { return fmt.Errorf("error executing download command: %v", err) } fmt.Println("Download completed successfully") return nil } func getDownloadCommand(item Item, mpdPath string) string { metadata := parseMetadata(item.Metadata) keys := getKeys(item.Keys) command := fmt.Sprintf("%s %s", config.N_m3u8DLRE.Path, mpdPath) for _, key := range keys { if key != "" { command += fmt.Sprintf(" --key %s", key) } } command += " --auto-select" sanitizedFilename := sanitizeFilename(item.Filename) filename := fmt.Sprintf("\"%s\"", sanitizedFilename) command += fmt.Sprintf(" --save-name %s", filename) command += fmt.Sprintf(" --mux-after-done format=%s", config.Format) saveDir := config.BaseDir if metadata.Type == "serie" { saveDir = filepath.Join(saveDir, "Series", metadata.Title, metadata.Season) } else { saveDir = filepath.Join(saveDir, "Movies", metadata.Title) } command += fmt.Sprintf(" --save-dir \"%s\"", saveDir) fmt.Println(command) return command }