0

Here's the scenario, I have a site with thousands of YouTube video posts which are stored in a custom field 'video_url' which is being used in a custom video player.

The custom player I'm using now doesn't take the entire YouTube URL but instead just the video ID. What I need to do is figure out how to grab the YouTube video ID from the url in the custom field and place that into a HTML 5 video attribute.

<video class="custom-player" data-youtube-id="YOUTUBE_ID_HERE" width="700" height="420" preload="none"></video>

Thanks.

Update: Answer

Credits to Chandan Chaudhary https://gist.github.com/ckchaudhary/8629242#file-get-youtube-video-id-from-url

Add the following to the functions.php file.

function extractUTubeVidId($url){
    /*
    * type1: http://www.youtube.com/watch?v=9Jr6OtgiOIw
    * type2: http://www.youtube.com/watch?v=9Jr6OtgiOIw&feature=related
    * type3: http://youtu.be/9Jr6OtgiOIw
    */
    $vid_id = "";
    $flag = false;
    if(isset($url) && !empty($url)){
        /*case1 and 2*/
        $parts = explode("?", $url);
        if(isset($parts) && !empty($parts) && is_array($parts) && count($parts)>1){
            $params = explode("&", $parts[1]);
            if(isset($params) && !empty($params) && is_array($params)){
                foreach($params as $param){
                    $kv = explode("=", $param);
                    if(isset($kv) && !empty($kv) && is_array($kv) && count($kv)>1){
                        if($kv[0]=='v'){
                            $vid_id = $kv[1];
                            $flag = true;
                            break;
                        }
                    }
                }
            }
        }

        /*case 3*/
        if(!$flag){
            $needle = "youtu.be/";
            $pos = null;
            $pos = strpos($url, $needle);
            if ($pos !== false) {
                $start = $pos + strlen($needle);
                $vid_id = substr($url, $start, 11);
                $flag = true;
            }
        }
    }
    return $vid_id;
}

The add this to the post loop.

<?php 
$videoID = get_post_meta($post->ID, 'video_url', true); 
echo $youtube_video_id = extractUTubeVidId($videoID);   
?>

Change 'video_url' to whatever custom field name your YouTube video URLs are stored in.

3
  • Do you know how to get the URL and you're just asking how to split it?
    – mor7ifer
    Jan 28, 2015 at 22:31
  • I figured it out, I updated my question.
    – Chozen
    Jan 28, 2015 at 23:15
  • 1
    Submit your solution as an answer and mark it solved so that the question does not go listed as unanswered. Also, fwiw, you probably want to look at PHP's parse_url() as it may lend itself to a slightly better solution.
    – mor7ifer
    Jan 28, 2015 at 23:23

5 Answers 5

1

An alternative would be to use WordPress's build in auto embed, the following line in core is responsible for auto embed:

add_filter( 'the_content', array(&$this, 'autoembed'), 8 ); 

Which means: Whenever we are about to display content try to auto embed all url's with a priority of 8.

You could add a custom filter before this one to add the youtube url's, like so:

add_filter( 'the_content', 'prefix_add_youtube_videos', 7 );
function prefix_add_youtube_videos( $content ) {
    $video = get_post_meta( get_the_ID(), 'video_url', true );
    if ( ! empty( $video ) ) {
        $content .= $video;
    }

    return $content;
}

So we add our function with priority 7 so it's before WordPress's auto embed and so WordPress will embed the video for us. That is less code you'll have to maintain.

PS Embedding is good! Don't freeboot!

2
  • But how would that work in a custom video player.
    – Chozen
    Jan 28, 2015 at 23:46
  • It doesn't work with a custom video player, I'm just giving an alternative answer. Jan 28, 2015 at 23:48
1

Credits to Chandan Chaudhary https://gist.github.com/ckchaudhary/8629242#file-get-youtube-video-id-from-url

Add the following to the functions.php file.

function extractUTubeVidId($url){
    /*
    * type1: http://www.youtube.com/watch?v=9Jr6OtgiOIw
    * type2: http://www.youtube.com/watch?v=9Jr6OtgiOIw&feature=related
    * type3: http://youtu.be/9Jr6OtgiOIw
    */
    $vid_id = "";
    $flag = false;
    if(isset($url) && !empty($url)){
        /*case1 and 2*/
        $parts = explode("?", $url);
        if(isset($parts) && !empty($parts) && is_array($parts) && count($parts)>1){
            $params = explode("&", $parts[1]);
            if(isset($params) && !empty($params) && is_array($params)){
                foreach($params as $param){
                    $kv = explode("=", $param);
                    if(isset($kv) && !empty($kv) && is_array($kv) && count($kv)>1){
                        if($kv[0]=='v'){
                            $vid_id = $kv[1];
                            $flag = true;
                            break;
                        }
                    }
                }
            }
        }

        /*case 3*/
        if(!$flag){
            $needle = "youtu.be/";
            $pos = null;
            $pos = strpos($url, $needle);
            if ($pos !== false) {
                $start = $pos + strlen($needle);
                $vid_id = substr($url, $start, 11);
                $flag = true;
            }
        }
    }
    return $vid_id;
}

