Youtube Video ID From URL - Objective C

后端 未结 16 782
失恋的感觉
失恋的感觉 2020-12-22 23:23

I basically have a Youtube url as an NSString, but I need to extract the video id that is displayed in the url. I found many tutorials on how to do this in php or and other

相关标签:
16条回答
  • 2020-12-22 23:50

    Here is my solution which referenced from StackOveFlow. (Youtube I.D parsing for new URL formats)

    I did some modification.

    ///This is the .h

    #import <Foundation/Foundation.h>
    @interface YoutubeParser : NSObject
    
    +(BOOL) isValidateYoutubeURL:(NSString * )youtubeURL;
    
    +(NSArray *) parseHTML:(NSString *)html ;
    
    @end
    
    ///This is the .m 
    #import "YoutubeParser.h"
    
    @interface YoutubeParser () {
    }
    
    @end
    
    @implementation YoutubeParser
    
    #define YOUTUBE_PATTERN @"(https?://)?(www\\.)?(youtu\\.be/|youtube\\.com)?(/|/embed/|/v/|/watch\\?v=|/watch\\?.+&v=)([\\w_-]{11})(&.+)?"
    
    +(NSRegularExpression *)regex {
    
        static NSRegularExpression * regex = nil;
    
        regex =     [NSRegularExpression regularExpressionWithPattern:YOUTUBE_PATTERN
                                                                   options:NSRegularExpressionCaseInsensitive
                                                                     error:nil];
        return regex;
    }
    
    +(BOOL) isValidateYoutubeURL:(NSString * )youtubeURL {
        NSInteger cnt = [[YoutubeParser regex] numberOfMatchesInString:youtubeURL options:0 range:NSMakeRange(0, [youtubeURL length])  ];
    
        return cnt > 0 ? YES : NO;
    }
    
    typedef void (^matching_block_t)  (NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop);
    
    +(NSArray *) parseHTML:(NSString *)html {
        NSMutableArray * youtubeURLArray = [[NSMutableArray alloc] init];
    
        matching_block_t parseTask = ^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
            NSRange matchRange = [result range];
            NSRange youtubeKey = [result rangeAtIndex:5]; //the youtube key
            NSString * strKey = [html substringWithRange:youtubeKey] ;
            NSLog(@"youtubeKey=%@ , with url=%@ " ,strKey , [html substringWithRange:matchRange]);
    
            [youtubeURLArray addObject:strKey];
        };
    
        [[YoutubeParser regex] enumerateMatchesInString:html   options:0   range:NSMakeRange(0, [html length])   usingBlock:parseTask ];
    
        return youtubeURLArray;
    }
    
    @end
    
    0 讨论(0)
  • 2020-12-22 23:53

    Based on this answer: PHP Regex to get youtube video ID?

    I adapted a regex for c/objc/c++ string, the important part here is that the regex doesn't get videos from facebook or other services. iOS regex is based on: ICU

    NSString *regexString = @"^(?:http(?:s)?://)?(?:www\\.)?(?:m\\.)?(?:youtu\\.be/|youtube\\.com/(?:(?:watch)?\\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)/))([^\?&\"'>]+)";
    
    NSError *error;
    NSRegularExpression *regex =
    [NSRegularExpression regularExpressionWithPattern:regexString
                                              options:NSRegularExpressionCaseInsensitive
                                                error:&error];
    NSTextCheckingResult *match = [regex firstMatchInString:message
                                                    options:0
                                                      range:NSMakeRange(0, [message length])];
    
    if (match && match.numberOfRanges == 2) {
        NSRange videoIDRange = [match rangeAtIndex:1];
        NSString *videoID = [message substringWithRange:videoIDRange];
    
        return videoID;
    }
    

    Matches:

    • youtube.com/v/vidid
    • youtube.com/vi/vidid
    • youtube.com/?v=vidid
    • youtube.com/?vi=vidid
    • youtube.com/watch?v=vidid
    • youtube.com/watch?vi=vidid
    • youtu.be/vidid
    • youtube.com/embed/vidid
    • http://youtube.com/v/vidid
    • http://www.youtube.com/v/vidid
    • https://www.youtube.com/v/vidid
    • youtube.com/watch?v=vidid&wtv=wtv
    • http://www.youtube.com/watch?dev=inprogress&v=vidid&feature=related
    • https://m.youtube.com/watch?v=vidid

    Does not match:

    • www.facebook.com?wtv=youtube.com/v/vidid
    • https://www.facebook.com/video.php?v=10155279523025107
    0 讨论(0)
  • 2020-12-22 23:54

    There is a lot of good answers here but I thought it might be beneficial to some to parse multiple video_ID from a string. This could be a web page or an array of different URL.

    Example of page content

    NSString *content = @"http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo,http://youtu.be/NLqAF9hrVbY,http://www.youtube.com/watch?v=NLqAF9hrVbY,http://facebook.com,http://www.youtube.com/watch?v=cAcqdjLCN7s";
    

    Method

    -(NSArray *)extractVideos:(NSString *)content {
        NSString *extractRegex = @"(?<=v(=|/))([-a-zA-Z0-9_]+)|(?<=youtu.be/)([-a-zA-Z0-9_]+)"
        NSMutableArray *extractedContent = [[NSMutableArray alloc] init];
        if ([content hasPrefix:@"http://"] || [content hasPrefix:@"https://"]) {
            NSURL *extractURL = [NSURL URLWithString:content];
            if ([extractURL.host rangeOfString:@"youtu"].location != NSNotFound) {
                NSRegularExpression *extractRegex = [NSRegularExpression regularExpressionWithPattern:extractRegex options:NSRegularExpressionCaseInsensitive error:nil];
                NSArray *extractResults = [extractRegex matchesInString:content options:0 range:NSMakeRange(0, content.length)];
                for (NSTextCheckingResult *match in extractResults) {
                    [extractedContent addObject:[content substringWithRange:match.range]];
    
                }
    
            }
    
        }
    
        return extractedContent;
    
    }
    

    Output

    ( 
        NLqAF9hrVbY,
        QLqAF9eeVbY,
        cAcqdjLCN7s
    )
    

    Credit to @Alex for the Regex

    0 讨论(0)
  • 2020-12-22 23:55

    You don't even need regexes. The following works regardless of the length of the video ID and its position within the URL:

    NSString *vID = nil;
    NSString *url = @"http://www.youtube.com/watch?v=cAcqdjLCN7s";
    
    NSString *query = [url componentsSeparatedByString:@"?"][1];
    NSArray *pairs = [query componentsSeparatedByString:@"&"];
    for (NSString *pair in pairs) {
        NSArray *kv = [pair componentsSeparatedByString:@"="];
        if ([kv[0] isEqualToString:@"v"]) {
            vID = kv[1];
            break;
        }
    }
    
    NSLog(@"%@", vID);
    
    0 讨论(0)
  • 2020-12-22 23:55

    I figured it out by myself...

    NSArray *videoURLSplit = [videoURL componentsSeparatedByString:@"v="];
    NSString *videoID = [[videoURLSplit objectAtIndex:1] substringToIndex:11];
    NSLog(@"%@",videoID);
    

    Very simple... All video urls contain v=VIDEO_ID I just separated the url into an array and then took the first 11 digits of what is after v= since there could be more http GET information in the url...

    Thanks for helping though!

    0 讨论(0)
  • 2020-12-22 23:58

    Here is RegExp it cover these cases

    Objective C

    - (NSString *)extractYoutubeIdFromLink:(NSString *)link {
        NSString *regexString = @"((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)";
        NSRegularExpression *regExp = [NSRegularExpression regularExpressionWithPattern:regexString
                                                                                options:NSRegularExpressionCaseInsensitive
                                                                                  error:nil];
    
        NSArray *array = [regExp matchesInString:link options:0 range:NSMakeRange(0,link.length)];
        if (array.count > 0) {
            NSTextCheckingResult *result = array.firstObject;
            return [link substringWithRange:result.range];
        }
        return nil;
    }
    

    Swift

    func extractYoutubeIdFromLink(link: String) -> String? {
        let pattern = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
        guard let regExp = try? NSRegularExpression(pattern: pattern, options: .CaseInsensitive) else {
            return nil
        }
        let nsLink = link as NSString
        let options = NSMatchingOptions(rawValue: 0)
        let range = NSRange(location: 0,length: nsLink.length)
        let matches = regExp.matchesInString(link as String, options:options, range:range)
        if let firstMatch = matches.first {
            return nsLink.substringWithRange(firstMatch.range)
        }
        return nil
    }
    

    Swift 3

    func extractYoutubeIdFromLink(link: String) -> String? {
        let pattern = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)"
        guard let regExp = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive) else {
            return nil
        }
        let nsLink = link as NSString
        let options = NSRegularExpression.MatchingOptions(rawValue: 0)
        let range = NSRange(location: 0, length: nsLink.length)
        let matches = regExp.matches(in: link as String, options:options, range:range)
        if let firstMatch = matches.first {
            return nsLink.substring(with: firstMatch.range)
        }
        return nil
    }
    
    0 讨论(0)
提交回复
热议问题