Files
rolandradio_record/stream_cut.go
Mac Call e53fb1b54f initial
2023-03-05 15:06:10 +01:00

145 lines
3.8 KiB
Go

package main
import (
"bufio"
"errors"
"fmt"
"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 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", err)
panic(err)
}
defer f.Close()
// créer un tampon pour stocker les octets lus
tampon := make([]byte, octetsFin-octetDebut)
// lire les octets spécifiés à partir de la position spécifiée
n, err := f.ReadAt(tampon, int64(octetDebut))
if err != nil {
fmt.Fprintf(os.Stderr, "Erreur de lecture du fichier mp3 de %d a %d soit %d octets: %v", 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)
err = os.WriteFile(outputFile, tampon, 0644)
if err != nil {
fmt.Fprintf(os.Stderr, "Erreur d'écriture du fichier mp3 du morceau: %v", 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", 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", 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", err)
panic(err)
}
}