php Youtube API - 提取视频 ID

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6556559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 00:42:54  来源:igfitidea点击:

Youtube API - Extract video ID

phpyoutube

提问by Gabriel Spiteri

I am coding a functionality that allows users to enter a Youtube video URL. I would like to extract the video ID from these urls.

我正在编写一个允许用户输入 Youtube 视频 URL 的功能。我想从这些网址中提取视频 ID。

Does Youtube API support some kind of function where I pass the link and it gives the video ID in return. Or do I have to parse the string myself?

Youtube API 是否支持我传递链接的某种功能,并提供视频 ID 作为回报。还是我必须自己解析字符串?

I am using PHP ... I would appreciate any pointers / code samples in this regard.

我正在使用 PHP ......我将不胜感激这方面的任何指针/代码示例。

Thanks

谢谢

回答by hakre

Here is an example function that uses a regular expression to extract the youtube ID from a URL:

下面是一个使用正则表达式从 URL 中提取 youtube ID 的示例函数:

/**
 * get youtube video ID from URL
 *
 * @param string $url
 * @return string Youtube video id or FALSE if none found. 
 */
function youtube_id_from_url($url) {
    $pattern = 
        '%^# Match any youtube URL
        (?:https?://)?  # Optional scheme. Either http or https
        (?:www\.)?      # Optional www subdomain
        (?:             # Group host alternatives
          youtu\.be/    # Either youtu.be,
        | youtube\.com  # or youtube.com
          (?:           # Group path alternatives
            /embed/     # Either /embed/
          | /v/         # or /v/
          | /watch\?v=  # or /watch\?v=
          )             # End path alternatives.
        )               # End host alternatives.
        ([\w-]{10,12})  # Allow 10-12 for 11 char youtube id.
        $%x'
        ;
    $result = preg_match($pattern, $url, $matches);
    if ($result) {
        return $matches[1];
    }
    return false;
}

echo youtube_id_from_url('http://youtu.be/NLqAF9hrVbY'); # NLqAF9hrVbY

It's an adoption of the answer from a similar question.

这是对类似问题的答案的采用。



It's not directly the API you're looking for but probably helpful. Youtube has an oembedservice:

它不是您正在寻找的直接 API,但可能有帮助。Youtube 有一个oembed服务:

$url = 'http://youtu.be/NLqAF9hrVbY';
var_dump(json_decode(file_get_contents(sprintf('http://www.youtube.com/oembed?url=%s&format=json', urlencode($url)))));

Which provides some more meta-information about the URL:

它提供了一些关于 URL 的更多元信息:

object(stdClass)#1 (13) {
  ["provider_url"]=>
  string(23) "http://www.youtube.com/"
  ["title"]=>
  string(63) "Hang Gliding: 3 Flights in 8 Days at Northside Point of the Mtn"
  ["html"]=>
  string(411) "<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/NLqAF9hrVbY?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/NLqAF9hrVbY?version=3" type="application/x-shockwave-flash" width="425" height="344" allowscriptaccess="always" allowfullscreen="true"></embed></object>"
  ["author_name"]=>
  string(11) "widgewunner"
  ["height"]=>
  int(344)
  ["thumbnail_width"]=>
  int(480)
  ["width"]=>
  int(425)
  ["version"]=>
  string(3) "1.0"
  ["author_url"]=>
  string(39) "http://www.youtube.com/user/widgewunner"
  ["provider_name"]=>
  string(7) "YouTube"
  ["thumbnail_url"]=>
  string(48) "http://i3.ytimg.com/vi/NLqAF9hrVbY/hqdefault.jpg"
  ["type"]=>
  string(5) "video"
  ["thumbnail_height"]=>
  int(360)
}

But the ID is not a direct part of the response. However it might contain the information you're looking for and it might be useful to validate the youtube URL.

但 ID 不是响应的直接部分。但是,它可能包含您要查找的信息,并且验证 youtube URL 可能很有用。

回答by Sabeeh Chaudhry

I am making slight changes in the above regular expression, although it is working fine for youtube short URL (which have been used in the above example) and simple video URL where no other parameter is coming after video code, but it does not work for URLs like http://www.youtube.com/watch?v=B_izAKQ0WqQ&feature=relatedas video code is not the last parameter in this URL. In the same way v={video_code} does not always come after watch (whereas above regular expression is assuming that it will always come after watch?), like if user has selected language OR location from the footer, for example if user has selected English (UK) from Language option then URL will be http://www.youtube.com/watch?feature=related&hl=en-GB&v=B_izAKQ0WqQ

