Youtube Video Id from URL - Swift3

冷暖自知 提交于 2019-12-06 03:32:23

问题


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


回答1:


I have a different way of doing this using URLComponents. You then just select the 'v' parameter from the url, if it exists.

func getYoutubeId(youtubeUrl: String) -> String? {
    return URLComponents(string: youtubeUrl)?.queryItems?.first(where: { $0.name == "v" })?.value
}

And then pass in a Youtube url like this:

print (getYoutubeId(youtubeUrl: "https://www.youtube.com/watch?v=Y7ojcTR78qE&spfreload=9"))



回答2:


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




回答3:


Here is code to extract youtube video id from any youtube url: (Swift)

func extractYoutubeId(fromLink link: String) -> String {
        let regexString: String = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
        let regExp = try? NSRegularExpression(pattern: regexString, options: .caseInsensitive)
        let array: [Any] = (regExp?.matches(in: link, options: [], range: NSRange(location: 0, length: (link.characters.count ))))!
        if array.count > 0 {
            let result: NSTextCheckingResult? = array.first as? NSTextCheckingResult
            return (link as NSString).substring(with: (result?.range)!)
        }

        return ""
    }



回答4:


A Swift 4 version using the elegant flatMap:

func extractYouTubeId(from url: String) -> String? {
    let typePattern = "(?:(?:\\.be\\/|embed\\/|v\\/|\\?v=|\\&v=|\\/videos\\/)|(?:[\\w+]+#\\w\\/\\w(?:\\/[\\w]+)?\\/\\w\\/))([\\w-_]+)"
    let regex = try? NSRegularExpression(pattern: typePattern, options: .caseInsensitive)
    return regex
        .flatMap { $0.firstMatch(in: url, range: NSMakeRange(0, url.count)) }
        .flatMap { Range($0.range(at: 1), in: url) }
        .map { String(url[$0]) }
}

This method uses a regex that detects most of the possible YouTube URL formats (.be/*, /embed/, /v/ - you can find the full list here).




回答5:


Your first problem is you are not escaping ? in your expression. ? is reserved character and if you want to use it in your expressions, you must escape with \ and since \ is used also to escape " character you must escape ? with double backslash something like \\?. So according to above information, following code correctly extracts the videoId

let youtubeURL = "https://www.youtube.com/watch?v=uH8o-JTHJdM"
let regex = try! NSRegularExpression(pattern: "\\?.*v=([^&]+)", options: .caseInsensitive)
let match = regex.firstMatch(in: youtubeURL, options: [], range: NSRange(location: 0, length: youtubeURL.characters.count))
if let videoIDRange = match?.rangeAt(1) {
    let substringForFirstMatch = (youtubeURL as NSString).substring(with: videoIDRange)
} else {
    //NO video URL
}



回答6:


To get video Id from Youtube Url, use code # Swift4 :

var videoId = ""

    if youtubeLink.lowercased().contains("youtu.be"){
            linkString = youtubeLink
            if let range = linkString.range(of: "be/"){
                videoId = youtubeLink[range.upperBound...].trimmingCharacters(in: .whitespaces)
            }
        }
        else if youtubeLink.lowercased().contains("youtube.com"){
            linkString = youtubeLink
            if let range = linkString.range(of: "?v="){
                videoId = youtubeLink[range.upperBound...].trimmingCharacters(in: .whitespaces)
            }
        }

Hope will be helping! :)



来源:https://stackoverflow.com/questions/41166092/youtube-video-id-from-url-swift3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!