需依次实现短视频上传、ffmpeg转hls、php动态播放页、分片代理及mp4范围请求:一、表单上传并校验视频文件,存入/uploads/raw/并记录数据库;二、用ffmpeg生成.m3u8与.ts分片,更新hls_path字段;三、play.php查询id渲染含hls.js的页面;四、proxy/hls.php代理分片并鉴权;五、proxy/mp4.php支持range请求实现mp4流式播放。

如果您正在搭建一个PHP网站并希望集成短视频的上传、转码与流式播放功能,则需分别处理文件接收、视频格式转换及HLS或MP4分片传输等环节。以下是实现该功能的具体步骤:
一、短视频上传功能实现
PHP需通过表单接收前端提交的视频文件,并进行合法性校验与安全存储,防止恶意文件上传导致服务器风险。
1、在HTML表单中设置enctype="multipart/form-data",并限定accept="video/*"以引导用户选择视频文件。
2、在PHP脚本中使用$_FILES获取上传数据,检查$_FILES['video']['error'] === UPLOAD_ERR_OK确认无上传错误。
3、验证文件MIME类型是否属于video/mp4、video/webm或video/quicktime,拒绝非视频类型。
4、生成唯一文件名(如sha1_file($_FILES['video']['tmp_name']).'.mp4'),将文件移至指定上传目录(如./uploads/raw/)。
5、记录文件元信息(原始名称、大小、路径、上传时间)至MySQL数据库表videos中。
二、服务端视频转码为HLS格式
为支持流式播放,需将原始视频转为HLS协议所需的.m3u8索引文件与多个.ts分片,此过程依赖FFmpeg命令行工具。
1、确认服务器已安装FFmpeg且PHP可执行系统命令(需开启exec函数或使用proc_open)。
2、构建转码命令:使用-profile:v baseline -level 3.0确保兼容性,输出至./uploads/hls/{video_id}/目录。
3、执行命令示例:ffmpeg -i /path/to/input.mp4 -codec: copy -start_number 0 -hls_time 10 -hls_list_size 0 -f hls /path/to/output.m3u8。
4、转码完成后,更新数据库中对应记录的hls_path字段为/uploads/hls/{video_id}/output.m3u8。
5、设置Web服务器(如Nginx)对.m3u8和.ts文件启用application/vnd.apple.mpegurl与video/MP2T MIME类型。
三、PHP动态生成HLS播放页
通过PHP渲染包含<video></video>标签的HTML页面,并注入HLS播放器(如hls.js),实现跨浏览器兼容播放。
1、创建play.php?id=123路由,根据$_GET['id']查询数据库获取hls_path值。
2、校验该ID对应视频状态为“已转码完成”,否则返回HTTP 404或提示“转码中”。必须验证用户权限,禁止未授权访问私有视频路径。
3、在HTML中引入hls.js CDN:<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>。
4、编写JavaScript逻辑:检测浏览器是否原生支持video/mp4,若不支持则初始化Hls对象加载.m3u8地址。
5、将<video></video>标签的src属性设为临时代理URL(如/proxy/hls.php?path={encoded_hls_path})以统一鉴权控制。
四、基于PHP的视频分片代理服务
为避免直接暴露.m3u8与.ts物理路径,需通过PHP脚本读取并输出文件内容,同时嵌入访问控制逻辑。
1、创建proxy/hls.php,解析$_GET['path']并进行urldecode与路径白名单校验。
2、检查请求IP是否在允许列表内,或验证JWT token是否携带有效video_id与过期时间。
3、使用fopen($real_path, 'rb')打开目标文件,逐块读取并调用fpassthru()输出二进制流。
4、设置响应头:Content-Type依据扩展名设为application/vnd.apple.mpegurl或video/MP2T,并添加Cache-Control: public, max-age=3600。
5、禁止在代理脚本中使用eval、system或shell_exec处理用户输入路径,严防路径遍历攻击。
五、MP4范围请求支持(备用流式方案)
当HLS不可用时,可通过PHP响应HTTP Range请求实现MP4文件的分段加载,满足Chrome/Firefox原生<video></video>控件需求。
1、创建proxy/mp4.php,接收$_GET['file']参数并校验其是否匹配数据库中已审核的MP4路径。
2、使用filesize()获取文件总长度,读取HTTP头中的Range字段(如bytes=0-1023)。
3、计算起始偏移量与长度,设置响应状态码为206 Partial Content,并输出Content-Range头。
4、使用fseek()定位到指定位置,循环fread()输出对应字节段。
5、必须校验Range值为合法整数区间,且不超过文件实际大小,防止内存溢出或超大读取。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











