Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get YouTube video id from URL with jQuery

I'm trying to take a textarea input that takes any YouTube URL as the input and embed the video much like Facebook does.

I have:

var text = $('#content').val().split(' ');
    for (i = 0; i < text.length; i++) {
        var test = text[i].indexOf('youtube.com/watch');
        var check = text[i].indexOf('[youtube=');

        if (test != -1 && check == -1) {
            var ytid = text[i].substring(text[i].lastIndexOf('=') + 1);
            text[i] = '[youtube=' + ytid + ']';
        }
    }
var boxval = text.join(' ').trim();

which takes any YouTube URL and makes it into a [youtube=videoid]. Problem then is that when a URL is submitted with a <br> or a \n at the end it adds the ] afterwards.

Anyone know of a better way?

like image 868
Ryan Avatar asked Mar 25 '11 07:03

Ryan


2 Answers

A similar question was recently asked (but that question wanted a PHP solution). Here is a JavaScript version of my solution to that question:

// Linkify youtube URLs which are not already links.
function linkifyYouTubeURLs(text) {
    /* Commented regex (in PHP syntax)
    $text = preg_replace('%
        # Match any youtube URL in the wild.
        (?: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})  # $1: Allow 10-12 for 11 char youtube id.
        \b               # Anchor end to word boundary.
        [?=&\w]*         # Consume any URL (query) remainder.
        (?!              # But don\'t match URLs already linked.
          [\'"][^<>]*>   # Not inside a start tag,
        | </a>           # or <a> element text contents.
        )                # End negative lookahead assertion.
        %ix', 
        '<a href="http://www.youtube.com/watch?v=$1">YouTube link: $1</a>',
        $text);
    */
    // Here is the same regex in JavaScript literal regexp syntax:
    return text.replace(
        /(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com(?:\/embed\/|\/v\/|\/watch\?v=))([\w\-]{10,12})\b[?=&\w]*(?!['"][^<>]*>|<\/a>)/ig,
        '<a href="http://www.youtube.com/watch?v=$1">YouTube link: $1</a>');
}

You can easily modify the replacement string to convert to a BBCode rather than HTML.

like image 144
ridgerunner Avatar answered Sep 18 '22 02:09

ridgerunner


Regular expressions to the rescue:

var text = (
"http://www.youtube.com/watch?v=gzDS-Kfd5XQ\n" +
"http://www.youtube.com/watch?v=gzDS-Kfd5XQ&feature=youtube_gdata_player\n" +
"http://www.youtube.com/watch?feature=youtube_gdata_player&v=gzDS-Kfd5XQ\n" +
"http://www.youtube.com/watch?v=gzDS-Kfd5XQ http://www.youtube.com/watch?v=gzDS-Kfd5XQ"
).split(/\s+/);
for (var i = 0; i < text.length; i++) {
    var url = text[i];
    if (/^https?\:\/\/.+/i.test(url)) {
        var temp = /[\?\&]v=([^\?\&]+)/.exec(url);
        if (temp) {
            text[i] = '[youtube=' + temp[1] + ']';
        } else {
            text[i] = "URL found but does not contain video id";
        }
    } else {
        // other case left as an exercise
    }
}
alert(text.join('\n'));

Code borrowed from here.

like image 22
Salman A Avatar answered Sep 22 '22 02:09

Salman A