Skip to content
网游世界
网游世界

吾生有涯,而知无涯。

  • 首页
  • PHP
    • ThinkPHP
    • FastAdmin
    • webman
  • JavaScript
    • jQuery
    • AdminLTE
  • Free Pascal
  • Java
    • JeeSite
    • 若依
    • ruoyi-vue-pro
  • 其它
    • 操作系统
    • 树莓派
    • 前端
    • Null
  • 关于
网游世界

吾生有涯,而知无涯。

Windows BT 面板 PHP 实现获取视频时长

3Vshej, 2024年2月28日 周三2024年2月28日 周三

业务中,需要获取上传视频的时长,用于外部展示。

目前暂未找到理想的方法,只能用“大炮打蚊子”的方式——使用 ffmpeg。

通过下载 ffmpeg,在 BT 面板中安装 PHP 5.6,并放开 exec 函数。在建立的新站点中,使用 PHP5.6 版本。因为,为了安全 PHP 5.6 允许执行外部程序,且其他站点不使用 PHP 5.6 版本,而后,由 PHP 程序执行 ffmpeg,获取时间时长并存储到数据库中。

1、下载 ffmpeg

打开 https://www.gyan.dev/ffmpeg/builds/

点击左侧导航菜单中的 release builds,在右侧,找到,ffmpeg-release-essentials.zip ,点击以下载。

根据需要下载工具,点击左侧导航菜单中的 tools,在右侧,找到,ffmpeg-tools.zip ,点击以下载。

包含的工具有:
aviocat crypto_bench cws2fws ffescape ffeval ffhash fourcc2pixfmt graph2dot ismindex pktdumper probetest qt-faststart seek_print sidxindex venc_data_dump zmqsend

将压缩包中的 bin 目录解压,如存放在 d:\ffmpeg\bin 中。

2、设置环境变量
在“此电脑”中,点击右键,选择“属性”,之后选择“高级系统设置”。
在“高级选择卡”中点击“环境变量”,在“系统变量”中,找到“Path”,双击编辑后,添加新的环境变量值,如 d:\ffmpeg\bin。

3、新建建站

绑定的域名,填写,127.0.0.2(只用于内部访问), 无数据库,无 FTP,PHP 版本设置为 5.6,且在禁用函数中,移除 exec。

编辑 .user.ini,增加 TP5 站点目录,ffmpeg 程序目录。

open_basedir="d:/wwwroot/syncvideoinfo/;D:/wwwroot/kaoshi/;D:/ffmpeg/bin/;C:/Windows/Temp/;C:/Temp/;D:/BtSoft/temp/session/"

4、使用 SyncVideo.php

该程序是基于 TP5 框架的,因为需要设置 .env 所在目录,及解析视频地址。

之后读取数据库中存储的视频地址,并获取时间,然后,写入到数据库中。

<?php
/**
 * 同步视频长度
 */

class SyncVideo
{
    /** @var string 锁文件路径 */
    private $lockFile;
    /** @var string env 配置文件路径 */
    private $dbEnvFile;
    /** @var string env 待解析视频目录 */
    private $parseVideoDir;

    function __construct()
    {
        $this->lockFile      = "./sync.lock";
        $this->dbEnvFile     = "../kaoshi/.env";
        $this->parseVideoDir = "../kaoshi/public";
    }

    public function canSync($write = false, $val = 0)
    {

        if ($write) {
            return file_put_contents($this->lockFile, $val) ? true : false;
        }
        $data = file_get_contents($this->lockFile);
        if ($data) {
            return false;
        } else {
            return true;
        }
    }

    public function getVideoMins($file)
    {
        $command = "ffmpeg -i " . $file . " 2>&1";
        exec($command, $output);
        // 从输出中提取视频信息

        $line = implode('', $output);

        // 提取视频时长
        if (preg_match("/Duration: (.*?), /", $line, $matches)) {
            $time = explode(':', $matches[1]);
            return (intval($time[0]) * 60 * 60) + intval($time[1]) * 60 + intval($time[2]);
        }

        return 0;

    }

