найдите определенный тип файла в каталоге в php и отправьте его в другой каталог после преобразования - PullRequest
3 голосов
/ 12 мая 2019

У меня есть каталог, в котором есть mp4 файл (включая другие файлы), который я хочу преобразовать в mp3 и затем отправить его в другой каталог.Я использовал следующую команду командной строки для конвертации в mp3, и она прекрасно работает.

ffmpeg -i 36031P.mp4 -map 0:2 -ac 1 floor_english.mp3 

mp4 файл находится внутри in_folder .Используя ffmpeg, я хочу преобразовать файл mp4 в mp3 и отправить его в out_folder .

<?php
$dir    = 'in_folder';
$files1 = scandir($dir);
print_r($files1);    /* It lists all the files in a directory including mp4 file*/
?>

print_r ($ files1) выводит список всех файлов в каталоге, включая mp4file.

Описание проблемы:

Мне интересно, какой php-код мне нужно написать, чтобы он искал только mp4 файл в каталоге и отправлял его в другой каталог (скажем, out_folder) после преобразования в mp3.

графическое представление того, что я хочу:

enter image description here

Ответы [ 3 ]

4 голосов
/ 12 мая 2019

В мысли, это то, что вы хотите:

<?php
$dir    = 'in_folder';
$files1 = scandir($dir);
print_r($files1);    /* It lists all the files in a directory including mp4 file*/

$destination = 'your new destination';

foreach($files1 as $f)
{
  $parts = pathinfo($f);
  if ($parts['extension'] = 'mp3';
  {
    // copy($f, $destination. DS . $parts['filename']. '.' . $parts['extension']);
    rename($f, $destination. DS . $parts['filename']. '.mp3');
  }
}
?>

Документация pathinfo

Редактировать с преобразованием:

Я думаю, что вы можете напрямую экспортировать свой mp3, как это

foreach($files1 as $f)
{
  $parts = pathinfo($f);
  if ($parts['extension'] = 'mp4';
  {
    // $result : the last line of the command output on success, and FALSE on failure. Optional.
    system('ffmpeg -i '.$f.' -map 0:2 -ac 1 '.$destination.DS. $parts['filename'].'.mp3', $result);
  }

  // See: https://www.php.net/manual/en/function.system.php
  if ($result === false) {
    // Do something if failed
    // log for example
  } else {
    // command completed with code : $result
    // 0 by convention for exit with success EXIT_SUCCESS
    // 1 by convention for exit with error EXIT_ERROR
    // https://stackoverflow.com/questions/12199216/how-to-tell-if-ffmpeg-errored-or-not
  }
}

Документация Система

или первый цикл тоже конвертируйте в mp4, а второй цикл для копирования mp3

Редактировать все в одном:

foreach($files1 as $f)
{
  $parts = pathinfo($f);

  switch(strtolower($parts['extension']))
  {
    case 'mp4' :
      // $result : the last line of the command output on success, and FALSE on failure. Optional.
      system('ffmpeg -i '.$f.' -map 0:2 -ac 1 '.$destination.DS. $parts['filename'].'.mp3', $result);

      // See: https://www.php.net/manual/en/function.system.php
      if ($result === false) {
        // Do something if failed
        // log for example
      } else {
        // command completed with code : $result
        // 0 by convention for exit with success EXIT_SUCCESS
        // 1 by convention for exit with error EXIT_ERROR
        // https://stackoverflow.com/questions/12199216/how-to-tell-if-ffmpeg-errored-or-not
      }
      break;

    case 'mp3' :
      // copy($f, $destination. DS . $parts['filename']. '.' . $parts['extension']);
      rename($f, $destination.DS.$parts['filename'].'.mp3');
      break;  
  }
}

Редактировать 1 : исправление strtolower($parts['extension']) для проверки расширения файла без учета регистра.

или как это:

strtolower(pathinfo("/path/file.mP4", PATHINFO_EXTENSION)) == ".mp4"

Нет необходимости использовать preg_match и regexp, потому что pathinfo - это готовая функция для выполнения работы, и она прекрасно работает, если вы не используете расширение с двойным именем, например .tar.gz.

регулярное выражение к детектировать-а-расширение файла

Редактировать 2 : используйте rename вместо copy для перемещения mp3.

2 голосов
/ 14 мая 2019

Это сделает это.Я проверил решение, и оно работает.Мне пришлось сделать одно изменение параметра для команды ffmpeg.На моей машине это выкидывало ошибку для отображения.Я добавил вопросительный знак после сопоставления, чтобы игнорировать ошибку.

Код принимает следующую структуру папок: enter image description here

<?php

  error_reporting(E_ALL);

  $in_folder = sprintf("%s/mp4", __DIR__);
  $out_folder = sprintf("%s/mp3", __DIR__);

  if(!file_exists($in_folder)){
    mkdir($in_folder);
  }

  if(!file_exists($out_folder)){
    mkdir($out_folder);
  }

  $items = scandir($in_folder);
  foreach($items as $item){
    if(preg_match('/^.*\.mp4$/', $item)){
      $file_name = str_replace(".mp4", "", $item);
      $in_file = sprintf("%s/%s.mp4", $in_folder, $file_name);
      $out_file = sprintf("%s/%s.mp4", $out_folder, $file_name);
      if(file_exists($out_file)){
        unlink($out_file);
      }
      $cmd = sprintf("ffmpeg -i %s -map 0:2? -ac 1 %s", $in_file, $out_file);
      print "$cmd\n";
      exec($cmd);
    }
  }

?>
2 голосов
/ 14 мая 2019

Я чувствую, что все это может быть немного крепче и короче.

<?php

// the folder to get MP4's from, recursively
$src_dir = 'folder/a';
// the destination to put MP3's in.
$dst_dir = 'folder/b';

// An iterator ('reader') that takes all files in src
$files = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($src_dir)
);

// A filter, that only leaves entries ending with .mp4, case-insensitive.
$videos = new RegexIterator($files, '/^.+\.mp4$/i', RecursiveRegexIterator::MATCH));

// Then, for each element in videos, convert to MP3
foreach ($videos as $video) {
    $src = $video->getPathname();
    // The destination is the basename without 'mp4', with 'mp3' appended.
    $dst = $dst_dir.'/'.$video->getBaseName($video->getExtension()).'mp3';

    system("ffmpeg -i $src -map 0:2 -ac 1 $dst");
}

Вы должны позаботиться о том, чтобы вы не разрешали имена, указанные пользователем, а использовали собственные (случайные) имена файлов.Избегайте выполнения неподтвержденного пользовательского ввода любой ценой!

...