package main import ( "bufio" "errors" "fmt" "io" "os" "strconv" "strings" ) const delaiDebut float64 = 2.00 //secondes const delaiFin float64 = 0.20 //secondes /* transforme la chaine de temps en ms * format d'entrée : une chaine au format hh:mm:ss.ms (pas d'obligation d'avoir des heurs ou minutes ) */ func strTimeToS(strTime string) (float64, error) { tabTime := strings.Split(strTime, ":") var ( timeMultiplicateur int = 1 time float64 ) for i := len(tabTime) - 1; i >= 0; i-- { timeVal, err := strconv.ParseFloat(tabTime[i], 64) if err != nil { return 0, errors.New("format invalide, nombre incorrect") } time += float64(timeMultiplicateur) * timeVal timeMultiplicateur *= 60 } return time, nil } func GetInfo(ligne string) (float64, string, string, error) { //split la ligne en 2 sur le premier espace tabInfo := strings.SplitN(ligne, " ", 2) strTime, strTitre := tabInfo[0], tabInfo[1] debTime, err := strTimeToS(strTime) if err != nil { return 0, "", "", err } //split tmpTitre en artiste + titre en séparant par " - " split := strings.SplitN(strTitre, " - ", 2) var artiste, titre string if len(split) > 1 { artiste, titre = split[0], split[1] } else { titre = split[0] } return debTime, artiste, titre, nil } // on suppose un flux a 128kb/s soit 128000/8 kB/s func timerToBytes(timer float64) int64 { return int64(128000. / 8. * timer) } func isWriteMp3(filename string, newSize int64) bool { fileInfo, err := os.Stat(filename) // si le fichier n'existe pasn on peut ecrire le mp3 if os.IsNotExist(err) { return true } // si le fichier existant est plus petit que le fichier qu'on souhaite créer, on l'ecrase fileSize := fileInfo.Size() return fileSize < newSize } func cutAndSave(mp3File string, timerDebut float64, timerFin float64, artiste string, titre string) { octetDebut := timerToBytes(timerDebut) octetsFin := timerToBytes(timerFin) //fmt.Printf("je coupe le fichier %s de %v a %v le mp3 de %s s'apellant %s \n", mp3File, timerDebut, timerFin, artiste, titre) // ouvrir le fichier f, err := os.Open(mp3File) if err != nil { fmt.Fprintf(os.Stderr, "Erreur d'ouverture du fichier mp3 : %v\n", err) panic(err) } defer f.Close() bufferSize := octetsFin - octetDebut // créer un tampon pour stocker les octets lus tampon := make([]byte, bufferSize) // lire les octets spécifiés à partir de la position spécifiée n, err := f.ReadAt(tampon, int64(octetDebut)) // en cas d'erreur EOF, on continue comme si de rien n'était (il est possible qu'on tente //d'accedeer un pu plus loin que la fin du fichier avec le delaiFin, ce n'est pas grave ça passera la fois d'apres ) if err != nil && !errors.Is(err, io.EOF) { fmt.Fprintf(os.Stderr, "Erreur de lecture du fichier mp3 de %d a %d soit %d octets: %v\n", octetDebut, octetsFin, n, err) panic(err) } // Écriture du tableau d'octets dans un fichier artiste = strings.ReplaceAll(artiste, "/", "_") if artiste == "" { artiste = "Inconnu" } titre = strings.ReplaceAll(titre, "/", "_") var outputFile string = fmt.Sprintf("%s.__.%s.mp3", artiste, titre) if isWriteMp3(outputFile, bufferSize) { err = os.WriteFile(outputFile, tampon, 0644) if err != nil { fmt.Fprintf(os.Stderr, "Erreur d'écriture du fichier mp3 du morceau: %v\n", err) panic(err) } } } func Cut(mp3File string, indexFile string) { // Ouvrir le fichier index en lecture fichier, err := os.Open(indexFile) if err != nil { fmt.Fprintf(os.Stderr, "Erreur d'ouverture du fichier index : %v\n", err) panic(err) } defer fichier.Close() // Créer un scanner pour lire le fichier ligne par ligne scanner := bufio.NewScanner(fichier) // Parcourir chaque ligne du fichier timerPrecedent := -1. artistePrecedent := "" titrePrecedent := "" for scanner.Scan() { // Faire quelque chose avec la ligne, par exemple : ligne := scanner.Text() timer, artiste, titre, err := GetInfo(ligne) if err != nil { fmt.Fprintf(os.Stderr, "Erreur de récupération des infos de la ligne %s : %v\n", ligne, err) panic(err) } if timerPrecedent != -1. { cutAndSave(mp3File, timerPrecedent-delaiDebut, timer+delaiFin, artistePrecedent, titrePrecedent) timerPrecedent = timer } else { timerPrecedent = 0. + delaiDebut } artistePrecedent = artiste titrePrecedent = titre } // Vérifier s'il y a eu une erreur lors de la lecture du fichier if err := scanner.Err(); err != nil { fmt.Fprintf(os.Stderr, "Erreur de lecture du fichier index : %v\n", err) panic(err) } }