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
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 .
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 _.
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".
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With