监控视频片段合并完整视频|FFmpeg将多个视频片段拼接完整视频|PHP自动批量拼接合并视频

news/2024/7/10 18:42:21 标签: 音视频, ffmpeg, php

关于环境配置ffmpeg安装使用的看之前文章 哔哩哔哩缓存转码|FFmpeg将m4s文件转为mp4|PHP自动批量转码B站视频

php"><?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);
    }
}

// 删除指定文件
function deleteFile($filename)
{
    // 检查文件是否存在
    if (file_exists($filename)) {
        // 尝试删除文件
        if (unlink($filename)) {
            return null;
        } else {
            return "文件删除失败";
        }
    } else {
        return "文件不存在";
    }
}

/**
 * 操作文件夹
 * 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];
}

// 命令参数字段映射
$cmdFiledMap = array(
    'P' => 'path',
    'D' => 'debug',
    'H' => 'help',
);
// 命令行参数变量
$console = array();
if (preg_match_all('/--(\w+)(=(.*?)(?=\s--|$))?/u', implode(' ', array_slice($_SERVER['argv']/*获取命令行参数的完整字符串*/, 1)), $matches)) {
    $console = [];
    for ($i = 0; $i < count($matches[0]); $i++) {
        $key = $matches[1][$i];
        $value = $matches[3][$i];
        $console[$key] = $value;
    }
    foreach ($cmdFiledMap as $key => $item) {
        if (isset($console[$key])) {
            if (empty($console[$item]) && !empty($console[$key])) {
                $console[$item] = $console[$key];
            }
            unset($console[$key]);
        }
    }
}
// 判断是否要获取使用方法
if (empty($console) || isset($console['help']) || empty($console['path'])) {
    $errMsg = array(
        'help:',
        '  as => php index.php --path=your_resource_path --debug=0',
        'OR',
        '  as => php index.php --F=your_resource_path --D=1',
        '',
        '',
    );
    die(implode(PHP_EOL . PHP_EOL, $errMsg));
}

$outputDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . $console['path'] . 'Mp4';
do_rmdir($outputDir, true);
mkdirs($outputDir);
$isDebug = !empty($console['debug']);

$list = getDir($console['path'], false);
if (empty($list)) {
    die(PHP_EOL . '空文件夹。。。');
}
$startTime = time();
foreach ($list as $key => $item) {
    $itemDirName = basename($item); // 目录名
    $fileList = getDirFile($item);
    $listText = array();
    foreach ($fileList as $keyx => $itemx) {
        $itemxInfo = pathinfo($itemx);
        $midifyTime = filemtime($itemx); // 最后一次修改时间

        $ext = $itemxInfo['extension'];
        if ($ext == 'mp4') {
            $listText[$midifyTime] = "file '" . basename($itemx) . "'";
        }
    }
    ksort($listText);
    $listTextPath = $item . DIRECTORY_SEPARATOR . 'list.txt';
    file_put_contents($listTextPath, implode(PHP_EOL, $listText));
    $outputFileName = $outputDir . DIRECTORY_SEPARATOR . $itemDirName . '.mp4';
    $cmd = "ffmpeg " . ($isDebug ? "" : "-loglevel quiet") . " -f concat -safe 0 -i {$listTextPath} -c copy {$outputFileName}";
    echo $cmd . PHP_EOL;
    shell_exec($cmd); // cmd可执行
    // 删除list.txt 临时文件
    deleteFile($listTextPath);
}

echo PHP_EOL . '处理完成, 耗时:' . (time() - $startTime) . '秒';


http://www.niftyadmin.cn/n/5173535.html

相关文章

安卓常见设计模式14------单例模式(Kotlin版)

1. W1 是什么&#xff0c;什么是单例模式&#xff1f;​ 单例模式属于创建型模式&#xff0c;旨在确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取该实例。单例模式的核心思想是限制类的实例化&#xff0c;使得系统中只有一个共享的实例。 2. W2 为什么&#…

【自动驾驶】初学者播包与可视化工具学习记录

对于本地进行结果复现或者是功能验证等&#xff0c;需要实车录制数据包ros2&#xff0c;本地播包ros2/plotjuggler&#xff0c;最后结果可视化rviz2。 所以对于初学者&#xff0c;至少要学习ros2相关操作&#xff0c;可以让你进入职场后更好的适应。本文主要针对上面三个步骤进…

人工智能领域200例教程专栏—学习人工智能的指南宝典

&#x1f389;&#x1f38a;&#x1f389; 你的技术旅程将在这里启航&#xff01; &#x1f680; 本专栏&#xff1a;人工智能领域200例教程专栏 从基础到实践&#xff0c;深入学习。无论你是初学者还是经验丰富的老手&#xff0c;对于本专栏案例和项目实践都有参考学习意义。 …

md文件快速将图片链接持久化到本地链接

修改图片网站域名前缀即可运行 注意&#xff1a; 所有图片放到images目录下所有修改后的md文件放到mdfile目录下把mdfile文件下的md文件拖出到和images同目录下&#xff0c;即可完成操作(因为md文件中图片路径为./images/aaa.jpg) import os import requests from urllib.pa…

UnRaid安装安装仓库管理系统GreaterWMS

文章目录 0、前言1、安装流程1.1、克隆GreaterWMS项目到UnRaid本地目录1.2、修改项目前后端端口1.3、修改baseurl1.4、修改Nginx.conf配置文件1.5、安装依赖插件1.5.1、Docker Compose Manager插件1.5.2、Python3环境 1.6、创建GreaterWMS容器1.6.1、为前后端启动脚本赋执行权限…

从虚拟机下载开始的kubeSphere安装

目录 一、虚拟机安装 二、镜像下载安装 1、镜像下载 2、虚拟机创建 3、虚拟机系统安装 三、虚拟机配置 1、IP固定 2、配置yum阿里源 3、关闭防火墙 4、 关闭selinux 5、 禁止swap交换 6、内核参数修改 7、设置kubernetes源 四、docker安装 五、虚拟机分组 六、…

2023亚太杯数学建模A题思路

文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料5 最后 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 2023年第十三…

配置交换机将Log发送到日志服务器

文章目录 一、配置说明二、配置步骤推荐阅读 一、配置说明 配置将实现如下&#xff1a; 配置交换机将Log发送到日志服务器。 将信息等级高于等于 debug 的日志信息将会发送到日志服务器上。 允许输出日志信息的模块为default所有应用模块日志信息。 SW1为我们日志源交换机…