Skip to content

Commit

Permalink
Merge pull request #40 from souvik-ghosh/1.4.0
Browse files Browse the repository at this point in the history
1.4.0
  • Loading branch information
souvik-ghosh authored May 23, 2021
2 parents d02e9ba + 61907c5 commit 7728c78
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 18 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ createThumbnail({
| format | `String` (default `jpeg`) | Thumbnail format, can be one of: `jpeg`, or `png` |
| dirSize | `Number` (default `100`) | Maximum size of the cache directory (in megabytes) |
| headers | `Object` | Headers to load the video with. e.g. `{ Authorization: 'someAuthToken' }` |
| cacheName | `String` (optional) | Cache name for this thumbnail to avoid duplicate generation. If specified, and a thumbnail already exists with the same cache name, it will be returned without generating a new one. |
## Response Object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Build.VERSION;
import android.text.TextUtils;
import android.webkit.URLUtil;

import com.facebook.react.bridge.Arguments;
Expand Down Expand Up @@ -44,19 +46,31 @@ public String getName() {
public void create(ReadableMap options, Promise promise) {
String filePath = options.hasKey("url") ? options.getString("url") : "";
String format = options.hasKey("format") ? options.getString("format") : "jpeg";
String cacheName = options.hasKey("cacheName") ? options.getString("cacheName") : "";
int timeStamp = options.hasKey("timeStamp") ? options.getInt("timeStamp") : 0;
int dirSize = options.hasKey("dirSize") ? options.getInt("dirSize") : 100;
HashMap headers = options.hasKey("headers") ? options.getMap("headers").toHashMap() : new HashMap<String, String>();
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
String thumbnailDir = reactContext.getApplicationContext().getCacheDir().getAbsolutePath() + "/thumbnails";
String fileName = "thumb-" + UUID.randomUUID().toString() + "." + format;
String fileName = TextUtils.isEmpty(cacheName) ? ("thumb-" + UUID.randomUUID().toString()) : cacheName + "." + format;
File dir = createDirIfNotExists(thumbnailDir);
File file = new File(thumbnailDir, fileName);
if (file.exists()) {
WritableMap map = Arguments.createMap();
map.putString("path", "file://" + thumbnailDir + '/' + fileName);
Bitmap image = BitmapFactory.decodeFile(file.getAbsolutePath());
map.putDouble("size", image.getByteCount());
map.putString("mime", "image/" + format);
map.putDouble("width", image.getWidth());
map.putDouble("height", image.getHeight());

promise.resolve(map);
return;
}
long cacheDirSize = dirSize * 1024 * 1024;
OutputStream fOut = null;

try {
File dir = createDirIfNotExists(thumbnailDir);
Bitmap image = getBitmapAtTime(this.reactContext, filePath, timeStamp, headers);
File file = new File(thumbnailDir, fileName);
file.createNewFile();
fOut = new FileOutputStream(file);

Expand All @@ -78,6 +92,8 @@ public void create(ReadableMap options, Promise promise) {

WritableMap map = Arguments.createMap();
map.putString("path", "file://" + thumbnailDir + '/' + fileName);
map.putDouble("size", image.getByteCount());
map.putString("mime", "image/" + format);
map.putDouble("width", image.getWidth());
map.putDouble("height", image.getHeight());

Expand Down
2 changes: 1 addition & 1 deletion example/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function App() {

createThumbnail({
url: path,
timeStamp
timeStamp: parseInt(timeStamp)
})
.then(response => {
setThumbnail(response.path);
Expand Down
8 changes: 4 additions & 4 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ PODS:
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsinspector (0.61.5)
- react-native-create-thumbnail (1.1.1):
- react-native-create-thumbnail (1.4.0):
- React
- React-RCTActionSheet (0.61.5):
- React-Core/RCTActionSheetHeaders (= 0.61.5)
Expand Down Expand Up @@ -253,7 +253,7 @@ DEPENDENCIES:
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)

SPEC REPOS:
https://github.com/CocoaPods/Specs.git:
trunk:
- boost-for-react-native

EXTERNAL SOURCES:
Expand Down Expand Up @@ -326,7 +326,7 @@ SPEC CHECKSUMS:
React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7
React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386
React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0
react-native-create-thumbnail: 98493415cc6e722e80fee6522e5412857a1eed3b
react-native-create-thumbnail: 679c9e15411bbf9aa5ee2ce33b69f69f9f1bc0fe
React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76
React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360
React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72
Expand All @@ -341,4 +341,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 79310af6b976c356911a8a833e9b99c3399fdda3

COCOAPODS: 1.8.4
COCOAPODS: 1.10.1
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ declare module "react-native-create-thumbnail" {
format?: "jpeg" | "png";
dirSize?: number;
headers?: object;
cacheName?: string;
}

export interface Thumbnail {
Expand Down
30 changes: 22 additions & 8 deletions ios/CreateThumbnail.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,32 @@ @implementation CreateThumbnail
int timeStamp = [[config objectForKey:@"timeStamp"] intValue] ?: 0;
NSString *format = (NSString *)[config objectForKey:@"format"] ?: @"jpeg";
int dirSize = [[config objectForKey:@"dirSize"] intValue] ?: 100;
NSString *cacheName = (NSString *)[config objectForKey:@"cacheName"];
NSDictionary *headers = config[@"headers"] ?: @{};

unsigned long long cacheDirSize = dirSize * 1024 * 1024;

@try {
// Prepare cache folder
NSString* tempDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
tempDirectory = [tempDirectory stringByAppendingString:@"/thumbnails/"];
// Create thumbnail directory if not exists
[[NSFileManager defaultManager] createDirectoryAtPath:tempDirectory withIntermediateDirectories:YES attributes:nil error:nil];
NSString *fileName = [NSString stringWithFormat:@"thumb-%@.%@", cacheName ?: [[NSProcessInfo processInfo] globallyUniqueString], format];
NSString* fullPath = [tempDirectory stringByAppendingPathComponent:fileName];
if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath]) {
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:fullPath]];
UIImage *thumbnail = [UIImage imageWithData:imageData];
resolve(@{
@"path" : fullPath,
@"size" : [NSNumber numberWithFloat: data.length],
@"mime" : [NSString stringWithFormat: @"image/%@", format],
@"width" : [NSNumber numberWithFloat: thumbnail.size.width],
@"height" : [NSNumber numberWithFloat: thumbnail.size.height]
});
return;
}

NSURL *vidURL = nil;
NSString *url_ = [url lowercaseString];

Expand All @@ -28,11 +49,7 @@ @implementation CreateThumbnail
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:vidURL options:@{@"AVURLAssetHTTPHeaderFieldsKey": headers}];
UIImage *thumbnail = [self generateThumbImage:asset atTime:timeStamp];

// Save to temp directory
NSString* tempDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
tempDirectory = [tempDirectory stringByAppendingString:@"/thumbnails/"];
// Create thumbnail directory if not exists
[[NSFileManager defaultManager] createDirectoryAtPath:tempDirectory withIntermediateDirectories:YES attributes:nil error:nil];

// Clean directory
unsigned long long size = [self sizeOfFolderAtPath:tempDirectory];
if (size >= cacheDirSize) {
Expand All @@ -41,13 +58,10 @@ @implementation CreateThumbnail

// Generate thumbnail
NSData *data = nil;
NSString *fullPath = nil;
if ([format isEqual: @"png"]) {
data = UIImagePNGRepresentation(thumbnail);
fullPath = [tempDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"thumb-%@.png",[[NSProcessInfo processInfo] globallyUniqueString]]];
} else {
data = UIImageJPEGRepresentation(thumbnail, 1.0);
fullPath = [tempDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"thumb-%@.jpeg",[[NSProcessInfo processInfo] globallyUniqueString]]];
}

NSFileManager *fileManager = [NSFileManager defaultManager];
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-native-create-thumbnail",
"title": "React Native Create Thumbnail",
"version": "1.3.0",
"version": "1.4.0",
"description": "iOS/Android thumbnail generator with support for both local and remote videos",
"main": "index.js",
"scripts": {
Expand Down

0 comments on commit 7728c78

Please sign in to comment.