【问题标题】:Returning shell_exec as string PHP detecting BPM with soundtouch/soundstrech返回 shell_exec 作为字符串 PHP 使用 soundtouch/soundstrech 检测 BPM
【发布时间】:2016-01-23 00:15:32
【问题描述】:

我正在开发一个 php 函数,用于将 .wav 上传到服务器 (以及转换为 mp3 并创建波形图像 png),并且在函数中我希望它使用 @987654321 @ 检测 B.P.M. (每分钟节拍)。我知道这不会是最准确的,但就我的目的而言,这将是我所需要的。

我能够获得 B.P.M.使用soundtouch / soundstrech 的.wav 文件以及使用deven's php-bpm-detect wrapper 的test.php 文件中的ffmpeg 但是当我尝试将它集成到我的PHP 函数中时,它会返回B.P.M.为零。

我想知道是否有一种更简单的方法可以将 bpm 作为字符串从以下 shell exec 中获取,而无需使用单独的 php 库?

我想执行此操作并将其作为字符串返回:

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

test.php(这可以正常工作并返回正确的 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 函数:(将 bpm 返回为零)

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
}

我还发现 this 可以工作,但当我将它集成到我的函数中时却不行:

// 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];

【问题讨论】:

    标签: php string ffmpeg shell-exec


    【解决方案1】:

    我已经更新了my class,所以它现在支持绝对和相对路径。

    以及直接的解决方案:

    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;
    

    请记住,如果出现任何问题,$average_bpm 将包含错误。

    【讨论】:

      猜你喜欢
      • 2014-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-27
      • 1970-01-01
      • 2018-11-18
      • 2019-07-11
      相关资源
      最近更新 更多