window download and install FFmpeg
- Open ffMpeg official website
- Select window=>Windows builds from gyan.dev
- Open https://www.gyan.dev/ffmpeg/builds/
- Here is the download link extracted above. If it expires and cannot be used, go to the official website yourself.
Configure FFmpeg environment variables
The FFmpeg downloaded above is green software. Just download and unzip it to your common software installation directory, then enter the bin and copy the system environment variables under the full path configuration.
Terminal command processing
# 常规命令
ffmpeg -i video.m4s -i audio.m4s -codec copy video.mp4
# 屏蔽输出日志
ffmpeg -loglevel quiet -i video.m4s -i audio.m4s -codec copy video.mp4
Call FFmpeg using PHP
- https://github.com/PHP-FFMpeg/PHP-FFMpeg/
<?php
// require 'vendor/autoload.php';
// $ffmpeg = FFMpeg\FFMpeg::create();
// $oldAudio = $ffmpeg->open('./assets/32.amr');
// $newAudio = new FFMpeg\Format\Audio\Mp3();
// $newAudio->setAudioKiloBitrate(8); // 设置音频比特
// $oldAudio->save($newAudio, './assets/32.mp3');
// shell_exec("ffmpeg -i 32.amr b.mp3"); // cmd可执行
/* http请求可执行 */
// $file = './src/32.amr';
// $outFile = './src/b.mp3';
// $handle = popen("ffmpeg -i $file $outFile", 'w');
// pclose($handle);
// $filePath = './src/32.amr';
// $filePath_mp = './src/b.mp3';
// echo "ffmpeg -i $filePath $filePath_mp";
// $handle = popen("ffmpeg -i $filePath $filePath_mp", 'w');
// pclose($handle);
shell_exec("ffmpeg -i video.m4s -i audio.m4s -codec copy video.mp4"); // cmd可执行
- batch processing program
<?php
date_default_timezone_set("PRC");
header("Content-type: text/html; charset=utf-8");
set_time_limit(0);
// 遍历获取文件
function getDirFile($path = null, $deep = true) {
if (empty($path)) {
return [];
}
$files = scandir($path);
$fileItem = [];
foreach($files as $v) {
$newPath = $path .DIRECTORY_SEPARATOR.$v;
if($deep && is_dir($newPath) && $v != '.' && $v != '..') {
if (is_numeric($deep)) {
$deep--;
}
$fileItem = array_merge($fileItem, getDirFile($newPath, $deep));
}else if(is_file($newPath)){
$fileItem[] = $newPath;
}
}
return $fileItem;
}
// 遍历获取文件夹
function getDir($path = null, $deep = true) {
if (empty($path)) {
return [];
}
$files = scandir($path);
$dirList = [];
foreach($files as $v) {
$newPath = $path .DIRECTORY_SEPARATOR.$v;
if (is_dir($newPath) && $v != '.' && $v != '..') {
$dirList[] = $newPath;
if ($deep) {
if (is_numeric($deep)) {
$deep--;
}
$dirList = array_merge($dirList, getDir($newPath, $deep));
}
}
}
return $dirList;
}
//判断文件夹是否存在,没有则新建。
if (!function_exists('mkdirs')) {
function mkdirs($dir, $mode = 0777)
{
if (is_dir($dir) || @mkdir($dir, $mode)) {
return true;
}
if (!mkdirs(dirname($dir), $mode)) {
return false;
}
return @mkdir($dir, $mode);
}
}
/**
* 操作文件夹
* addtime 2020年7月17日
* @param [type] $dirname 文件夹路径
* @param boolean $self 是否删除文件夹本身[true是 false否] 具体看需求
* @return void
*/
function do_rmdir($dirname, $self = false)
{
# 检查文件或目录是否存在
if (!file_exists($dirname)) {
return false;
}
# 是文件进行删除
if (is_file($dirname) || is_link($dirname)) {
return unlink($dirname);
}
# 开始读取目录
$dir = dir($dirname);
if ($dir) {
while (false !== $entry = $dir->read()) {
if ($entry == '.' || $entry == '..') {
continue;
}
# 进行文件删除
do_rmdir($dirname . '/' . $entry);
}
}
# 关闭目录
$dir->close();
# 是否删除本身文件夹
$self && rmdir($dirname);
# 成功返回
return ['code' => 200];
}
$inputParams = getopt('d:s:'); // 接收-d参数
if (empty($inputParams['d']) || !file_exists($inputParams['d'])) {
die(PHP_EOL.'请输入正确的B站视频文件目录');
}
// $isNo = empty($inputParams['s'])?false: true;
// print_r($inputParams);
// die();
$inputDir = $inputParams['d'];
$outputDir = dirname(__FILE__).DIRECTORY_SEPARATOR. $inputDir.'Mp4';
do_rmdir($outputDir, true);
mkdirs($outputDir);
$isDebug = false;
$list = getDir($inputDir, false);
if (empty($list)) {
die(PHP_EOL.'空文件夹。。。');
}
$i = 0;
foreach ($list as $key => $item) {
$entryJson = $item. DIRECTORY_SEPARATOR . 'entry.json';
$audio = $item. DIRECTORY_SEPARATOR . '80' . DIRECTORY_SEPARATOR . 'audio.m4s';
$video = $item. DIRECTORY_SEPARATOR . '80' . DIRECTORY_SEPARATOR . 'video.m4s';
if (file_exists($entryJson) && file_exists($audio) && file_exists($video)) {
$entryJsonText = file_get_contents($item. DIRECTORY_SEPARATOR . 'entry.json');
if (!empty($entryJsonText)) {
$entryJsonText = json_decode($entryJsonText, true);
$fileName = $entryJsonText['page_data']['part'];
// $fileName = explode($separator, $fileName, 2);
// $fileName[0] = str_pad($fileName[0], 3, '0', STR_PAD_LEFT );
// $fileName = implode('.', $fileName);
// 替换中文括号
$fileName = str_replace('(', '(', $fileName);
$fileName = str_replace(')', ')', $fileName);
// 替换文件名不能含有的符号? \ / : | * "
$fileName = str_replace('\\', '_{_', $fileName);
$fileName = str_replace('/', '_}_', $fileName);
$fileName = str_replace(':', ':', $fileName);
$fileName = str_replace('*', '_ALL_', $fileName);
$fileName = str_replace('<', '《', $fileName);
$fileName = str_replace('>', '》', $fileName);
$fileName = str_replace('|', '_OR_', $fileName);
// 是否开启编号
$No = str_pad($entryJsonText['page_data']['page'], 3, '0', STR_PAD_LEFT );
$cmdFileName = $outputDir . DIRECTORY_SEPARATOR . $No . '.mp4';
$fileName = $outputDir . DIRECTORY_SEPARATOR . $No. '.' . $fileName . '.mp4';
$cmd = "ffmpeg ".($isDebug? "": "-loglevel quiet")." -i {
$audio} -i {
$video} -codec copy {
$cmdFileName}";
shell_exec($cmd); // cmd可执行
// 重命名
rename($cmdFileName, $fileName);
print_r([
'index' => $i++,
'path' => $item,
'fileName' => $fileName,
'cmd' => $cmd,
]);
}
}
}
echo PHP_EOL;
print_r(array(
'总计文件' => count($list),
'完成文件' => $i,
));
- run script
php index.php -d 目录名