Skip to content

Commit

Permalink
Merge pull request #14 from zaption/referer
Browse files Browse the repository at this point in the history
Allow custom referer to work with Vimeo privacy settings
  • Loading branch information
lilfaf committed Sep 5, 2014
2 parents 2d07829 + 90bd02b commit eacaa91
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 16 deletions.
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Use the block based methods and pass it the video url and the desired quality
}];
```
or create an instance of YTVimeoExtractor
or create an instance of YTVimeoExtractor.
```objc
self.extractor = [[YTVimeoExtractor alloc] initWithURL:@"http://vimeo.com/58600663" quality:YTVimeoVideoQualityMedium];
Expand All @@ -62,6 +62,25 @@ and implement YTVimeoExtractor delegate methods in your ViewController.
}
```

If the Vimeo videos have domain-level restrictions and can only be played from particular domains, it's easy to add a referer:

```objc
[YTVimeoExtractor fetchVideoURLFromURL:@"http://vimeo.com/58600663"
quality:YTVimeoVideoQualityMedium
referer:@"http://www.mywebsite.com"
completionHandler:^(NSURL *videoURL, NSError *error, YTVimeoVideoQuality quality) {
if (error) {
// handle error
NSLog(@"Video URL: %@", [videoURL absoluteString]);
} else {
// run player
self.playerViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
[self.playerViewController.moviePlayer prepareToPlay];
[self presentViewController:self.playerViewController animated:YES completion:nil];
}
}];
```
Check the sample application for more details.
## Requirements
Expand Down
5 changes: 5 additions & 0 deletions YTVimeoExtractor/YTVimeoExtractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,20 @@ typedef void (^completionHandler) (NSURL *videoURL, NSError *error, YTVimeoVideo

@property (nonatomic, readonly) BOOL running;
@property (nonatomic, readonly) YTVimeoVideoQuality quality;
@property (nonatomic, readonly) NSString* referer;
@property (strong, nonatomic, readonly) NSURL *vimeoURL;

@property (unsafe_unretained, nonatomic) id<YTVimeoExtractorDelegate> delegate;

+ (void)fetchVideoURLFromURL:(NSString *)videoURL quality:(YTVimeoVideoQuality)quality completionHandler:(completionHandler)handler;
+ (void)fetchVideoURLFromID:(NSString *)videoURL quality:(YTVimeoVideoQuality)quality completionHandler:(completionHandler)handler;
+ (void)fetchVideoURLFromURL:(NSString *)videoURL quality:(YTVimeoVideoQuality)quality referer:(NSString *)referer completionHandler:(completionHandler)handler;
+ (void)fetchVideoURLFromID:(NSString *)videoURL quality:(YTVimeoVideoQuality)quality referer:(NSString *)referer completionHandler:(completionHandler)handler;

- (id)initWithURL:(NSString *)videoURL quality:(YTVimeoVideoQuality)quality;
- (id)initWithID:(NSString *)videoID quality:(YTVimeoVideoQuality)quality;
- (id)initWithURL:(NSString *)videoURL quality:(YTVimeoVideoQuality)quality referer:(NSString *)referer;
- (id)initWithID:(NSString *)videoID quality:(YTVimeoVideoQuality)quality referer:(NSString *)referer;

- (void)start;

Expand Down
54 changes: 39 additions & 15 deletions YTVimeoExtractor/YTVimeoExtractor.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,37 +22,55 @@ - (void)extractorFailedWithMessage:(NSString*)message errorCode:(int)code;

@implementation YTVimeoExtractor

+ (void)fetchVideoURLFromURL:(NSString *)videoURL quality:(YTVimeoVideoQuality)quality completionHandler:(completionHandler)handler
+ (void)fetchVideoURLFromURL:(NSString *)videoURL quality:(YTVimeoVideoQuality)quality referer:(NSString *)referer completionHandler:(completionHandler)handler
{
YTVimeoExtractor *extractor = [[YTVimeoExtractor alloc] initWithURL:videoURL quality:quality];
YTVimeoExtractor *extractor = [[YTVimeoExtractor alloc] initWithURL:videoURL quality:quality referer:referer];
extractor.completionHandler = handler;
[extractor start];
}

+ (void)fetchVideoURLFromID:(NSString *)videoID quality:(YTVimeoVideoQuality)quality completionHandler:(completionHandler)handler
+ (void)fetchVideoURLFromID:(NSString *)videoID quality:(YTVimeoVideoQuality)quality referer:(NSString *)referer completionHandler:(completionHandler)handler
{
YTVimeoExtractor *extractor = [[YTVimeoExtractor alloc] initWithID:videoID quality:quality];
YTVimeoExtractor *extractor = [[YTVimeoExtractor alloc] initWithID:videoID quality:quality referer:referer];
extractor.completionHandler = handler;
[extractor start];
}
+ (void)fetchVideoURLFromURL:(NSString *)videoURL quality:(YTVimeoVideoQuality)quality completionHandler:(completionHandler)handler
{
return [YTVimeoExtractor fetchVideoURLFromURL:videoURL quality:quality referer:nil completionHandler:handler];
}

+ (void)fetchVideoURLFromID:(NSString *)videoID quality:(YTVimeoVideoQuality)quality completionHandler:(completionHandler)handler
{
return [YTVimeoExtractor fetchVideoURLFromID:videoID quality:quality referer:nil completionHandler:handler];}

#pragma mark - Constructors

- (id)initWithID:(NSString *)videoID quality:(YTVimeoVideoQuality)quality
- (id)initWithID:(NSString *)videoID quality:(YTVimeoVideoQuality)quality referer:(NSString *)referer
{
self = [super init];
if (self) {
_vimeoURL = [NSURL URLWithString:[NSString stringWithFormat:YTVimeoPlayerConfigURL, videoID]];
_quality = quality;
_referer = referer;
_running = NO;
}
return self;
}

- (id)initWithURL:(NSString *)videoURL quality:(YTVimeoVideoQuality)quality
- (id)initWithURL:(NSString *)videoURL quality:(YTVimeoVideoQuality)quality referer:(NSString *)referer
{
NSString *videoID = [[videoURL componentsSeparatedByString:@"/"] lastObject];
return [self initWithID:videoID quality:quality];
return [self initWithID:videoID quality:quality referer:referer];
}

- (id)initWithID:(NSString *)videoID quality:(YTVimeoVideoQuality)quality
{
return [self initWithID:videoID quality:quality referer:nil];
}

- (id)initWithURL:(NSString *)videoURL quality:(YTVimeoVideoQuality)quality {
return [self initWithURL:videoURL quality:quality referer:nil];
}

- (void)dealloc
Expand All @@ -75,8 +93,14 @@ - (void)start
[self extractorFailedWithMessage:@"Already in progress" errorCode:YTVimeoExtractorErrorCodeNotInitialized];
return;
}

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:self.vimeoURL];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

if (self.referer) {
[request setValue:self.referer forHTTPHeaderField:@"Referer"];
}

self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
_running = YES;
}
Expand All @@ -86,7 +110,7 @@ - (void)start
- (void)extractorFailedWithMessage:(NSString*)message errorCode:(int)code {
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:message forKey:NSLocalizedDescriptionKey];
NSError *error = [NSError errorWithDomain:YTVimeoExtractorErrorDomain code:code userInfo:userInfo];

if (self.completionHandler) {
self.completionHandler(nil, error, self.quality);
}
Expand All @@ -106,7 +130,7 @@ -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLRespons
[self extractorFailedWithMessage:@"Invalid video indentifier" errorCode:YTVimeoExtractorErrorInvalidIdentifier];
[connection cancel];
}

NSUInteger capacity = (response.expectedContentLength != NSURLResponseUnknownLength) ? (uint)response.expectedContentLength : 0;
self.buffer = [[NSMutableData alloc] initWithCapacity:capacity];
}
Expand All @@ -120,38 +144,38 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error;
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:self.buffer options:NSJSONReadingAllowFragments error:&error];

if (error) {
[self extractorFailedWithMessage:@"Invalid video indentifier" errorCode:YTVimeoExtractorErrorInvalidIdentifier];
return;
}

NSDictionary *filesInfo = [jsonData valueForKeyPath:@"request.files.h264"];
if (!filesInfo) {
[self extractorFailedWithMessage:@"Unsupported video codec" errorCode:YTVimeoExtractorErrorUnsupportedCodec];
return;
}

NSDictionary *videoInfo;
YTVimeoVideoQuality videoQuality = self.quality;
do {
videoInfo = [filesInfo objectForKey:@[ @"mobile", @"sd", @"hd" ][videoQuality]];
videoQuality--;
} while (!videoInfo && videoQuality >= YTVimeoVideoQualityLow);

if (!videoInfo) {
[self extractorFailedWithMessage:@"Unavailable video quality" errorCode:YTVimeoExtractorErrorUnavailableQuality];
return;
}

NSURL *fileURL = [NSURL URLWithString:[videoInfo objectForKey:@"url"]];
if (self.completionHandler) {
self.completionHandler(fileURL, nil, videoQuality);
}
else if ([self.delegate respondsToSelector:@selector(vimeoExtractor:didSuccessfullyExtractVimeoURL:withQuality:)]) {
[self.delegate vimeoExtractor:self didSuccessfullyExtractVimeoURL:fileURL withQuality:videoQuality];
}

_running = NO;
}

Expand Down

0 comments on commit eacaa91

Please sign in to comment.