温馨提示×

Debian PHP如何进行视频处理

小樊
42
2025-12-15 00:04:46
栏目: 编程语言

Debian 下使用 PHP 进行视频处理

一 方案总览

  • Debian 上,PHP 本身不内置视频编解码能力,通常做法是安装系统级的 FFmpeg,再通过 PHP-FFmpeg(PHP 库)exec/process 调用 FFmpeg 完成转码、切片、水印等任务。
  • 常见选择对比:
    • PHP-FFmpeg(库):面向对象 API,开发效率高,适合在 PHP-FPM 中做常规批处理与接口触发处理。
    • exec/process(命令行):最灵活,可写复杂滤镜链,适合需要精细控制的场景。
    • 不建议使用老旧的 ffmpeg-php 扩展(pecl/ffmpeg),多年未维护,易与新版 FFmpeg API 不兼容。

二 环境准备

  • 安装 FFmpeg(系统级):
    • 更新索引并安装:sudo apt update && sudo apt install -y ffmpeg
    • 验证安装:ffmpeg -versionffprobe -version
  • 安装 PHP 依赖与 Composer(用于 PHP-FFmpeg 库):
    • 安装常用工具:sudo apt install -y php-cli php-curl unzip
    • 安装 Composer(如未安装):curl -sS https://getcomposer.org/installer | php && sudo mv composer.phar /usr/local/bin/composer
  • 说明:
    • 若使用 Nginx + PHP-FPM,确保 PHP-FPM 与 CLI 使用同一 PHP 版本与配置;处理大文件时适当增大 FPM 超时与内存限制

三 方法一 使用 PHP-FFmpeg 库

  • 安装库(在项目目录):
    • composer require php-ffmpeg/php-ffmpeg
  • 最小可用示例(转码为 H.264/AAC 并生成缩略图):
    <?php
    require 'vendor/autoload.php';
    
    use FFMpeg\FFMpeg;
    use FFMpeg\Format\Video\X264;
    use FFMpeg\Coordinate\TimeCode;
    
    $ffmpeg = FFMpeg::create([
        'ffmpeg.binaries'  => '/usr/bin/ffmpeg',
        'ffprobe.binaries' => '/usr/bin/ffprobe',
        'timeout'          => 3600,
    ]);
    
    $video = $ffmpeg->open('/data/in.mp4');
    
    // 转码为 H.264/AAC
    $format = new X264();
    $format->setAudioCodec('aac');
    $video->save($format, '/data/out.mp4');
    
    // 截取第10秒缩略图
    $frame = $video->frame(TimeCode::fromSeconds(10));
    $frame->save('/data/thumb.jpg');
    
  • 要点:
    • 通过 ffmpeg.binaries/ffprobe.binaries 显式指定二进制路径,避免 PATH 不一致导致失败。
    • 处理耗时任务建议放入队列/后台作业,避免 Web 请求超时。

四 方法二 使用 exec 调用 FFmpeg 命令行

  • 适用场景:需要复杂滤镜、快速脚本化处理或已有成熟命令模板。
  • 示例 1 添加图片水印(右下角,50% 透明度):
    <?php
    $in  = '/data/in.mp4';
    $wm  = '/data/logo.png';
    $out = '/data/out_wm.mp4';
    
    $pos = 'overlay=W-w-10:H-h-10'; // 右下角,距边10px
    $cmd = sprintf(
        'ffmpeg -y -i %s -i %s -filter_complex "[1]format=rgba,colorchannelmixer=aa=0.5[wm];[0][wm]%s" -c:a copy %s 2>&1',
        escapeshellarg($in), escapeshellarg($wm), $pos, escapeshellarg($out)
    );
    
    exec($cmd, $lines, $ret);
    if ($ret === 0) {
        echo "Watermark OK: $out\n";
    } else {
        echo "FFmpeg failed:\n" . implode("\n", $lines) . "\n";
    }
    
  • 示例 2 HLS 切片(10 秒一片,保留全部分片):
    <?php
    $in  = '/data/in.mp4';
    $dir = '/data/hls/';
    $m3u8 = $dir . 'playlist.m3u8';
    
    if (!is_dir($dir)) mkdir($dir, 0755, true);
    
    $cmd = sprintf(
        'ffmpeg -y -i %s -c:v libx264 -c:a aac -hls_time 10 -hls_list_size 0 '
        . '-hls_segment_filename %s -f hls %s 2>&1',
        escapeshellarg($in),
        escapeshellarg($dir . 'seg_%03d.ts'),
        escapeshellarg($m3u8)
    );
    
    exec($cmd, $lines, $ret);
    echo $ret === 0 ? "HLS OK: $m3u8\n" : "FFmpeg failed:\n" . implode("\n", $lines) . "\n";
    
  • 安全要点:
    • 所有用户输入与文件路径必须使用 escapeshellarg() 转义,防止命令注入。
    • 限制上传类型/大小,启用超时与内存限制,耗时任务改为异步队列。

五 常见问题与优化

  • 找不到 FFmpeg/ffprobe:在 PHP-FFmpeg 配置中显式设置 /usr/bin/ffmpeg/usr/bin/ffprobe 路径;或在 /etc/php/*/cli|fpm/php.iniPATH 包含 /usr/bin
  • 老扩展不可用:避免 ffmpeg-php(pecl/ffmpeg),该扩展已多年未维护,建议改用 PHP-FFmpeg 库 或命令行方式。
  • 性能与稳定性:
    • 转码尽量使用硬件加速(如 VAAPI/NVENC),示例:-hwaccel vaapi -i in.mp4 -c:v h264_vaapi out.mp4(需服务器与 FFmpeg 编译支持)。
    • 大文件与队列处理:使用 Supervisor + 队列任务(如 Laravel Queue、Symfony Messenger)避免 Web 超时。
    • 权限与目录:确保 PHP-FPM 运行用户 对输入/输出目录具有读写权限;临时目录可挂载到 tmpfs 提升 I/O。
  • 流媒体补充:若需推流/拉流,可部署 Nginx + nginx-rtmp-module,用 FFmpeg 推 RTMP 到 rtmp://your_server/live/stream 并在前端用 Video.js/HLS 播放。

0