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

转换为MP4的视频经PHP上传后无法在HTML5 video标签显示问题求助

问题核心原因

你当前的代码根本没有执行实际的视频转码操作,仅仅是把上传文件的后缀名强制改成了.mp4,源文件的容器格式、编码规则完全没有变化,而HTML5的video标签仅支持H.264视频编码+AAC音频编码的MP4格式文件,自然无法正常播放。

其他需要修复的错误

  • 格式校验逻辑存在漏洞:使用preg_match匹配后缀容易出现误判,比如后缀为mo也能匹配到mov格式,同时格式列表中混入了纯音频格式wav,不符合视频上传的业务逻辑。
  • 存在严重的SQL注入风险:直接将用户可控的参数拼接进SQL语句,未做任何过滤,极易被恶意攻击导致数据泄露、数据库被销毁。
  • 文件名生成逻辑错误:$targetvid . basename($_FILES["post_photo"] . ".mp4")中$_FILES["post_photo"]是数组,直接拼接会得到Array.mp4的错误结果,当前文件名能对应仅为巧合。
  • HTML的video标签配置冗余:同一个文件同时配置了video/mp4和video/ogg两种类型的source,转码后仅存在MP4格式文件,多余配置会导致浏览器解析异常。

解决方法

  1. 服务器端提前安装FFmpeg工具并配置环境变量,保证PHP可调用,添加实际的转码逻辑,强制输出HTML5兼容的MP4格式,修复现有代码的各类漏洞:
<?php 
include "includes/dbh.inc.php";
session_start();
if (isset($_SESSION['user_name'])){
    if (isset($_POST['submit'])) {
        $author = $_SESSION['user_name'];
        $post_photo = time() . '-' . $_FILES["post_photo"]["name"];
        if (file_exists($_FILES['post_photo']['tmp_name']) && is_uploaded_file($_FILES['post_photo']['tmp_name'])) {
            $targetvid     = md5(time() . rand(1000,9999)); // 加随机数避免重名
            $target_dirvid = "post_video/";
            $videotype = strtolower(pathinfo($post_photo, PATHINFO_EXTENSION));
            $uploadOk = 0;

            $video_formats = [
                "mpeg",
                "mp4",
                "mov",
                "avi",
                "dat",
                "flv",
                "3gp"
            ];

            // 直接用in_array校验后缀,不需要循环
            if(in_array($videotype, $video_formats)){
                $uploadOk = 1;
            }

            if ($uploadOk == 0) {
                echo "不支持的视频格式";
            } else {
                // 先保存原始上传文件
                $original_file = $target_dirvid . $targetvid . '_original.' . $videotype;
                move_uploaded_file($_FILES["post_photo"]["tmp_name"], $original_file);
                // 最终输出的mp4文件名
                $target_filevid = $targetvid . '.mp4';
                $output_path = $target_dirvid . $target_filevid;
                // FFmpeg转码命令:强制H264视频编码、AAC音频编码,moov原子前置方便流式播放
                $ffmpeg_cmd = "ffmpeg -i ".escapeshellarg($original_file)." -vcodec libx264 -acodec aac -movflags +faststart ".escapeshellarg($output_path)." 2>&1";
                exec($ffmpeg_cmd, $output, $return_var);
                // 转码成功才写入数据库
                if($return_var === 0){
                    // 删除原始文件节省空间
                    unlink($original_file);
                    // 用预处理语句避免SQL注入
                    $stmt = $conn->prepare("INSERT INTO video_posts (author, video_post) VALUES (?, ?)");
                    $stmt->bind_param("ss", $author, $target_filevid);
                    if($stmt->execute()){
                        echo "上传转码成功";
                    }else{
                        echo "数据库写入失败:". $stmt->error;
                    }
                    $stmt->close();
                }else{
                    echo "视频转码失败,错误信息:".implode("\n",$output);
                    // 清理无效文件
                    unlink($original_file);
                    if(file_exists($output_path)) unlink($output_path);
                }
            }
        }
    }
}
?>
  1. 修复HTML的video标签代码,删除冗余的ogg source配置,同时输出文件名时做转义避免XSS漏洞:
<video id="myVideo" controls playsinline>
  <source src="../post_video/<?php echo htmlspecialchars($user_post['video_post']); ?>" type="video/mp4">
</video>
  1. 检查post_video文件夹的权限,设置为755,保证web服务器进程有读取权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 03:15:02