The add this to the post loop.

<?php 
$videoID = get_post_meta($post->ID, 'video_url', true); 
echo $youtube_video_id = extractUTubeVidId($videoID);   
?>

Change 'video_url' to whatever custom field name your YouTube video URLs are stored in.

0

If you have any, even basic experience with PHP, this can be rather straight forward to setup.

Have a look at explode and substr.

<?php

  // explode() will split the string up into an array, for ex:
  $youtube_url = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
  $youtube_array = explode('?v=', $youtube_url);

  // we used '?v=' as the delimter, so explode will create an array of two parts, the first being everything before the delimiter and the second being everything after (the YouTube ID)

        print_r($youtube_array);
        // will print: Array ( [0] => https://www.youtube.com/watch [1] => dQw4w9WgXcQ )

        echo $youtube_array[1];
        // will echo: dQw4w9WgXcQ
?>

If all your inputed YouTube links follow the exact same format (for ex: https://www.youtube.com/watch?v=dQw4w9WgXcQ) then our work here is done. But, we all know that YouTube links come in all shapes and sizes with extra variables attached.

<?php

  // lets use a more complicated link
  $youtube_url = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ&list=RDdQw4w9WgXcQ#t=0';
  $youtube_array = explode('?v=', $youtube_url);

        print_r($youtube_array);
        // will print: Array ( [0] => https://www.youtube.com/watch [1] => dQw4w9WgXcQ&list=RDdQw4w9WgXcQ#t=0 )

        echo $youtube_array[1];
        // will echo: dQw4w9WgXcQ&list=RDdQw4w9WgXcQ#t=0

        // we can use substr() to pull out just the id by cuting it down to the first 11 characters of the string, all YouTube IDs are 11 characters
        $youtube_id = substr($youtube_array[1], 0, 11);

        echo $youtube_id;
        // will echo: dQw4w9WgXcQ
?>  

Of course, some YouTube links can also follow this format: http://youtu.be/dQw4w9WgXcQ. Which would use a different delimiter .be/ and you could write a function to check for both. Please let us know your PHP experience level. And check to see how all your links are formatted. And have a look at those two functions above.

2
  • Sorry, should have mentioned I'm a PHP beginner.
    – Chozen
    Jan 28, 2015 at 21:09
  • I don't mean to sound condescending, but even so, you could probably figure this out from my examples. I'm no super PHP user either, and explode was one of the first functions I ever learned.
    – deflime
    Jan 28, 2015 at 21:11
0

You could use this directly in a template or with some type of action or filter hook

wp_oembed_get( get_post_meta( get_the_ID(), 'video_url', true ) );
-1

I use a regular expression to match and return a youtube video id from a url:

<?php    
  /**
   * Match non-linked youtube URL in the wild.
   * : Regex Overview/Pseudo-code :
   * 
   * Required scheme. Either http or https.
   * Optional subdomain.
   * Group host alternatives.
   * Either youtu.be
   * or youtube.com 
   * or youtube-nocookie.com
   * followed by
   * Allow anything up to VIDEO_ID,
   * but char before ID is non-ID char.
   * End host alternatives.
   * $1: VIDEO_ID is exactly 11 chars.
   * Assert next char is non-ID or EOS.
   * Assert URL is not pre-linked.
   * Allow URL (query) remainder.
   * Group pre-linked alternatives.
   * Either inside a start tag,
   * or inside <a> element text contents.
   * End recognized pre-linked alts.
   * End negative lookahead assertion.
   * Consume any URL (query) remainder.
   */

function getYoutubeVideoID ( $youtube_url ) {

  return preg_replace('~https?://(?:[0-9A-Z-]+\.)?(?:youtu\.be/| youtube(?:-nocookie)?\.com\S*[^\w\s-])([\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:[\'"][^<>]*>| </a>))[?=&+%\w.-]*~ix', '$1', $youtube_url);

}

Call function by providing youtube url, like so:

// example urls
$this_video_url = 'https://youtu.be/RVWtSsMUBD0';
$this_video_url = 'https://www.youtube.com/watch?v=RVWtSsMUBD0';

$this_youtube_id = getYoutubeVideoID( $this_video_url );
echo 'YouTube ID: ' . $this_youtube_id;
3
  • I think you messed the regex comments up. They belong into the regex behind a #.
    – fuxia
    Dec 30, 2015 at 19:54
  • @toscho I'm not sure I've messed anything up. I'm able to copy+paste and run this code. Would you mind elaborating? Thanks :-) Dec 30, 2015 at 20:15
  • The modifier x says that you can embed comments in the regex to explain each part better. Putting these comments on top is rather confusing. See wpkrauts.com/2013/enforce-utf-8-with-php for an example.
    – fuxia
    Dec 30, 2015 at 22:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.