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

使用yt-dlp结合PHP获取YouTube视频标题不稳定问题求助

稳定获取YouTube视频标题的优化方案

针对你用PHP调用yt-dlp偶尔返回错误标题的问题,可通过以下几个关键优化提升稳定性:

1. 过滤冗余输出,保证JSON纯净度

你当前命令加了--verbose,会把yt-dlp的日志输出混入结果中,破坏JSON结构,导致解析后拿到错误内容。建议去掉该参数,并将错误输出重定向,只保留标准输出的纯净JSON:

// Linux/macOS
$metadata_command = "$yt_dlp_path --dump-json --no-playlist --skip-download \"$user_url\" 2>/dev/null";
// Windows
// $metadata_command = "$yt_dlp_path --dump-json --no-playlist --skip-download \"$user_url\" 2>nul";

额外添加--no-playlist避免播放列表URL返回多条数据,--skip-download确保不会触发下载操作。

2. 用proc_open替代exec,分离标准输出与错误输出

exec会混合stdout和stderr,容易导致JSON被日志污染。proc_open可分别捕获两类输出,既保证JSON纯净,又能获取错误信息用于排查:

$descriptorspec = [
    0 => ["pipe", "r"],
    1 => ["pipe", "w"],
    2 => ["pipe", "w"]
];

$process = proc_open($metadata_command, $descriptorspec, $pipes);
if (!is_resource($process)) {
    throw new Exception('Failed to initialize yt-dlp process');
}

$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
foreach ($pipes as $pipe) fclose($pipe);

$return_var = proc_close($process);
if ($return_var !== 0) {
    throw new Exception("Metadata fetch failed: {$stderr}");
}

$metadata = json_decode($stdout, true);
if ($metadata === null) {
    throw new Exception('Invalid JSON metadata returned');
}

3. 严格验证标题字段有效性

解析JSON后,不要直接取title字段,先检查其是否存在且非空:

if (!isset($metadata['title']) || trim($metadata['title']) === '') {
    throw new Exception('Valid video title not found in metadata');
}
$video_title = trim($metadata['title']);

4. 增加URL合法性校验

在执行命令前,先验证输入URL是否为有效的YouTube视频地址,避免无效请求导致异常结果:

$youtube_regex = '/^(https?:\/\/)?(www\.)?(youtube\.com\/(watch\?v=|embed\/|v\/)|youtu\.be\/)[a-zA-Z0-9_-]{11}/';
if (!preg_match($youtube_regex, $user_url)) {
    throw new Exception('Invalid YouTube video URL');
}

5. 添加重试机制应对临时故障

偶尔的网络波动或YouTube反爬限制可能导致单次请求失败,可添加重试逻辑:

$max_retries = 3;
$retry_count = 0;
$success = false;
$video_title = '';

while ($retry_count < $max_retries && !$success) {
    try {
        // 这里放入上述获取元数据的完整逻辑
        $success = true;
    } catch (Exception $e) {
        $retry_count++;
        sleep(2); // 间隔2秒重试
        if ($retry_count === $max_retries) {
            throw new Exception("Failed after {$max_retries} retries: {$e->getMessage()}");
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 09:47:37