diff --git a/android/src/main/java/com/createthumbnail/CreateThumbnailModule.java b/android/src/main/java/com/createthumbnail/CreateThumbnailModule.java index ecc91d9..61238ac 100644 --- a/android/src/main/java/com/createthumbnail/CreateThumbnailModule.java +++ b/android/src/main/java/com/createthumbnail/CreateThumbnailModule.java @@ -58,7 +58,7 @@ public void create(ReadableMap options, Promise promise) { handler.post(() -> { promise.resolve(data); }); - } catch (IOException | IllegalStateException e) { + } catch (Exception e) { handler.post(() -> { promise.reject("CreateThumbnail_ERROR", e); }); @@ -162,44 +162,62 @@ private static File createDirIfNotExists(String path) { } private static Bitmap getBitmapAtTime(Context context, String filePath, int time, int maxWidth, int maxHeight, boolean onlySyncedFrames, Map headers) throws IOException, IllegalStateException { + if (TextUtils.isEmpty(filePath)) { + throw new IllegalStateException("Video url is empty"); + } + MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - if (URLUtil.isFileUrl(filePath)) { - String decodedPath; - try { - decodedPath = URLDecoder.decode(filePath, "UTF-8"); - } catch (UnsupportedEncodingException e) { - decodedPath = filePath; + try { + if (URLUtil.isFileUrl(filePath)) { + String decodedPath; + try { + decodedPath = URLDecoder.decode(filePath, "UTF-8"); + } catch (UnsupportedEncodingException e) { + decodedPath = filePath; + } + + retriever.setDataSource(decodedPath.replace("file://", "")); + } else if (filePath.contains("content://")) { + retriever.setDataSource(context, Uri.parse(filePath)); + } else { + if (VERSION.SDK_INT < 14) { + throw new IllegalStateException("Remote videos aren't supported on sdk_version < 14"); + } + HashMap stringHeaders = new HashMap<>(); + if (headers != null) { + for (Object key : headers.keySet()) { + Object value = headers.get(key); + if (key != null && value != null) { + stringHeaders.put(String.valueOf(key), String.valueOf(value)); + } + } + } + retriever.setDataSource(filePath, stringHeaders); } - retriever.setDataSource(decodedPath.replace("file://", "")); - } else if (filePath.contains("content://")) { - retriever.setDataSource(context, Uri.parse(filePath)); - } else { - if (VERSION.SDK_INT < 14) { - throw new IllegalStateException("Remote videos aren't supported on sdk_version < 14"); + Bitmap image; + if (Build.VERSION.SDK_INT >= 27) { + image = retriever.getScaledFrameAtTime(time * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC, maxWidth, maxHeight); + } else { + // If on versions lower than API 27, use other methods to get frames + image = retriever.getFrameAtTime(time * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC); + if (image != null) { + image = Bitmap.createScaledBitmap(image, maxWidth, maxHeight, true); + } } - retriever.setDataSource(filePath, headers); - } - - Bitmap image; - if (Build.VERSION.SDK_INT >= 27) { - image = retriever.getScaledFrameAtTime(time * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC, maxWidth, maxHeight); - } else { - // If on versions lower than API 27, use other methods to get frames - image = retriever.getFrameAtTime(time * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC); - if (image != null) { - image = Bitmap.createScaledBitmap(image, maxWidth, maxHeight, true); + if (image == null) { + throw new IllegalStateException("File doesn't exist or not supported"); + } + return image; + } catch (RuntimeException e) { + throw new IllegalStateException("Failed to create thumbnail for: " + filePath, e); + } finally { + try { + retriever.release(); + } catch (Exception e) { + e.printStackTrace(); } } - try { - retriever.release(); - } catch(IOException e) { - e.printStackTrace(); - } - if (image == null) { - throw new IllegalStateException("File doesn't exist or not supported"); - } - return image; } private static long getDirSize(File dir) { diff --git a/index.js b/index.js index be05450..392e4de 100644 --- a/index.js +++ b/index.js @@ -2,5 +2,8 @@ import { NativeModules } from "react-native"; const { CreateThumbnail } = NativeModules; -export const { create: createThumbnail } = CreateThumbnail; -export default CreateThumbnail; +export const createThumbnail = CreateThumbnail?.create + ? (config) => CreateThumbnail.create(config) + : () => Promise.reject(new Error("CreateThumbnail native module is not available")); + +export default CreateThumbnail ?? { create: createThumbnail };