    /**
     * @throws Exception
     */
    public function sync()
    {
        $res = [
            'count' => 0,
            'list'  => [],

        ];

        if (!$this->canSync()) {
            throw new Exception("Please hold on ...");
        }
        $this->canSync(true, date('Y-m-d H:i:s'));
        $dbConfig = parse_ini_file($this->dbEnvFile, true);

        try {
            // 创建连接
            $conn = new PDO("mysql:host={$dbConfig['database']['hostname']};dbname={$dbConfig['database']['database']}",
                $dbConfig['database']['username'],
                $dbConfig['database']['password']);
            // 设置 PDO 错误模式为异常
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

            $list         = $conn->query("SELECT id,moive_file FROM fa_exam_course_movie where mins=0");
            $res['count'] = count($list->rowCount() > 0 ? $list : []);
            foreach ($list as $row) {
                $t   = time();
                $sec = $this->getVideoMins($this->parseVideoDir . $row['moive_file']);
                // SQL 更新语句
                $sql = "update fa_exam_course_movie set mins=:sec,updatetime=:t where id=:id";

                // 预处理 SQL 语句
                $stmt = $conn->prepare($sql);

                // 绑定参数
                $stmt->bindParam(':sec', $sec);
                $stmt->bindParam(':t', $t);
                $stmt->bindParam(':id', $row['id']);

                // 执行更新操作
                $stmt->execute();
                $res['list'][] = [
                    'id'         => $row['id'],
                    'moive_file' => $row['moive_file'],
                    'length'     => $sec,
                    'status'     => $stmt->rowCount(),

                ];

            }

        } catch (PDOException $e) {
            throw new Exception($e->getMessage());
        }

        // 关闭连接
        $conn = null;
        $this->canSync(true, 0);
        return $res;
    }
}

try {
    $data = (new SyncVideo())->sync();
    echo date('Y-m-d H:i:s'), " count: ", $data['count'], PHP_EOL;
    foreach ($data['list'] as $v) {
        echo $v['id'], "\t", $v['moive_file'], "\t", $v['length'], "\t", $v['status'], PHP_EOL;
    }
} catch (Exception $e) {
    echo $e;
}
// 程序正常退出
exit(0);

5、增加计划任务

任务类型为,访问 URL,每1分钟访问一次,地址为 http://127.0.0.2/SyncVideo.php。

这样就可以了,虽然不是最优方法,先实现再说,时间紧张。

相关文章:

  1. PHP OAuth2 OAuth 不是一个 API 或者服务,而是一个验证授权(Authorization)的开放标准,所......
  2. PHP OAuth2 Server league/oauth2-server 是用 PHP 编写的 OAuth 2.0 授权服务器的标准......
  3. PHP OAuth Server 访问令牌存储库接口文档 getNewToken() : AccessTokenEntityInterface 此方法应返回 ......
  4. PHP OAuth Server 客户端存储库接口文档 getClientEntity() : ClientEntityInterface 此方法应返回 的......
PHP ThinkPHP BT 面板ffmpegPHP视频时长

文章导航

Previous post
Next post

近期文章

  • Android Studio Gradle 配置国内镜像
  • 为什么重新发明轮子
  • ruoyi-vue-pro 匿名访问
  • VUE 中接收 code 异常
  • 关于 AI

归档

  • 2025 年 4 月
  • 2025 年 3 月
  • 2025 年 2 月
  • 2025 年 1 月
  • 2024 年 12 月
  • 2024 年 11 月
  • 2024 年 10 月
  • 2024 年 9 月
  • 2024 年 8 月
  • 2024 年 7 月
  • 2024 年 6 月
  • 2024 年 5 月
  • 2024 年 4 月
  • 2024 年 3 月
  • 2024 年 2 月
  • 2024 年 1 月
  • 2023 年 12 月
除非特殊说明,本站作品采用知识共享署名 4.0 国际许可协议进行许可。
豫公网安备 41010402002622号 豫ICP备2020029609号-3
©2025 3Vshej