确定 YouTube 视频是否为宽屏?

Determine if YouTube video is widescreen?

我想确切地知道 YouTube 视频是否是宽屏或不使用 v3 API。有很多老视频有 4:3 的比例,所以我需要检测这个。

这可以通过 API v2, but it is officially retired now. Here are the API v3 docs 实现。

一个 API 调用看起来像这样:

https://www.googleapis.com/youtube/v3/videos?id=[VIDEOID]&part=snippet&key=[DEVELOPERKEY]

此外,缩略图数据始终 returns 尺寸为 4:3,因此这无济于事。这是一个例子:

[thumbnails] => Array
(
    [default] => Array
    (
        [url] => https://i.ytimg.com/vi/nnnnnnnnn/default.jpg
        [width] => 120
        [height] => 90
    )
    ...
)

有什么想法吗?

(我目前正在 破解 通过分析缩略图中的像素来解决 4:3 视频中的黑条问题。)

这是 4:3 比例的示例视频:

https://www.youtube.com/watch?v=zMJ-Dl4eJu8(老武侠视频)

和 16:9 中的一个:

https://www.youtube.com/watch?v=7O2Jqi-LhEI(新的锻炼视频)


更新: 一个有前途的建议是探索 fileDetails.videoStreams[].aspectRatio,但似乎只有视频所有者可以使用。否则请求 fileDetails 会导致

The request cannot access user rating information. This error may occur because the request is not properly authorized

如果您愿意使用 API 的 V3 以外的其他方法,那么我相信可以通过 oEmbed API.

http://www.youtube.com/oembed?url={VIDEO_URL}&format=json

像这样:

http://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=zMJ-Dl4eJu8&format=json

会产生:

{  
    "provider_url":"https:\/\/www.youtube.com\/",
    "thumbnail_url":"https:\/\/i.ytimg.com\/vi\/zMJ-Dl4eJu8\/hqdefault.jpg",
    "thumbnail_height":360,
    "height":344,
    "type":"video",
    "version":"1.0",
    "html":"\u003ciframe width=\"459\" height=\"344\" src=\"https:\/\/www.youtube.com\/embed\/zMJ-Dl4eJu8?feature=oembed\" frameborder=\"0\" allowfullscreen\u003e\u003c\/iframe\u003e",
    "author_name":"hadronica2",
    "width":459,
    "provider_name":"YouTube",
    "author_url":"https:\/\/www.youtube.com\/user\/hadronica2",
    "title":"Aikido - Kazuo Chiba sensei - 1\u00ba part",
    "thumbnail_width":480
}

在您给出的示例中,输出如下:

http://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=zMJ-Dl4eJu8&format=json

Width: 459
Height: 344
Ratio: w/h = 1.3343 = 4:3 (ish)

http://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=zMJ-Dl4eJu8&format=json

Width: 480
Height: 270
Ratio: w/h = 1.7777 = 16/9

这似乎适用于您提供的示例。

这是自 API 的 v2 退役后我一直在使用的精简版本。

它测试给定视频的 default.jpg 缩略图顶部和底部可能存在黑条的几个点。测试与顶点垂直相对的点,以查看这些像素是否在某个增量内彼此相似。再重复几个点。

function isWidescreen($video = null) {

    // LOGIC:
    // 4:3 videos will have default.jpg with no top black bars
    // 16:9 videos will have black top and bottom borders on default.jpg

    // Get the default thumbnail (may have black bars on top and bottom)
    $response = self::accessCurlObj()->get("https://i.ytimg.com/vi/{$video}/default.jpg");
    $defaultImgRes = imagecreatefromstring($response);

    $samplePoints = array(array(20,2), array(40,4), array(60,6), array(80,8));

    // Scan a few points for equality between top and bottom
    $height = imagesy($defaultImgRes);
    foreach($samplePoints as $point) {
        // Top
        $rgbTop = imagecolorat($defaultImgRes, $point[0], $point[1]);
        $colorsTop = imagecolorsforindex($defaultImgRes, $rgbTop);

        // Bottom
        $rgbBottom = imagecolorat($defaultImgRes, $point[0], $height - $point[1]);
        $colorsBottom = imagecolorsforindex($defaultImgRes, $rgbBottom);

        // If these arrays are not close, then let's call this 4:3 aspect
        if(!$this->areArraysClose($colorsTop, $colorsBottom, 20)) {
            return false;
        }
    }

    // Default to widescreen
    return true;
}

// Determine if the numeric values in the RGBA array are within some delta from each other
function areArraysClose(&$a, &$b, $delta = 10) {
    foreach($a as $key => $val) {
        if(abs($val - $b[$key]) > $delta) {
            return false;
        }
    }
    return true;
}

这似乎足够有效了。一个明显的改进是检查像素是否接近黑色,或者应用一些图像处理来自动去除黑条,然后检查剩余图像的尺寸。

但是,我希望在深入了解这个兔子洞之前,具有领域知识的 SO 成员会有更好的解决方案......并且