在 php 的目录中查找特定文件类型,并在转换后将其发送到不同的目录
look for a specific filetype in a directory in php and send it to a different directory after conversion
我有一个目录,其中有一个 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 文件并将其发送到 different转换为 mp3 后的目录(比如 out_folder)。
我想要的图示:
认为这就是你想要的:
<?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
//
}
}
文档system
或者第一个循环也转换 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
//
}
break;
case 'mp3' :
// copy($f, $destination. DS . $parts['filename']. '.' . $parts['extension']);
rename($f, $destination.DS.$parts['filename'].'.mp3');
break;
}
}
编辑 1:
更正 strtolower($parts['extension'])
检查文件的扩展名 none case-sensitive.
或者像这样:
strtolower(pathinfo("/path/file.mP4", PATHINFO_EXTENSION)) == ".mp4"
不需要使用 preg_match
和 regexp
因为 pathinfo
是一个 pre-made 函数来完成这项工作并且它工作正常除非你使用双命名扩展例如 .tar.gz
。
regular-expression-to-detect-a-file-extension
编辑 2:使用 rename
而不是 copy
来移动 mp3。
我觉得这一切都可以更健壮和更短。
<?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");
}
您应该注意不允许 'user specified' 文件名,而是使用您自己的(随机)文件名。不惜一切代价避免执行未经验证的用户输入!
这样就可以了。我测试了解决方案并且它有效。我不得不为 ffmpeg 命令更改一个参数。在我的机器上,它抛出了映射错误。我在映射后添加了一个问号以忽略该错误。
代码采用以下文件夹结构:
<?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);
}
}
?>
我有一个目录,其中有一个 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 文件并将其发送到 different转换为 mp3 后的目录(比如 out_folder)。
我想要的图示:
认为这就是你想要的:
<?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
//
}
}
文档system
或者第一个循环也转换 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
//
}
break;
case 'mp3' :
// copy($f, $destination. DS . $parts['filename']. '.' . $parts['extension']);
rename($f, $destination.DS.$parts['filename'].'.mp3');
break;
}
}
编辑 1:
更正 strtolower($parts['extension'])
检查文件的扩展名 none case-sensitive.
或者像这样:
strtolower(pathinfo("/path/file.mP4", PATHINFO_EXTENSION)) == ".mp4"
不需要使用 preg_match
和 regexp
因为 pathinfo
是一个 pre-made 函数来完成这项工作并且它工作正常除非你使用双命名扩展例如 .tar.gz
。
regular-expression-to-detect-a-file-extension
编辑 2:使用 rename
而不是 copy
来移动 mp3。
我觉得这一切都可以更健壮和更短。
<?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");
}
您应该注意不允许 'user specified' 文件名,而是使用您自己的(随机)文件名。不惜一切代价避免执行未经验证的用户输入!
这样就可以了。我测试了解决方案并且它有效。我不得不为 ffmpeg 命令更改一个参数。在我的机器上,它抛出了映射错误。我在映射后添加了一个问号以忽略该错误。
代码采用以下文件夹结构:
<?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);
}
}
?>