我对上面的正则表达式做了一些细微的改变,虽然它对 youtube 短 URL(在上面的例子中使用过)和简单的视频 URL 工作正常,在视频代码之后没有其他参数,但它不适用于像 http://www.youtube.com/watch?v=B_izAKQ0WqQ&feature=related作为视频代码这样的 URL 不是此 URL 中的最后一个参数。以同样的方式 v={video_code} 并不总是在观看后出现(而上面的正则表达式假设它总是在观看后出现?),例如如果用户从页脚选择了语言或位置,例如如果用户选择了来自语言选项的英语(英国)然后 URL 将是http://www.youtube.com/watch?feature=related&hl=en-GB&v=B_izAKQ0WqQ

So I have made some modification in the above regular expressions, but definitely credit goes to hakre for providing the base regular expression, thanks @hakre:

所以我对上面的正则表达式做了一些修改,但肯定归功于 hakre 提供了基本的正则表达式,谢谢@hakre:

function youtube_id_from_url($url) {
   $pattern =
    '%^# Match any youtube URL
    (?:https?://)?  # Optional scheme. Either http or https
    (?:www\.)?      # Optional www subdomain
    (?:             # Group host alternatives
      youtu\.be/    # Either youtu.be,
    | youtube\.com  # or youtube.com
      (?:           # Group path alternatives
        /embed/     # Either /embed/
      | /v/         # or /v/
      | .*v=        # or /watch\?v=
      )             # End path alternatives.
    )               # End host alternatives.
    ([\w-]{10,12})  # Allow 10-12 for 11 char youtube id.
    ($|&).*         # if additional parameters are also in query string after video id.
    $%x'
    ;
    $result = preg_match($pattern, $url, $matches);
    if (false !== $result) {
      return $matches[1];
    }
    return false;
 }

回答by Salman A

You can use the PHP function parse_urlto extract host name, path, query string and the fragment. You can then use PHP string functions to locate the video id.

您可以使用 PHP 函数parse_url提取主机名、路径、查询字符串和片段。然后,您可以使用 PHP 字符串函数来定位视频 ID。

function getYouTubeVideoId($url)
{
    $video_id = false;
    $url = parse_url($url);
    if (strcasecmp($url['host'], 'youtu.be') === 0)
    {
        #### (dontcare)://youtu.be/<video id>
        $video_id = substr($url['path'], 1);
    }
    elseif (strcasecmp($url['host'], 'www.youtube.com') === 0)
    {
        if (isset($url['query']))
        {
            parse_str($url['query'], $url['query']);
            if (isset($url['query']['v']))
            {
                #### (dontcare)://www.youtube.com/(dontcare)?v=<video id>
                $video_id = $url['query']['v'];
            }
        }
        if ($video_id == false)
        {
            $url['path'] = explode('/', substr($url['path'], 1));
            if (in_array($url['path'][0], array('e', 'embed', 'v')))
            {
                #### (dontcare)://www.youtube.com/(whitelist)/<video id>
                $video_id = $url['path'][1];
            }
        }
    }
    return $video_id;
}
$urls = array(
    'http://youtu.be/dQw4w9WgXcQ',
    'http://www.youtube.com/?v=dQw4w9WgXcQ',
    'http://www.youtube.com/?v=dQw4w9WgXcQ&feature=player_embedded',
    'http://www.youtube.com/watch?v=dQw4w9WgXcQ',
    'http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=player_embedded',
    'http://www.youtube.com/v/dQw4w9WgXcQ',
    'http://www.youtube.com/e/dQw4w9WgXcQ',
    'http://www.youtube.com/embed/dQw4w9WgXcQ'
);
foreach ($urls as $url)
{
    echo sprintf('%s -> %s' . PHP_EOL, $url, getYouTubeVideoId($url));
}

回答by KJS

As mentioned in a comment below the valid answer, we use it like this, and it works mighty fine!

正如在有效答案下方的评论中所提到的,我们像这样使用它,并且效果很好!

function youtube_id_from_url($url) {

$url = trim(strtok("$url", '?'));
$url = str_replace("#!/", "", "$url");

    $pattern = 
        '%^# Match any youtube URL
        (?:https?://)?  # Optional scheme. Either http or https
        (?:www\.)?      # Optional www subdomain
        (?:             # Group host alternatives
          youtu\.be/    # Either youtu.be,
        | youtube\.com  # or youtube.com
          (?:           # Group path alternatives
            /embed/     # Either /embed/
          | /v/         # or /v/
          | /watch\?v=  # or /watch\?v=
          )             # End path alternatives.
        )               # End host alternatives.
        ([\w-]{10,12})  # Allow 10-12 for 11 char youtube id.
        $%x'
        ;
    $result = preg_match($pattern, $url, $matches);
    if ($result) {
        return $matches[1];
    }
    return false;
}

回答by dctremblay

Simple as return substr(strstr($url, 'v='), 2, 11);

简单如 return substr(strstr($url, 'v='), 2, 11);

回答by A. Genedy

I know this is a very late answer but I found this thread while searching for the topic so I want to suggest a more elegant way of doing this using oEmbed:

我知道这是一个很晚的答案,但我在搜索主题时发现了这个线程,所以我想建议使用oEmbed更优雅的方法:

echo get_embed('youtube', 'https://www.youtube.com/watch?v=IdxKPCv0bSs');

function get_embed($provider, $url, $max_width = '', $max_height = ''){
    $providers = array(
        'youtube' => 'http://www.youtube.com/oembed'
        /* you can add support for more providers here */
    );

    if(!isset($providers[$provider])){
        return 'Invalid provider!';
    }

    $movie_data_json = @file_get_contents(
        $providers[$provider] . '?url=' . urlencode($url) . 
        "&maxwidth={$max_width}&maxheight={$max_height}&format=json"
    );

    if(!$movie_data_json){
        $error = error_get_last();
        /* remove the PHP stuff from the error and show only the HTTP error message */
        $error_message = preg_replace('/.*: (.*)/', '', $error['message']);
        return $error_message;
    }else{
        $movie_data = json_decode($movie_data_json, true);
        return $movie_data['html'];
    }
}

oEmbed makes it possible to embed content from more sites by just adding their oEmbed API endpoint to the $providersarray in the above code.

oEmbed 只需将其 oEmbed API 端点添加到上述代码中的$providers数组,就可以嵌入来自更多站点的内容。

回答by dsbajna

Here is a simple solution that has worked for me.

这是一个对我有用的简单解决方案。

VideoId is the longest word in any YouTube URL types and it comprises (alphanumeric + "-") with minimum length of 8 surrounded by non-word chars. So you can search for below regex in the URL as a group and that first group is your answer. First group because some youtube parameters such as enablejsapi are more than 8 chars but they always come after videoId.

VideoId 是任何 YouTube URL 类型中最长的单词,它由(字母数字 +“-”)组成,最小长度为 8,由非单词字符包围。所以你可以在 URL 中搜索下面的正则表达式作为一个组,第一组就是你的答案。第一组,因为一些 youtube 参数(例如 enablejsapi)超过 8 个字符,但它们总是在 videoId 之后。

Regex: "\W([\w-]{9,})(\W|$)"

正则表达式:“\W([\w-]{9,})(\W|$)”

Here is the working java code:

这是工作的java代码:

String[] youtubeUrls = {
    "https://www.youtube.com/watch?v=UzRtrjyDwx0",
    "https://youtu.be/6butf1tEVKs?t=22s",
    "https://youtu.be/R46-XgqXkzE?t=2m52s",
    "http://youtu.be/dQw4w9WgXcQ",
    "http://www.youtube.com/?v=dQw4w9WgXcQ",
    "http://www.youtube.com/?v=dQw4w9WgXcQ&feature=player_embedded",
    "http://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=player_embedded",
    "http://www.youtube.com/v/dQw4w9WgXcQ",
    "http://www.youtube.com/e/dQw4w9WgXcQ",
    "http://www.youtube.com/embed/dQw4w9WgXcQ"
};

String pattern = "\W([\w-]{9,})(\W|$)";
Pattern pattern2 = Pattern.compile(pattern);

for (int i=0; i<youtubeUrls.length; i++){
    Matcher matcher2 = pattern2.matcher(youtubeUrls[i]);
    if (matcher2.find()){
        System.out.println(matcher2.group(1));
    }
    else System.out.println("Not found");
}

回答by petwho

How about this one:

这个怎么样:

function getVideoId() {
    $query = parse_url($this->url, PHP_URL_QUERY);

    $arr = explode('=', $query);

    $index = array_search('v', $arr);

    if ($index !== false) {
        if (isset($arr[$index++])) {
            $string = $arr[$index++];
            if (($amp = strpos($string, '&')) !== false) {
                return substr($string, 0, $amp);
            } else {
                return $string;
            }
        } else {
            return false;
        }
    }
    return false;
}

No regex, support multiple query parameters, i.e, https://www.youtube.com/watch?v=PEQxWg92Ux4&index=9&list=RDMMom0RGEnWIEkalso works.

没有正则表达式,支持多个查询参数,即https://www.youtube.com/watch?v=PEQxWg92Ux4&index=9&list=RDMMom0RGEnWIEk也有效。