Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Youtube Video Id from URL - Swift3

Basically I have a Youtube URL as string, I want to extract the video Id from that URL. I found some code in objective c that is as below:

NSError *error = NULL;
NSRegularExpression *regex = 
[NSRegularExpression regularExpressionWithPattern:@"?.*v=([^&]+)"
                                          options:NSRegularExpressionCaseInsensitive
                                            error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:youtubeURL
                                                options:0
                                                  range:NSMakeRange(0, [youtubeURL length])];
if (match) {
    NSRange videoIDRange = [match rangeAtIndex:1];
    NSString *substringForFirstMatch = [youtubeURL substringWithRange:videoIDRange];
}

When I am converting this code to swift3 that is:

var error: Error? = nil
var regex = try! NSRegularExpression(pattern: "?.*v=([^&]+)", options: .caseInsensitive)
var match = regex!.firstMatch(in: youtubeURL, options: [], range: NSRange(location: 0, length: youtubeURL.length))!
if match {
    var videoIDRange = match.rangeAt(1)
    var substringForFirstMatch = (youtubeURL as NSString).substring(with: videoIDRange)
}

Gives error as:

fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=2048 "The value “?.*v=([^&]+)” is invalid."

Can anybody help me about this error or anybody explain how to get video id from url in Swift 3.

Thanks in advance

like image 738
Susanta Sahu Avatar asked Dec 15 '16 14:12

Susanta Sahu


People also ask

How do I get the YouTube video ID from a URL?

The video ID will be located in the URL of the video page, right after the v= URL parameter. In this case, the URL of the video is: https://www.youtube.com/watch?v=aqz-KE-bpKQ. Therefore, the ID of the video is aqz-KE-bpKQ .

How is YouTube video ID generated?

Every YouTube video has a unique ID based on a counting system called Base 64. Randomly generated, that Base 64 ID allows YouTube to have a unique yet short url by using the alphabet in lowercase and uppercase plus two symbols: – and _.

What is the YT ID?

The YouTube ID will be the portion at the end of the URL after the last slash. In this example, the YouTube ID is "GYGIVAb5s4U".

How does YouTube video ID work?

Videos uploaded to YouTube are scanned against a database of audio and visual content that's been submitted to YouTube by copyright owners. When Content ID finds a match, it applies a Content ID claim to the matching video.


2 Answers

Safer version (without force unwrapping !):

extension String {
    var youtubeID: String? {
        let pattern = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"

        let regex = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive)
        let range = NSRange(location: 0, length: count)

        guard let result = regex?.firstMatch(in: self, range: range) else {
            return nil
        }

        return (self as NSString).substring(with: result.range)
    }
}

Examples:

"https://www.youtube.com/watch?v=C0DPdy98e4c".youtubeID // "C0DPdy98e4c"
"https://youtube.com/watch?v=C0DPdy98e4c".youtubeID // "C0DPdy98e4c"
"www.youtube.com/watch?v=C0DPdy98e4c".youtubeID // "C0DPdy98e4c"
"youtube.com/watch?v=C0DPdy98e4c".youtubeID // "C0DPdy98e4c"

"https://youtu.be/C0DPdy98e4c".youtubeID // "C0DPdy98e4c"
"youtu.be/C0DPdy98e4c".youtubeID // "C0DPdy98e4c"

Credits: Usman Nisar's answer

like image 64
Islam Avatar answered Nov 15 '22 23:11

Islam


Swift 5

var youtubeURLs = [
    "http://www.youtube.com/watch?v=-wtIMTCHWuI",
    "http://www.youtube.com/v/-wtIMTCHWuI?version=3&autohide=1",
    "http://youtu.be/-wtIMTCHWuI",
    "http://www.youtube.com/oembed?url=http%3A//www.youtube.com/watch?v%3D-wtIMTCHWuI&format=json",
    "https://youtu.be/uJ2PZaO1N5E",
    "https://www.youtube.com/embed/M7lc1UVf-VE",
    "http://www.youtube.com/attribution_link?a=JdfC0C9V6ZI&u=%2Fwatch%3Fv%3DEhxJLojIE_o%26feature%3Dshare",
    "https://www.youtube.com/attribution_link?a=8g8kPrPIi-ecwIsS&u=/watch%3Fv%3DyZv2daTWRZU%26feature%3Dem-uploademail"
]

func getVideoID(from urlString: String) -> String? {
    guard let url = urlString.removingPercentEncoding else { return nil }
    do {
        let regex = try NSRegularExpression.init(pattern: "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)", options: .caseInsensitive)
        let range = NSRange(location: 0, length: url.count)
        if let matchRange = regex.firstMatch(in: url, options: .reportCompletion, range: range)?.range {
            let matchLength = (matchRange.lowerBound + matchRange.length) - 1
            if range.contains(matchRange.lowerBound) &&
                range.contains(matchLength) {
                let start = url.index(url.startIndex, offsetBy: matchRange.lowerBound)
                let end = url.index(url.startIndex, offsetBy: matchLength)
                return String(url[start...end])
            }
        }
    } catch {
        print(error.localizedDescription)
    }
    return nil
}

for url in youtubeURLs {
    print("Video id: \(getVideoID(from: url) ?? "NA") for url: \(url)")
}

Result:

Video id: -wtIMTCHWuI for url: http://www.youtube.com/watch?v=-wtIMTCHWuI
Video id: -wtIMTCHWuI for url: http://www.youtube.com/v/-wtIMTCHWuI?version=3&autohide=1
Video id: -wtIMTCHWuI for url: http://youtu.be/-wtIMTCHWuI
Video id: -wtIMTCHWuI for url: http://www.youtube.com/oembed?url=http%3A//www.youtube.com/watch?v%3D-wtIMTCHWuI&format=json
Video id: uJ2PZaO1N5E for url: https://youtu.be/uJ2PZaO1N5E
Video id: M7lc1UVf-VE for url: https://www.youtube.com/embed/M7lc1UVf-VE
Video id: EhxJLojIE_o for url: http://www.youtube.com/attribution_link?a=JdfC0C9V6ZI&u=%2Fwatch%3Fv%3DEhxJLojIE_o%26feature%3Dshare
Video id: yZv2daTWRZU for url: https://www.youtube.com/attribution_link?a=8g8kPrPIi-ecwIsS&u=/watch%3Fv%3DyZv2daTWRZU%26feature%3Dem-uploademail
like image 26
arjavlad Avatar answered Nov 15 '22 23:11

arjavlad