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

如何在Web应用中实现类YouTube的视频分段加载播放?

实现视频分段加载(边播边缓冲)的解决方案

当前视频平台播放前会一次性加载完整视频,无法像YouTube那样随观看进度分块加载、立即播放。现有前端和PHP代码如下:

现有前端代码

<div class="main_video_player">
  <video controls width="100%" height="auto" poster="<?php echo $thumbnail_path; ?>" data-src="<?php echo $video_url; ?>">
    <source src="<?php echo $video_url; ?>" type="video/mp4">
    Your browser does not support the video tag.
  </video>
</div>

解决方案

要实现边播边缓冲,核心是让服务器支持HTTP字节范围请求(206 Partial Content),同时调整前端请求逻辑和视频文件格式。


一、修复后端字节范围请求处理逻辑

你的PHP代码里已经有send_video_content函数,但存在边界处理漏洞,需修正并确保视频请求走该函数:

修改后的send_video_content函数

function send_video_content($video_url) {
    if (!file_exists($video_url)) {
        header("HTTP/1.1 404 Not Found");
        exit;
    }

    $video_file_size = filesize($video_url);
    $chunk_size = 1024 * 1024; // 1MB分段,可按需调整

    header('Accept-Ranges: bytes');
    header('Content-Type: video/mp4');

    $range_start = 0;
    $range_end = $video_file_size - 1;

    // 处理浏览器发送的范围请求
    if (isset($_SERVER['HTTP_RANGE'])) {
        // 校验请求格式合法性
        if (!preg_match('/bytes=\d*-\d*/i', $_SERVER['HTTP_RANGE'])) {
            header("HTTP/1.1 416 Requested Range Not Satisfiable");
            header("Content-Range: bytes */$video_file_size");
            exit;
        }

        list($size_unit, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
        list($range_start, $range_end) = explode('-', $range, 2);

        $range_start = intval($range_start);
        // 处理浏览器只传起始位置的情况
        if (empty($range_end)) {
            $range_end = $video_file_size - 1;
        } else {
            $range_end = intval($range_end);
            $range_end = min($range_end, $video_file_size - 1);
        }

        if ($range_start > $range_end) {
            header("HTTP/1.1 416 Requested Range Not Satisfiable");
            header("Content-Range: bytes */$video_file_size");
            exit;
        }

        header('HTTP/1.1 206 Partial Content');
        header("Content-Range: bytes $range_start-$range_end/$video_file_size");
        header('Content-Length: ' . ($range_end - $range_start + 1));
    } else {
        // 无范围请求时返回完整文件
        header('Content-Length: ' . $video_file_size);
    }

    // 分段读取并输出视频内容
    $video_file = fopen($video_url, 'rb');
    fseek($video_file, $range_start);

    $remaining = $range_end - $range_start + 1;
    while ($remaining > 0) {
        $read_size = min($chunk_size, $remaining);
        echo fread($video_file, $read_size);
        flush(); // 立即输出内容到浏览器
        $remaining -= $read_size;
    }

    fclose($video_file);
    exit;
}

添加GET请求路由逻辑

在现有PHP代码的POST处理块之后,添加处理视频播放请求的逻辑:

// 处理视频播放的GET请求
if ($_SERVER["REQUEST_METHOD"] == "GET" && isset($_GET['video_id'])) {
    $video_id = $_GET['video_id'];
    $stmt = $conn->prepare("SELECT video_url FROM videos WHERE video_id = ?");
    $stmt->bind_param("s", $video_id);
    $stmt->execute();
    $result = $stmt->get_result();
    $row = $result->fetch_assoc();
    
    if ($row) {
        $video_file_path = "../uploads/" . $row['video_url'];
        send_video_content($video_file_path);
    } else {
        header("HTTP/1.1 404 Not Found");
        echo "Video not found";
    }
    $stmt->close();
    $conn->close();
    exit;
}

二、调整前端视频标签

修改视频src指向处理请求的PHP接口,而非直接指向视频文件:

<div class="main_video_player">
  <video controls width="100%" height="auto" poster="<?php echo $thumbnail_path; ?>">
    <source src="your-video-handler.php?video_id=<?php echo $video_id; ?>" type="video/mp4">
    Your browser does not support the video tag.
  </video>
</div>

注:将your-video-handler.php替换为你实际的PHP文件名


三、视频文件格式要求

浏览器能否分段加载还取决于视频本身,需确保:

  1. MP4文件的Moov原子前置:将视频元数据放在文件开头,可用ffmpeg处理:
    ffmpeg -i input.mp4 -movflags faststart output.mp4
    
  2. 使用H.264视频编码 + AAC音频编码,这是浏览器支持最广泛的组合

验证方法

  1. 打开浏览器开发者工具(F12)→ 切换到Network标签
  2. 播放视频,检查请求状态码是否为206 Partial Content
  3. 拖动进度条,观察是否有新的分段请求产生

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 00:20:58