dongsui0929 2015-12-22 20:50
浏览 146
已采纳

PHP:立即返回响应,但在后台运行多个冗长的shell_exec函数

I am creating a simple web service that accepts a video upload, runs multiple different encodes on the video (mp4, webm, ogv), and then uploads the newly created files to our video host.

Let's say I have multiple commands..

shell_exec('ffmpeg -i input.mp4 -f mp4 -c:v libx264 -preset slow -crf 24 -s 1280x720 -c:a libfdk_aac -profile:a aac_he -ar 22050 -b:a 64k -movflags +faststart output-1280x720.mp4');

shell_exec('ffmpeg -i input.mp4 -f mp4 -c:v libx264 -preset slow -crf 24 -s 1920x1080 -c:a libfdk_aac -profile:a aac_he -ar 22050 -b:a 64k -movflags +faststart output-1920x1080.mp4');

shell_exec('ffmpeg -i input.mp4 -f ogg -c:v libtheora -q:v 5 -s 1280x720 -c:a libvorbis -ar 22050 -b:a 64k -movflags +faststart output-1280x720.ogv');

shell_exec('ffmpeg -i input.mp4 -f ogg -c:v libtheora -q:v 5 -s 1920x1080 -c:a libvorbis -ar 22050 -b:a 64k -movflags +faststart output-1920x1080.ogv');

In summary, I want to...

  1. Print an immediate response: {success: true}
  2. Kick off multiple ffmpeg jobs synchronously.
  3. After each job is complete, send a POST to another server (one POST for each shell_exec).

It would also be nice to only send the POST if the job was successful, but I could easily work around that by just checking to see if the output file exists on the server.

I know that I can force shell_exec to run in the background by simply appending >/dev/null 2>/dev/null & to each command -- which would allow me to print a response immediately -- but I think by doing this, this would cause all of the jobs to run in parallel, and also, since this is diverting the output, I do not get any true callbacks when jobs are complete.

Any ideas??

  • 写回答

1条回答 默认 最新

  • duanjun7801 2016-01-15 17:09
    关注

    I decided to go with the idea of requesting the file asynchronously. To keep it clean, I was able to keep it all contained in a single file that "re-calls" itself with a different POST request.

    $root_path = $_SERVER['DOCUMENT_ROOT'] . '/';
    $root_http = 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . $_SERVER['HTTP_HOST'] . '/';
    
    function request_async($url, $params, $type='POST', $timeout=30) {
      foreach ($params as $key => &$val) {
        if (is_array($val)) $val = implode(',', $val);
        $post_params[] = $key.'='.urlencode($val);
      }
      $post_string = implode('&', $post_params);
    
      $parts = parse_url($url);
    
      $fp = fsockopen(
        $parts['host'],
        isset($parts['port']) ? $parts['port'] : 80,
        $errno,
        $errstr,
        $timeout
      );
    
      if ('GET' == $type) $parts['path'] .= '?'.$post_string;
    
      $out = "$type ".$parts['path']." HTTP/1.1
    ";
      $out.= "Host: ".$parts['host']."
    ";
      $out.= "Content-Type: application/x-www-form-urlencoded
    ";
      $out.= "Content-Length: ".strlen($post_string)."
    ";
      $out.= "Connection: Close
    
    ";
    
      if ('POST' == $type && isset($post_string)) $out .= $post_string;
    
      fwrite($fp, $out);
      fclose($fp);
    }
    
    function get_http_path($path, $relative = FALSE){
      global $root_http, $root_path;
      return str_replace($root_path, $relative ? '/' : $root_http, $path);
    }
    
    $url = $_POST['url'];
    $media = $_POST['media'];
    
    if (isset($url)) {
      request_async(get_http_path(__FILE__), array(media => $url), 'POST', 1800);
      echo '{"success": true}';
    } else
    if (isset($media)) {
      $data = file_get_contents($media);
      // KICK OFF JOBS HERE
      echo '{"success": true}';
    } else {
      echo '{"success": false}';
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