2016-01-23 4 views
1

Je travaille sur une fonction PHP utilisée pour télécharger un fichier .wav au serveur (avec la conversion en mp3 et la création d'image forme d'onde png), et dans la fonction je voudrais comme il faut utiliser soundtouch/soundstrech pour détecter le BPM (Battements par minute). Je sais que ce ne sera pas le plus précis mais pour mes fins ce sera tout ce dont j'ai besoin.Retour shell_exec en tant que chaîne PHP détecter BPM avec soundtouch/soundstrech

j'ai pu obtenir le B.P.M. d'un fichier .wav en utilisant soundtouch/soundstrech avec ffmpeg dans un fichier test.php en utilisant deven's php-bpm-detect wrapper Mais quand je tente de l'intégrer dans ma fonction PHP, il retourne le B.P.M. comme zéro.

Je me demande s'il y a un moyen plus simple d'obtenir le bpm en tant que chaîne de l'exec shell suivante sans avoir à utiliser une bibliothèque php séparée?

Je voudrais faire cela et avoir le retour sous forme de chaîne:

$song_bpm = shell_exec('soundstretch ' . $file_path . ' -bpm'); 

test.php (Cela fonctionne et retourne le bon bpm :)

<?php 
require "class.bpm.php"; 
$wavfile = "38a2819c20.wav"; 
$bpm_detect = new bpm_detect($wavfile); 
$test = $bpm_detect->detectBPM(); 
echo ' bpm of ' . $wavfile . ' is: ' . $test . ' '; 
?> 

PHP Fonction: (bpm retourne à zéro)

function upload_a_sound($user_id, $file_temp, $file_extn, $name, $uploader, $keywords) { 
    $timecode = substr(md5(time()), 0, 10); 
    $mp3name = 'beats/' . $timecode . '.mp3'; 
    $file_path = 'beats/' . $timecode . '.wav'; 
    move_uploaded_file($file_temp, $file_path); 
    shell_exec('ffmpeg -i ' . $file_path . ' -vn -ar 44100 -ac 2 -ab 192k -f mp3 ' . $mp3name . ''); 
    require ('classAudioFile.php'); // This creates a spectogram .png file of .wav 
    $AF = new AudioFile; 
    $AF->loadFile($file_path); 
    $AF->visual_width=200; 
    $AF->visual_height=200; 
    $AF->visual_graph_color="#c491db"; 
    $AF->visual_background_color="#000000"; 
    $AF->visual_grid=false; 
    $AF->visual_border=false; 
    $AF->visual_graph_mode=0; 
    $AF->getVisualization ('images/song/' . $timecode . '.png'); 
    $imageloc = 'images/song/' . $timecode . '.png'; 
    require ('class.bpm.php'); //Deseven's class to get bpm, 
    $bpm_detect = new bpm_detect($file_path); 
    $song_bpm = $bpm_detect->detectBPM(); //when used here this returns 0 
    mysql_query("INSERT INTO `content` VALUES ('', '', '$name', '$uploader', '$keywords', '$file_path', '$imageloc', '$mp3name', '$song_bpm')"); // I will update this to mysqli soon, for now it works 
} 

Je trouve aussi this qui fonctionne, mais pas quand je l'intégrer dans ma fonction:

// create new files, because we don't want to override the old files 
$wavFile = $filename . ".wav"; 
$bpmFile = $filename . ".bpm"; 

//convert to wav file with ffmpeg 
$exec = "ffmpeg -loglevel quiet -i \"" . $filename . "\" -ar 32000 -ac 1 \"" . $wavFile . "\""; 
$output = shell_exec($exec); 

// now execute soundstretch with the newly generated wav file, write the result into a file 
$exec = "soundstretch \"" . $wavFile . "\" -bpm 2> " . $bpmFile; 
shell_exec($exec); 

// read and parse the file 
$output = file_get_contents($bpmFile); 
preg_match_all("!(?:^|(?<=\s))[0-9]*\.?[0-9](?=\s|$)!is", $output, $match); 

// don't forget to delete the new generated files 
unlink($wavFile); 
unlink($bpmFile); 

// here we have the bpm 
echo $match[0][2]; 

Répondre

1

J'ai mis à jour my class il est donc l'appui des chemins absolus et relatifs maintenant.

Et la solution simple:

exec('soundstretch "test.wav" -bpm 2>&1',$average_bpm); 
foreach ($average_bpm as $line) { 
    if (strpos($line,"Detected BPM rate") !== false) { 
     $line = explode(" ",$line); 
     $average_bpm = round($line[3]); 
     break; 
    } 
} 

echo $average_bpm; 

Il suffit de garder à l'esprit que $average_bpm contiendra l'erreur si quelque chose va mal.

+0

Merci deseven! Cela fonctionne très bien! – Jeff