博客园  :: 首页  :: 新随笔  :: 订阅 订阅  :: 管理

PHP基于mjpeg连续图片功能动态发送svg图片流

Posted on 2025-08-15 17:08  PHP-张工  阅读(8)  评论(0)    收藏  举报

mjpeg格式的图片,可以实现图片流播放。
但jpeg文件毕竟是二进制的,就是简单图像也很大有几百K,我就想能不能用矢量的SVG替换jpeg,通过mjpeg协议把svg图片流发出去。
测试了一下是可以的。代码如下:

<?php
// 禁用输出缓冲(关键:确保内容实时发送)
if (ob_get_level()) {
    ob_end_clean();
}
ob_implicit_flush(true);

// 核心头信息:多部分替换格式(模拟MJPEG机制)
header('Content-Type: multipart/x-mixed-replace; boundary=svg_boundary');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
header('Connection: keep-alive');

$boundary = 'svg_boundary';

try {
    while (true) {
        // 1. 生成动态SVG内容(未压缩,提高兼容性)
        $svgContent = generateDynamicSvg();
        
        // 2. 输出多部分分隔符和帧头
        echo "--{$boundary}\r\n";
        echo "Content-Type: image/svg+xml\r\n";
        echo "Content-Encoding: gzip\r\n";
        echo "Content-Length: " . strlen($svgContent) . "\r\n\r\n";
        
        // 3. 输出当前帧的SVG内容
        echo $svgContent . "\r\n";
        
        // 4. 强制刷新输出
        flush();
        
        // 5. 检测客户端断开连接
        if (connection_aborted()) {
            break;
        }
        
        // 控制帧率
        usleep(100000);
    }
} catch (Exception $e) {
    error_log("SVG流错误: " . $e->getMessage());
}

/**
 * 生成简单可靠的动态SVG(避免复杂语法,提高兼容性)
 */
function generateDynamicSvg() {
    $width = 400;
    $height = 300;
    $time = date('H:i:s') . '; ' . rand(0,100);
    
    // 动态元素:随时间移动的矩形
    $x = (microtime(true) * 100) % ($width - 50); // 水平移动
    $color = '#' . dechex(rand(0x333333, 0xFFFFFF)); // 随机浅色调
    $x2 = $x/10 + 10;
    
    // 简化SVG语法,避免浏览器解析问题
    return <<<SVG
<svg xmlns="http://www.w3.org/2000/svg" width="{$width}" height="{$height}" version="1.1">
    <rect width="100%" height="100%" fill="#f8f9fa"/>
    <text x="10" y="20" font-family="Arial" font-size="14" fill="#333">Time: {$time}</text>
    <rect x="{$x}" y="120" width="50" height="50" fill="{$color}" rx="5"/>
    <circle cx="200" cy="80" r="{$x2}" fill="rgba(0,123,255,0.5)"/>
</svg>
SVG;
}
?>