在php项目中实现视频上传并转换为mp4格式,需要完成前端上传表单搭建、后端文件接收校验、视频转码三个核心步骤,同时要做好异常处理和安全性校验,避免恶意文件上传和转码失败的问题。

前端上传表单设计
首先需要搭建一个支持视频文件上传的前端表单,需要设置表单的enctype为multipart/form-data,同时限制上传文件的类型为视频格式。
<form action="upload_video.php" method="post" enctype="multipart/form-data">
<label for="video_file">选择视频文件:</label>
<input type="file" name="video_file" id="video_file" accept="video/*" required>
<button type="submit">上传</button>
</form>
后端php文件接收与校验
后端需要先接收上传的文件,对文件的大小、类型、后缀进行校验,避免上传不符合要求的文件,同时把临时文件移动到指定的存储目录。
<?php
// 设置上传目录
$uploadDir = './uploads/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
// 检查是否有文件上传
if (!isset($_FILES['video_file']) || $_FILES['video_file']['error'] != 0) {
die('文件上传失败,错误码:' . $_FILES['video_file']['error']);
}
$file = $_FILES['video_file'];
$fileName = $file['name'];
$fileTmp = $file['tmp_name'];
$fileSize = $file['size'];
// 校验文件大小,限制为100MB
$maxSize = 100 * 1024 * 1024;
if ($fileSize > $maxSize) {
die('文件大小不能超过100MB');
}
// 校验文件后缀
$allowExt = ['mp4', 'avi', 'mov', 'flv', 'mkv'];
$fileExt = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
if (!in_array($fileExt, $allowExt)) {
die('不支持的文件格式,仅支持mp4、avi、mov、flv、mkv');
}
// 生成唯一文件名,避免重名
$newFileName = uniqid() . '.' . $fileExt;
$targetPath = $uploadDir . $newFileName;
// 移动临时文件到目标目录
if (move_uploaded_file($fileTmp, $targetPath)) {
echo '文件上传成功,开始转码为mp4格式<br>';
// 调用转码方法
convertToMp4($targetPath, $uploadDir . uniqid() . '.mp4');
} else {
die('文件移动失败');
}
使用FFmpeg转换为mp4格式
php本身没有内置视频转码功能,需要借助FFmpeg工具实现,首先确保服务器已经安装FFmpeg,然后可以通过php的exec函数调用FFmpeg命令完成转码。
<?php
function convertToMp4($inputPath, $outputPath) {
// 检查FFmpeg是否可用
exec('ffmpeg -version', $output, $returnCode);
if ($returnCode != 0) {
die('服务器未安装FFmpeg,无法完成转码');
}
// 转码命令,-y表示覆盖已有文件,-c:v libx264是视频编码,-c:a aac是音频编码
$cmd = "ffmpeg -i {$inputPath} -c:v libx264 -c:a aac -y {$outputPath}";
exec($cmd, $cmdOutput, $cmdReturn);
if ($cmdReturn == 0) {
echo '转码成功,mp4文件路径:' . $outputPath . '<br>';
// 可选:删除原始上传文件
unlink($inputPath);
} else {
die('转码失败,错误信息:' . implode('', $cmdOutput));
}
}
常见问题处理
- 如果exec函数被禁用,需要修改php.ini中的disable_functions配置,移除exec函数限制
- 转码大文件时可能会超时,需要设置set_time_limit(0)延长脚本执行时间
- 要对上传文件的MIME类型做二次校验,避免伪装成视频的恶意文件上传
- 转码后的mp4文件可以做二次校验,确认文件可以正常播放
注意事项
视频转码会消耗较多服务器CPU资源,如果上传量较大,建议使用队列异步处理转码任务,避免阻塞用户请求。同时要做好上传目录的权限控制,防止上传的文件被直接执行。
如果是需要上传到第三方平台,转码完成后可以调用对应平台的开放接口,将生成的mp4文件通过curl等方式推送到平台指定的接口地址即可,推送时需要注意接口要求的参数格式和鉴权方式。
<?php
function uploadToPlatform($mp4Path, $platformApi, $authToken) {
$ch = curl_init();
$postData = [
'video' => new CURLFile($mp4Path),
'token' => $authToken
];
curl_setopt($ch, CURLOPT_URL, $platformApi);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
die('上传到平台失败:' . $error);
}
echo '上传到平台结果:' . $response;
}