Youtube API - 提取视频ID

时间:2011-07-02 10:51:37

标签: php youtube

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

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

我正在使用PHP ...我很欣赏这方面的任何指针/代码示例。

由于

9 个答案:

答案 0 :(得分:79)

以下是一个示例函数,它使用正则表达式从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

采用of the answer from a similar question


这不是您正在寻找的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)))));

其中提供了有关网址的更多元信息:

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)
}

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

答案 1 :(得分:18)

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

所以我在上面的正则表达式中进行了一些修改,但是肯定可以归功于提供基本正则表达式的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;
 }

答案 2 :(得分:10)

您可以使用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));
}

答案 3 :(得分:1)

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

答案 4 :(得分:1)

我知道这是一个非常晚的答案,但我在搜索主题时找到了这个主题,因此我想建议使用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('/.*: (.*)/', '$1', $error['message']);
        return $error_message;
    }else{
        $movie_data = json_decode($movie_data_json, true);
        return $movie_data['html'];
    }
}

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

答案 5 :(得分:1)

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

VideoId是所有YouTube网址类型中最长的字词,它包含(字母数字+“ - ”),最小长度为8,由非字字符包围。因此,您可以在URL中搜索以下正则表达式作为一个组,并且第一组是您的答案。第一组是因为某些youtube参数(例如enablejsapi)超过8个字符,但它们总是位于videoId之后。

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

这是工作的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");
}

答案 6 :(得分:1)

如下面评论中提到的有效答案,我们就像这样使用它,它的效果非常好!

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;
}

答案 7 :(得分:0)

这个怎么样:

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;
}

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

答案 8 :(得分:0)

对于JAVA开发人员

这对我有用,还支持无cookie网址:

    private static final Pattern youtubeId = Pattern.compile("^(?:https?\\:\\/\\/)?.*(?:youtu.be\\/|vi?\\/|vi?=|u\\/\\w\\/|embed\\/|(watch)?vi?=)([^#&?]*).*$");


    @VisibleForTesting
    String getVideoId(final String url) {
        final Matcher matcher = youtubeId.matcher(url);
        if(matcher.find()){
            return matcher.group(2);
        }
        return "";
    }

一些检查youtube网址的测试

    @ParameterizedTest
    @MethodSource("youtubeTestUrls")
    void videoIdFromUrlTest(final String url, final String videoId) {

        final String matchedVidID = this.youtubeService.getVideoId(url);

        assertEquals(videoId, matchedVidID);
    }

    private static Stream<Arguments> youtubeTestUrls() {
        return Stream.of(
                Arguments.of("www.youtube-nocookie.com/embed/dQw4-9W_XcQ?rel=0", "dQw4-9W_XcQ"),
                Arguments.of("http://www.youtube.com/user/Scobleizer#p/u/1/dQw4-9W_XcQ", "dQw4-9W_XcQ"),
                Arguments.of("http://www.youtube.com/watch?v=dQw4-9W_XcQ&feature=channel", "dQw4-9W_XcQ"),
                Arguments.of("http://www.youtube.com/watch?v=dQw4-9W_XcQ&playnext_from=TL&videos=osPknwzXEas&feature=sub", "dQw4-9W_XcQ"),
                Arguments.of("http://www.youtube.com/ytscreeningroom?v=dQw4-9W_XcQ", "dQw4-9W_XcQ"),
                Arguments.of("http://www.youtube.com/user/SilkRoadTheatre#p/a/u/2/dQw4-9W_XcQ", "dQw4-9W_XcQ"),
                Arguments.of("http://youtu.be/dQw4-9W_XcQ", "dQw4-9W_XcQ"),
                Arguments.of("http://www.youtube.com/watch?v=dQw4-9W_XcQ&feature=youtu.be", "dQw4-9W_XcQ"),
                Arguments.of("http://youtu.be/dQw4-9W_XcQ", "dQw4-9W_XcQ"),
                Arguments.of("https://www.youtube.com/user/Scobleizer#p/u/1/dQw4-9W_XcQ?rel=0", "dQw4-9W_XcQ"),
                Arguments.of("http://www.youtube.com/watch?v=dQw4-9W_XcQ&playnext_from=TL&videos=dQw4-9W_XcQ&feature=sub", "dQw4-9W_XcQ"),
                Arguments.of("http://www.youtube.com/ytscreeningroom?v=dQw4-9W_XcQ", "dQw4-9W_XcQ"),
                Arguments.of("http://www.youtube.com/embed/dQw4-9W_XcQ?rel=0", "dQw4-9W_XcQ"),
                Arguments.of("https://www.youtube.com/watch?v=dQw4-9W_XcQ", "dQw4-9W_XcQ"),
                Arguments.of("http://youtube.com/v/dQw4-9W_XcQ?feature=youtube_gdata_player", "dQw4-9W_XcQ"),
                Arguments.of("http://youtube.com/vi/dQw4-9W_XcQ?feature=youtube_gdata_player", "dQw4-9W_XcQ"),
                Arguments.of("http://youtube.com/?v=dQw4-9W_XcQ&feature=youtube_gdata_player", "dQw4-9W_XcQ"),
                Arguments.of("http://www.youtube.com/watch?v=dQw4-9W_XcQ&feature=youtube_gdata_player", "dQw4-9W_XcQ"),
                Arguments.of("http://youtube.com/?vi=dQw4-9W_XcQ&feature=youtube_gdata_player", "dQw4-9W_XcQ"),
                Arguments.of("https://youtube.com/watch?v=dQw4-9W_XcQ&feature=youtube_gdata_player", "dQw4-9W_XcQ"),
                Arguments.of("http://youtube.com/watch?vi=dQw4-9W_XcQ&feature=youtube_gdata_player", "dQw4-9W_XcQ"),
                Arguments.of("http://youtu.be/dQw4-9W_XcQ?feature=youtube_gdata_player", "dQw4-9W_XcQ"),
                Arguments.of("https://www.youtube.com/watch?v=yYw2Q141thM&list=PLOwEeBApnYoUFioRitjwz-DREzFGOSgiE&index=2", "yYw2Q141thM"),
                Arguments.of("https://www.youtube.com/watch?", "")
        );
    }