&1", $output, $return_code); // Vérifier s'il y a eu une erreur lors de l'exécution de la commande if ($return_code !== 0) { // Enregistrer l'erreur dans un fichier journal par exemple error_log("Erreur lors du calcul du fingerprint pour le fichier \"$file_bash\" : " . implode("\n", $output)); return null; // Retourner null pour indiquer une erreur } // Traitement de la réponse $result = json_decode(implode('', $output), true); // Vérifier si le résultat est valide if (isset($result['fingerprint'])) { return $result['fingerprint']; // Retourner le fingerprint } else { // Enregistrer un message d'erreur dans le journal error_log("Réponse invalide lors du calcul du fingerprint pour le fichier $file : " . implode("\n", $output)); return null; // Retourner null en cas de réponse invalide } } function getTagValue($metadataInFile, $tagKey) { // Vérifier si la clé existe dans le tableau et retourner sa valeur si c'est le cas if (isset($metadataInFile['streams'][0]['tags'][$tagKey])) { return $metadataInFile['streams'][0]['tags'][$tagKey]; } else { // Retourner null si la clé n'existe pas return null; } } // Fonction pour extraire les métadonnées d'un fichier audio function extract_metadata($file) { # Extraire les métadonnées avec ffprobe $ffprobe_output = shell_exec("ffprobe -hide_banner -loglevel fatal -show_error -show_format -show_streams -print_format json \"$file\""); // Décoder la sortie JSON $metadataInFile = json_decode($ffprobe_output, true); // Vérifier si les métadonnées contiennent les tags if (isset($metadataInFile['streams'][0]['tags'])) { // Extraire les metadonnées $metadata['ARTIST'] = getTagValue($metadataInFile, 'ARTIST'); $metadata['TITLE'] = getTagValue($metadataInFile, 'TITLE'); $metadata['ALBUM'] = getTagValue($metadataInFile, 'ALBUM'); $metadata['ACOUSTID'] = getTagValue($metadataInFile, 'ACOUSTID_ID'); $metadata['duration'] = isset($metadataInFile['format']['duration']) ? (float)$metadataInFile['format']['duration'] : null; } if (isset($metadata)) { return $metadata; } else { return null; } } // Vérifier si le nombre de paramètres est correct if ($argc != 3) { die("Usage: php scan_files.php \n"); } $directory = $argv[1]; $db_file = $argv[2]; // Vérifier si le dossier existe if (!is_dir($directory)) { die("Le dossier spécifié n'existe pas.\n"); } // Vérifier si la base de données existe, sinon la créer if (!file_exists($db_file)) { echo "La base de données n'existe pas. Création en cours...\n"; $db = new PDO("sqlite:$db_file"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Créer les tables $db->exec("CREATE TABLE IF NOT EXISTS files ( id INTEGER PRIMARY KEY, file_path TEXT UNIQUE, first_referenced DATETIME, last_updated DATETIME )"); $db->exec("CREATE TABLE IF NOT EXISTS fingerprints ( id INTEGER PRIMARY KEY, file_id INTEGER UNIQUE, fingerprint TEXT, FOREIGN KEY (file_id) REFERENCES files(id) )"); $db->exec("CREATE TABLE IF NOT EXISTS metadata ( file_id INTEGER PRIMARY KEY, artist TEXT, title TEXT, album TEXT, duration REAL, acoustid TEXT, FOREIGN KEY (file_id) REFERENCES files(id) )"); // Création de la table system_info si elle n'existe pas déjà $db->exec("CREATE TABLE IF NOT EXISTS system_info ( id INTEGER PRIMARY KEY, version INTEGER NOT NULL )"); // Insertion des données de version $version = "1"; $insert_version_sql = "INSERT INTO system_info (version) VALUES (:version)"; $stmt = $db->prepare($insert_version_sql); $stmt->bindParam(':version', $version, PDO::PARAM_STR); $stmt->execute(); echo "Base de données créée avec succès.\n"; } else { // Connexion à la base de données SQLite $db = new PDO("sqlite:$db_file"); } // Préparation de la requête d'insertion des fichiers $insert_file_stmt = $db->prepare("INSERT INTO files (file_path, first_referenced, last_updated) VALUES (:file_path, DATETIME('now'), DATETIME('now'))"); // Préparer la requête SQL d'insertion ou de mise à jour des empreintes digitales $insert_fingerprint_sql = "INSERT INTO fingerprints (file_id, fingerprint) VALUES (:file_id, :fingerprint) ON CONFLICT(file_id) DO UPDATE SET fingerprint = :fingerprint"; $insert_fingerprint_stmt = $db->prepare($insert_fingerprint_sql); // Préparer la requête SQL d'insertion ou de mise à jour des métadonnées $insert_metadata_sql = "INSERT INTO metadata (file_id, artist, title, album, acoustid, duration) VALUES (:file_id, :artist, :title, :album, :acoustid, :duration) ON CONFLICT(file_id) DO UPDATE SET artist = :artist, title = :title, album = :album, acoustid = :acoustid, duration = :duration"; $insert_metadata_stmt = $db->prepare($insert_metadata_sql); $count = 0; // Initialisation du compteur // Parcourir les fichiers audio $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)); foreach ($iterator as $file) { $file_bash = escapeshellarg($file); if ($file->isFile() && in_array($file->getExtension(), ['mp3', 'opus', 'ogg', 'm4a'])) { if ($count % 10 == 0) { echo "\rProgress: $count files processed\n"; } $file_path = $file->getPathname(); // Vérifier si le fichier existe déjà dans la base de données $result = $db->query("SELECT id FROM files WHERE file_path = " . $db->quote($file_path)); $file_id = $result->fetchColumn(); if (!$file_id) { // Insérer le fichier dans la base de données $insert_file_stmt->execute([':file_path' => $file_path]); $file_id = $db->lastInsertId(); // Calculer le fingerprint du fichier // $fingerprint = calculate_fingerprint($file_path); // Insérer le fingerprint dans la base de données // $insert_fingerprint_stmt->execute([':file_id' => $file_id, ':fingerprint' => $fingerprint]); } else { // Mettre à jour la date de dernière mise à jour du fichier $db->exec("UPDATE files SET last_updated = DATETIME('now') WHERE id = $file_id"); } // Extraire les métadonnées du fichier audio $metadata = extract_metadata($file_path); // Insérer les métadonnées dans la base de données $insert_metadata_stmt->execute([ ':file_id' => $file_id, ':artist' => isset($metadata['ARTIST']) ? $metadata['ARTIST'] : null, ':title' => isset($metadata['TITLE']) ? $metadata['TITLE'] : null, ':album' => isset($metadata['ALBUM']) ? $metadata['ALBUM'] : null, ':acoustid' => isset($metadata['ACOUSTID']) ? $metadata['ACOUSTID'] : null, ':duration' => isset($metadata['duration']) ? (int)$metadata['duration'] : null ]); $count++; } } // Fermer la connexion à la base de données $db = null; echo "Terminé.\n"; ?>