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

如何用可缓存JavaScript调用获取YouTube直播状态的PHP接口

YouTube直播状态查询脚本优化与前端实现

脚本功能说明

我编写了一段PHP脚本用于查询YouTube频道直播状态:

  • 不直接轮询YouTube,而是调用YouTube Live Embed插件提供的JSON接口获取live_status标识
  • 本地缓存机制:将API拉取结果与时间写入LastEmbedVidioPull.json,后续执行时检查时间差,不足5分钟返回缓存值,超过则重新拉取并更新缓存
  • 错误处理:请求出错时记录日志到EmbedVidioErrorLog.txt,默认返回状态码0(代表未直播)

PHP代码优化建议

  • 替换本地文件的cURL请求:当前用cURL读取本地缓存文件,完全可以用file_get_contents()替代,减少cURL的性能开销,本地文件读取效率更高
  • 修复JSON编码逻辑:原代码中json_encode('{"live_status":"' . $live_status . '", "pull_time":"' . $now . '"}')是对字符串编码,会导致JSON被转义,应改为数组转JSON:json_encode(['live_status' => $live_status, 'pull_time' => $now]),避免格式错误
  • 提前定义日志路径变量:$save_path仅在第一个错误分支定义,后续错误分支直接调用会触发变量未定义错误,建议将$Log、$upload_dir、$save_path的定义移到脚本最开头
  • 封装cURL请求逻辑:重复的cURL配置可以封装成通用函数,比如fetch_url($url),减少代码冗余,提升可维护性
  • 添加缓存文件存在性检查:首次运行时缓存文件不存在,json_decode会失败,需添加文件存在性判断,不存在则直接拉取API
  • 设置cURL超时参数:添加CURLOPT_TIMEOUT和CURLOPT_CONNECTTIMEOUT参数,避免请求挂起占用服务器资源

可缓存的JavaScript调用实现

通过localStorage缓存API结果,配合PHP的缓存策略,实现前端低频次请求,并根据状态码控制"直播中"横幅的显示:

示例代码

// 配置参数
const CONFIG = {
    phpEndpoint: '/path/to/your/live-status.php', // 你的PHP接口路径
    cacheExpireMinutes: 5, // 和PHP缓存保持一致
    bannerId: 'live-banner'
};

// 创建直播横幅元素
function createLiveBanner() {
    const banner = document.createElement('div');
    banner.id = CONFIG.bannerId;
    banner.style.cssText = `
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        background: #e74c3c;
        color: white;
        text-align: center;
        padding: 8px 0;
        font-weight: bold;
        z-index: 9999;
    `;
    banner.textContent = '直播中';
    return banner;
}

// 更新直播状态显示
function updateLiveStatus(status) {
    const existingBanner = document.getElementById(CONFIG.bannerId);
    if (status == 1) {
        if (!existingBanner) {
            document.body.prepend(createLiveBanner());
        }
    } else {
        if (existingBanner) {
            existingBanner.remove();
        }
    }
}

// 获取直播状态(带本地缓存)
async function getLiveStatus() {
    const now = Date.now();
    const cached = localStorage.getItem('liveStatusCache');
    
    if (cached) {
        const { status, expireTime } = JSON.parse(cached);
        if (now < expireTime) {
            // 缓存未过期,直接使用
            updateLiveStatus(status);
            return;
        }
    }

    // 缓存过期或不存在,请求PHP接口
    try {
        const response = await fetch(CONFIG.phpEndpoint, {
            method: 'GET',
            cache: 'no-store' // 让PHP自行处理服务器端缓存
        });
        const status = await response.text();
        
        // 更新本地缓存
        const expireTime = now + CONFIG.cacheExpireMinutes * 60 * 1000;
        localStorage.setItem('liveStatusCache', JSON.stringify({
            status: status,
            expireTime: expireTime
        }));
        
        updateLiveStatus(status);
    } catch (error) {
        // 请求出错,默认显示未直播
        updateLiveStatus(0);
        console.error('获取直播状态失败:', error);
    }
}

// 页面加载时执行
document.addEventListener('DOMContentLoaded', getLiveStatus);
// 定时刷新状态(可选)
setInterval(getLiveStatus, CONFIG.cacheExpireMinutes * 60 * 1000);

原PHP代码

<?php

$now = date("Y-m-d") . "T" . date("H:i:s.000") . "Z";
$curla = curl_init();

curl_setopt_array($curla, [
    CURLOPT_URL => "[URL to LastEmbedVidioPull.json]",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET"
]);

$responsec = curl_exec($curla);
$errora = curl_error($curla);

curl_close($curla);

if ($errora) {
    $toLog = $now . " cURL error #: " . $errora . "\n";
    $Log = "EmbedVidioErrorLog.txt";
    $upload_dir = wp_get_upload_dir();
    $save_path = $upload_dir['basedir'] . '/' . $Log;
    file_put_contents($save_path, $toLog, FILE_APPEND | LOCK_EX);
    echo 0;
} else {
    $showInfoa = json_decode($responsec, true);
    $lastpull = strtotime($showInfoa["pull_time"]);
    $diff = strtotime($now) - $lastpull;
    if ($diff > 300) {

        $curl = curl_init();

        curl_setopt_array($curl, [
            CURLOPT_URL => "[URL to External API endpoint provided by YT Live Embed Plugin Provider]",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "GET"
        ]);

        $response = curl_exec($curl);
        $error = curl_error($curl);

        curl_close($curl);

        if ($error) {
            $toLoga = $now . " EmbedVidio API cURL error #: " . $error . "\n";
            file_put_contents($save_path, $toLoga, FILE_APPEND | LOCK_EX);
            echo 0;
            
        } else {
            // echo $response;
            $extractInfo = str_replace('},]',"}]",$response);
            $showInfo = json_decode($extractInfo, true);
            $live_status = $showInfo["live_status"];
            $responsea = json_encode('{"live_status":"' . $live_status . '", "pull_time":"' . $now . '"}');
            file_put_contents($upload_dir['basedir'] . '/LastEmbedVidioPull.json', $responsea, LOCK_EX);
            echo $live_status;
        }
    } else {
        echo $showInfoa["live_status"];
    }
}
?>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:40:57