You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP上传视频自动转码多清晰度文件实现方法咨询

嗨,我来帮你搞定视频自动转码适配VideoJS清晰度切换的问题!这事儿核心靠FFmpeg(业界标准的视频处理工具)+ PHP的命令执行能力,下面一步步给你拆解:

一、先搞定服务器环境:安装FFmpeg

首先你的服务器必须装FFmpeg,不然没法转码。不同系统安装方式不一样:

  • Ubuntu/Debian:直接在终端跑sudo apt update && sudo apt install ffmpeg
  • CentOS/RHEL:先装EPEL源,再装sudo yum install epel-release && sudo yum install ffmpeg
  • Windows服务器:去FFmpeg官网下载二进制包,解压后把ffmpeg.exe所在路径加到系统环境变量里,然后在命令行测试ffmpeg -version能正常输出就行。

二、PHP处理上传+自动转码的核心逻辑

1. 接收并验证上传文件

先写基础的上传接收代码,记得验证文件类型(只允许视频格式,比如mp4、mov、avi),把上传的临时文件移到一个临时处理目录:

<?php
// 上传目录(确保www-data用户有读写权限)
$uploadDir = './temp_uploads/';
$processedDir = './videos/';

// 创建目录(如果不存在)
if (!file_exists($uploadDir)) mkdir($uploadDir, 0755, true);
if (!file_exists($processedDir)) mkdir($processedDir, 0755, true);

// 处理上传
if ($_FILES['video']['error'] === UPLOAD_ERR_OK) {
    $originalFileName = $_FILES['video']['name'];
    $tempFilePath = $uploadDir . uniqid('video_') . '.' . pathinfo($originalFileName, PATHINFO_EXTENSION);
    
    // 移到临时目录
    move_uploaded_file($_FILES['video']['tmp_name'], $tempFilePath);
    
    // 调用转码函数
    $transcodedFiles = transcodeVideo($tempFilePath, $processedDir);
    
    // 转码完成后可以删除原临时文件
    unlink($tempFilePath);
}

function transcodeVideo($inputPath, $outputDir) {
    // 定义需要转码的分辨率集合(对应VideoJS的4个清晰度)
    $resolutions = [
        '2160p' => '3840x2160',
        '1080p' => '1920x1080',
        '720p' => '1280x720',
        '480p' => '854x480'
    ];
    
    $outputFiles = [];
    $baseName = pathinfo($inputPath, PATHINFO_FILENAME);
    
    foreach ($resolutions as $label => $res) {
        $outputPath = $outputDir . $baseName . '_' . $label . '.mp4';
        
        // FFmpeg转码命令(核心参数)
        $command = "ffmpeg -i \"$inputPath\" -s $res -c:v libx264 -crf 23 -c:a aac -b:a 128k \"$outputPath\" -y";
        
        // 执行命令并捕获输出
        exec($command, $output, $returnCode);
        
        if ($returnCode === 0) {
            $outputFiles[$label] = $outputPath;
        } else {
            // 转码失败,记录日志或者处理错误
            error_log("转码$label失败:" . implode("\n", $output));
        }
    }
    
    return $outputFiles;
}
?>

2. FFmpeg命令参数解释

上面的命令里几个关键参数:

  • -i "$inputPath":指定输入视频文件
  • -s $res:设置输出分辨率(比如1280x720对应720p)
  • -c:v libx264:用H.264编码(VideoJS完美支持)
  • -crf 23:视频质量参数,值越小质量越高(18-28是合理范围)
  • -c:a aac -b:a 128k:音频用AAC编码,比特率128k(平衡音质和体积)
  • -y:如果输出文件已存在,直接覆盖

三、适配VideoJS的清晰度切换

转码完成后,你需要把不同清晰度的文件路径传给VideoJS。如果你的VideoJS已经带切换功能,直接生成对应的<source>标签就行:

<video id="my-video" class="video-js" controls preload="auto" width="1280" height="720" data-setup='{}'>
    <?php foreach ($transcodedFiles as $label => $path): ?>
        <source src="<?php echo $path; ?>" type='video/mp4' label='<?php echo $label; ?>' res='<?php echo str_replace('p', '', $label); ?>'>
    <?php endforeach; ?>
</video>

这里的label和res属性是给VideoJS的清晰度切换插件识别用的,确保和你购买的播放器代码逻辑匹配就行。

四、进阶优化建议

  • 异步转码:大视频转码会很耗时,别让用户等着!可以把转码任务放到队列(比如用Redis+PHP脚本),后台异步执行,转码完成后给用户发通知。
  • 硬件加速:如果服务器有NVIDIA显卡,FFmpeg支持NVENC硬件加速,把命令里的-c:v libx264换成-c:v h264_nvenc,转码速度能提升好几倍。
  • 文件管理:给每个视频生成唯一ID(比如UUID),用ID作为文件名前缀,避免重名问题;定期清理过期的未处理视频文件。
  • 错误监控:把转码的错误日志存到文件或者监控系统里,方便排查问题。

内容的提问来源于stack exchange,提问作者40oz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:54:17