确定YouTube视频是否为宽屏?

8
我希望能够确定一个YouTube视频是否使用v3 API的宽屏。有很多旧视频采用4:3比例,因此需要检测这一点。
API v2中是可以实现的,但它现在已正式停用。这里是API v3文档
API调用看起来像这样:
https://www.googleapis.com/youtube/v3/videos?id=[VIDEOID]&part=snippet&key=[DEVELOPERKEY]

此外,缩略图数据始终返回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(旧武术视频)

martial arts in 4:3

一个是16:9的:

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

workout video


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

请求无法访问用户评级信息。可能出现此错误的原因是请求未经正确授权。


你确定能自定义纵横比吗?我认为所有的视频都是固定的16:9。 - Halcyon
@Halcyon 许多旧视频仍然是标准的宽高比。我之前可以用v2检测到这一点,但最近不能了。 - Drakes
@jdepypere 这适用于任何视频,还是只适用于已经通过认证的用户(即视频所有者)? - Drakes
必须承认我以前从未使用过YT API,但根据文档,videos资源包含此信息,并且没有说明它仅适用于已登录的用户。它只说明_视频资源代表YouTube视频_。因此,我_假设_不需要身份验证。 - jdepypere
3
这些信息已经不再通过API公开。没有官方原因,但我猜测这是因为从客户端的角度来看,所有玩家大小(和缩略图大小)都已经标准化了。另外,如果存在'maxres'缩略图版本,则其将是16:9(而不是其他所有缩略图的4:3),但在具有'maxres'缩略图的4x3视频中,它只会在左右两侧添加黑边,就像视频一样。因此,您的hack可能是唯一的解决方案。 - jlmcdonald
显示剩余4条评论
2个回答

2

如果您可以接受使用oEmbed API而非API的V3版本,则我相信这是可能的。

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&格式= 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

在你提供的例子中,这似乎是有效的。


1
这是我自从 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 成员在深入研究之前能提供更好的解决方案... 然后有人做到了

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接