From 3ab9a51068cebc8addc121139f77d74bbc084652 Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Thu, 12 Apr 2018 14:43:53 +0200 Subject: [PATCH 1/4] Implement timestamp option for ios --- index.js | 13 +++++++-- ios/RNThumbnail.m | 73 ++++++++++++++++++++++++++--------------------- 2 files changed, 50 insertions(+), 36 deletions(-) diff --git a/index.js b/index.js index c480aff..eb0c0c8 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,13 @@ -import { NativeModules } from 'react-native'; +import { NativeModules, Platform } from 'react-native'; -const { RNThumbnail } = NativeModules; +const { RNThumbnail: NativeRNThumbnail } = NativeModules; -export default RNThumbnail; +export default class RNThumbnail { + static get(path, options = { timestamp: 0 }) { + if (Platform.OS === 'ios') { + return NativeRNThumbnail.get(path, options.timestamp) + } + return NativeRNThumbnail.get(path) + } +}; diff --git a/ios/RNThumbnail.m b/ios/RNThumbnail.m index 8310709..144a4a9 100644 --- a/ios/RNThumbnail.m +++ b/ios/RNThumbnail.m @@ -8,44 +8,51 @@ @implementation RNThumbnail - (dispatch_queue_t)methodQueue { - return dispatch_get_main_queue(); + return dispatch_get_main_queue(); } RCT_EXPORT_MODULE() -RCT_EXPORT_METHOD(get:(NSString *)filepath resolve:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject) +RCT_EXPORT_METHOD(get:(NSString *)filepath timestamp:(NSNumber * __nonnull)timestamp resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject) { - @try { - filepath = [filepath stringByReplacingOccurrencesOfString:@"file://" - withString:@""]; - NSURL *vidURL = [NSURL fileURLWithPath:filepath]; - - AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:vidURL options:nil]; - AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; - generator.appliesPreferredTrackTransform = YES; - - NSError *err = NULL; - CMTime time = CMTimeMake(1, 60); - - CGImageRef imgRef = [generator copyCGImageAtTime:time actualTime:NULL error:&err]; - UIImage *thumbnail = [UIImage imageWithCGImage:imgRef]; - // save to temp directory - NSString* tempDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, - NSUserDomainMask, - YES) lastObject]; - - NSData *data = UIImageJPEGRepresentation(thumbnail, 1.0); - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSString *fullPath = [tempDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"thumb-%@.jpg", [[NSProcessInfo processInfo] globallyUniqueString]]]; - [fileManager createFileAtPath:fullPath contents:data attributes:nil]; - if (resolve) - resolve(@{ @"path" : fullPath, - @"width" : [NSNumber numberWithFloat: thumbnail.size.width], - @"height" : [NSNumber numberWithFloat: thumbnail.size.height] }); - } @catch(NSException *e) { - reject(e.reason, nil, nil); + @try { + filepath = [filepath stringByReplacingOccurrencesOfString:@"file://" + withString:@""]; + NSURL *vidURL = [NSURL fileURLWithPath:filepath]; + + AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:vidURL options:nil]; + int64_t value = 0; + if (timestamp != 0) { + AVAssetTrack * videoAssetTrack = [asset tracksWithMediaType: AVMediaTypeVideo].firstObject; + value = [timestamp longLongValue] * videoAssetTrack.nominalFrameRate; } + + AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; + generator.appliesPreferredTrackTransform = YES; + + NSError *err = NULL; + CMTime time = CMTimeMake(value, 60); + + CGImageRef imgRef = [generator copyCGImageAtTime:time actualTime:NULL error:&err]; + UIImage *thumbnail = [UIImage imageWithCGImage:imgRef]; + // save to temp directory + NSString* tempDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, + NSUserDomainMask, + YES) lastObject]; + + NSData *data = UIImageJPEGRepresentation(thumbnail, 1.0); + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSString *fullPath = [tempDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"thumb-%@.jpg", [[NSProcessInfo processInfo] globallyUniqueString]]]; + [fileManager createFileAtPath:fullPath contents:data attributes:nil]; + if (resolve) + resolve(@{ @"path" : fullPath, + @"width" : [NSNumber numberWithFloat: thumbnail.size.width], + @"height" : [NSNumber numberWithFloat: thumbnail.size.height] }); + } @catch(NSException *e) { + reject(e.reason, nil, nil); + } } @end - + + From 2d3acf216fb254f6963cab0a9e6d4b2c51804668 Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Thu, 12 Apr 2018 14:46:50 +0200 Subject: [PATCH 2/4] Document new option --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 78e6faa..f007343 100644 --- a/README.md +++ b/README.md @@ -43,3 +43,9 @@ RNThumbnail.get(filepath).then((result) => { console.log(result.path); // thumbnail path }) ``` + +### Options + +`RNThumbnail.get` supports a second argument which is a object with the following possible options: + +- `timestamp` (currently `ios` only): The timestamp of the thumbnail in seconds (calculates the frame based on the FPS of the video). Default Value: `0` From 1a9d19229883281fee6d4cf212faffc6d5075af2 Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Thu, 12 Apr 2018 14:49:49 +0200 Subject: [PATCH 3/4] Fix indent --- ios/RNThumbnail.m | 58 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/ios/RNThumbnail.m b/ios/RNThumbnail.m index 144a4a9..61e7950 100644 --- a/ios/RNThumbnail.m +++ b/ios/RNThumbnail.m @@ -15,44 +15,42 @@ - (dispatch_queue_t)methodQueue RCT_EXPORT_METHOD(get:(NSString *)filepath timestamp:(NSNumber * __nonnull)timestamp resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { - @try { - filepath = [filepath stringByReplacingOccurrencesOfString:@"file://" + @try { + filepath = [filepath stringByReplacingOccurrencesOfString:@"file://" withString:@""]; - NSURL *vidURL = [NSURL fileURLWithPath:filepath]; + NSURL *vidURL = [NSURL fileURLWithPath:filepath]; - AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:vidURL options:nil]; - int64_t value = 0; - if (timestamp != 0) { - AVAssetTrack * videoAssetTrack = [asset tracksWithMediaType: AVMediaTypeVideo].firstObject; - value = [timestamp longLongValue] * videoAssetTrack.nominalFrameRate; - } + AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:vidURL options:nil]; + int64_t value = 0; + if (timestamp != 0) { + AVAssetTrack * videoAssetTrack = [asset tracksWithMediaType: AVMediaTypeVideo].firstObject; + value = [timestamp longLongValue] * videoAssetTrack.nominalFrameRate; + } - AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; - generator.appliesPreferredTrackTransform = YES; + AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; + generator.appliesPreferredTrackTransform = YES; - NSError *err = NULL; - CMTime time = CMTimeMake(value, 60); + NSError *err = NULL; + CMTime time = CMTimeMake(value, 60); - CGImageRef imgRef = [generator copyCGImageAtTime:time actualTime:NULL error:&err]; - UIImage *thumbnail = [UIImage imageWithCGImage:imgRef]; - // save to temp directory - NSString* tempDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, + CGImageRef imgRef = [generator copyCGImageAtTime:time actualTime:NULL error:&err]; + UIImage *thumbnail = [UIImage imageWithCGImage:imgRef]; + // save to temp directory + NSString* tempDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; - NSData *data = UIImageJPEGRepresentation(thumbnail, 1.0); - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSString *fullPath = [tempDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"thumb-%@.jpg", [[NSProcessInfo processInfo] globallyUniqueString]]]; - [fileManager createFileAtPath:fullPath contents:data attributes:nil]; - if (resolve) - resolve(@{ @"path" : fullPath, - @"width" : [NSNumber numberWithFloat: thumbnail.size.width], - @"height" : [NSNumber numberWithFloat: thumbnail.size.height] }); - } @catch(NSException *e) { - reject(e.reason, nil, nil); - } + NSData *data = UIImageJPEGRepresentation(thumbnail, 1.0); + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSString *fullPath = [tempDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"thumb-%@.jpg", [[NSProcessInfo processInfo] globallyUniqueString]]]; + [fileManager createFileAtPath:fullPath contents:data attributes:nil]; + if (resolve) + resolve(@{ @"path" : fullPath, + @"width" : [NSNumber numberWithFloat: thumbnail.size.width], + @"height" : [NSNumber numberWithFloat: thumbnail.size.height] }); + } @catch(NSException *e) { + reject(e.reason, nil, nil); + } } @end - - From d3585a8d0474a73deedcf61997bc7b12f191bab8 Mon Sep 17 00:00:00 2001 From: Laurin Quast Date: Thu, 12 Apr 2018 14:53:16 +0200 Subject: [PATCH 4/4] More indentation fixes... --- ios/RNThumbnail.m | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/ios/RNThumbnail.m b/ios/RNThumbnail.m index 61e7950..cb1a1cc 100644 --- a/ios/RNThumbnail.m +++ b/ios/RNThumbnail.m @@ -8,46 +8,48 @@ @implementation RNThumbnail - (dispatch_queue_t)methodQueue { - return dispatch_get_main_queue(); + return dispatch_get_main_queue(); } RCT_EXPORT_MODULE() -RCT_EXPORT_METHOD(get:(NSString *)filepath timestamp:(NSNumber * __nonnull)timestamp resolve:(RCTPromiseResolveBlock)resolve +RCT_EXPORT_METHOD(get:(NSString *)filepath + timestamp:(NSNumber * __nonnull)timestamp + resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { @try { filepath = [filepath stringByReplacingOccurrencesOfString:@"file://" - withString:@""]; + withString:@""]; NSURL *vidURL = [NSURL fileURLWithPath:filepath]; - + AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:vidURL options:nil]; - int64_t value = 0; + int64_t value = 1; if (timestamp != 0) { AVAssetTrack * videoAssetTrack = [asset tracksWithMediaType: AVMediaTypeVideo].firstObject; value = [timestamp longLongValue] * videoAssetTrack.nominalFrameRate; } - + AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; generator.appliesPreferredTrackTransform = YES; - + NSError *err = NULL; CMTime time = CMTimeMake(value, 60); - + CGImageRef imgRef = [generator copyCGImageAtTime:time actualTime:NULL error:&err]; UIImage *thumbnail = [UIImage imageWithCGImage:imgRef]; // save to temp directory NSString* tempDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, - NSUserDomainMask, - YES) lastObject]; - + NSUserDomainMask, + YES) lastObject]; + NSData *data = UIImageJPEGRepresentation(thumbnail, 1.0); NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *fullPath = [tempDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"thumb-%@.jpg", [[NSProcessInfo processInfo] globallyUniqueString]]]; [fileManager createFileAtPath:fullPath contents:data attributes:nil]; if (resolve) - resolve(@{ @"path" : fullPath, - @"width" : [NSNumber numberWithFloat: thumbnail.size.width], - @"height" : [NSNumber numberWithFloat: thumbnail.size.height] }); + resolve(@{ @"path" : fullPath, + @"width" : [NSNumber numberWithFloat: thumbnail.size.width], + @"height" : [NSNumber numberWithFloat: thumbnail.size.height] }); } @catch(NSException *e) { reject(e.reason, nil, nil); }