Skip to content

Commit

Permalink
few changes
Browse files Browse the repository at this point in the history
  • Loading branch information
asapJ committed Nov 15, 2018
1 parent 6620bf5 commit 8909430
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 67 deletions.
36 changes: 31 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
# thumbnails

A Flutter Plugin to generate thumbnails from videos on Android devices
A Flutter Plugin to generate thumbnails from videos.

## Getting Started
## Compatibility
Android OS only

For help getting started with Flutter, view our online
[documentation](https://flutter.io/).
## Usage

For help on editing plugin code, view the [documentation](https://flutter.io/developing-packages/#edit-plugin-package).
#### Depend on it
add `thumbnails` as a dependency in your pubspec.yaml file.

#### Add import statement
Import the library via
``` dart
import 'package:thumbnails/thumbnails.dart';
```

#### Examples
``` dart
// Fetch thumbnail, store in a specified output folder and return file path
String thumb = await Thumbnails.getThumbnail(
thumbOutputFile:
'[YOUR OUTPUT FILE HERE]',
videoFile: '[VIDEO PATH HERE]',
imageType: ThumbFormat.PNG,
quality: 30);
// Fetch thumbnail, store in app's Temporary directory output folder and return file path
String thumb = await Thumbnails.getThumbnail(
videoFile: 'VIDEO PATH HERE',
imageType: ThumbFormat.JPEG,
quality: 45);
```
95 changes: 82 additions & 13 deletions android/src/main/java/com/asapjay/thumbnails/ThumbnailsPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;

Expand All @@ -23,9 +24,15 @@ public class ThumbnailsPlugin implements MethodCallHandler {
/**
* Plugin registration.
*/
private Registrar mRegistrar;

private ThumbnailsPlugin(Registrar mRegistrar) {
this.mRegistrar = mRegistrar;
}

public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "thumbnails");
channel.setMethodCallHandler(new ThumbnailsPlugin());
channel.setMethodCallHandler(new ThumbnailsPlugin(registrar));
}

@Override
Expand All @@ -38,8 +45,8 @@ public void onMethodCall(MethodCall call, Result result) {
int imageType = (int) arguments.get("thumbnailFormat");
int quality = (int) arguments.get("thumbnailQuality");
try {
buildThumbnail(videoFile, thumbOutputFile, imageType, quality);
result.success("success");
String thumbnailPath = buildThumbnail(videoFile, thumbOutputFile, imageType, quality);
result.success(thumbnailPath);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
Expand All @@ -48,51 +55,113 @@ public void onMethodCall(MethodCall call, Result result) {
}
}

private void buildThumbnail(String vidPath, String thumbPath, int type, int quality) {
private String buildThumbnail(String vidPath, String thumbPath, int type, int quality) {
if (vidPath == null || vidPath.equals("")) {
Log.println(Log.INFO, "WARNING", "Thumbnails: Video Path must not be null or empty!");
return null;
}
return thumbPath == null ? cacheDirectory(vidPath, type, quality) : userDirectory(vidPath, thumbPath, type, quality);

}

private String cacheDirectory(String vidPath, int type, int quality) {
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(vidPath, MediaStore.Video.Thumbnails.MINI_KIND);
String sourceFileName = Uri.parse(vidPath).getLastPathSegment();
String thumbDirPath = mRegistrar.context().getExternalCacheDir() + File.separator + "ThumbFiles" + File.separator;
String tempFile = thumbDirPath + sourceFileName;
File tempDir = new File(thumbDirPath);

if (vidPath == null || vidPath == "") {
Log.println(Log.INFO, "WARNING", "Thumbnails: Video Path must not be null or empty");
return;
if (tempDir.exists()) {
clearThumbnails();
} else {
tempDir.mkdirs();
}
if (thumbPath == null || thumbPath == "") {
Log.println(Log.INFO, "WARNING", "Thumbnails: Thumbnail Path must not be null or empty");
return;

switch (type) {
case 1:
try {
FileOutputStream out = new FileOutputStream(new File(tempFile + ".jpg"));
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out);
out.flush();
out.close();
return tempFile + ".jpg";
} catch (IOException e) {
e.printStackTrace();
}
case 2:
try {
FileOutputStream out = new FileOutputStream(new File(tempFile + ".png"));
bitmap.compress(Bitmap.CompressFormat.PNG, quality, out);
out.flush();
out.close();
return tempFile + ".png";
} catch (IOException e) {
e.printStackTrace();
}
case 3:
try {
FileOutputStream out = new FileOutputStream(new File(tempFile + ".webp"));
bitmap.compress(Bitmap.CompressFormat.WEBP, quality, out);
out.flush();
out.close();
return tempFile + ".webp";
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
}

private String userDirectory(String vidPath, String thumbPath, int type, int quality) {
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(vidPath, MediaStore.Video.Thumbnails.MINI_KIND);
switch (type) {
case 1:
try {
FileOutputStream out = new FileOutputStream(new File(thumbPath));
FileOutputStream out = new FileOutputStream(new File(thumbPath + ".jpg"));
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out);
out.flush();
out.close();
return thumbPath + ".jpg";
} catch (IOException e) {
e.printStackTrace();
}
break;

case 2:
try {
FileOutputStream out = new FileOutputStream(new File(thumbPath));
FileOutputStream out = new FileOutputStream(new File(thumbPath + ".png"));
bitmap.compress(Bitmap.CompressFormat.PNG, quality, out);
out.flush();
out.close();
return thumbPath + ".png";
} catch (IOException e) {
e.printStackTrace();
}
break;
case 3:
try {
FileOutputStream out = new FileOutputStream(new File(thumbPath));
FileOutputStream out = new FileOutputStream(new File(thumbPath + "webp"));
bitmap.compress(Bitmap.CompressFormat.WEBP, quality, out);
out.flush();
out.close();
return thumbPath + ".webp";
} catch (IOException e) {
e.printStackTrace();
}
break;
}
return "";
}

private void clearThumbnails() {
String tempDirPath = mRegistrar.context().getExternalCacheDir()
+ File.separator + "TempFiles" + File.separator;
File tempDir = new File(tempDirPath);
if (tempDir.exists()) {
String[] children = tempDir.list();
for (String file : children) {
new File(tempDir, file).delete();
}
}
}
}
52 changes: 22 additions & 30 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:thumbnails/thumbnails.dart';

void main() => runApp(new MyApp());
Expand All @@ -12,33 +9,24 @@ class MyApp extends StatefulWidget {
}

class _MyAppState extends State<MyApp> {

@override
void initState() {
super.initState();
// initPlatformState();
}

// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
await Thumbnails.getThumbnail(
thumbOutputFile: '/storage/emulated/0/Whatsapp/Media/Test${TimeOfDay.now()}.jpg',
// Fetch thumbnail and store in a specified output folder
void _buildThumbToFile() async {
String thumb = await Thumbnails.getThumbnail(
thumbOutputFile:
'/storage/emulated/0/Whatsapp/Media/Test${TimeOfDay.now()}.jpg',
videoFile: '/storage/emulated/0/Whatsapp/Media/.Statuses/Testvid.mp4',
imageType: ThumbFormat.PNG,
quality: 30
);
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}

// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
quality: 30);
print(thumb);
}

// Fetch thumbnail and stores in app temporary directory (this is volatile)
void _buildThumbToCache() async {
String thumb = await Thumbnails.getThumbnail(
videoFile: '/storage/emulated/0/Whatsapp/Media/.Statuses/Testvid.mp4',
imageType: ThumbFormat.JPEG,
quality: 30);
print(thumb);
}

@override
Expand All @@ -49,9 +37,13 @@ class _MyAppState extends State<MyApp> {
title: const Text('Plugin example app'),
),
body: new Center(
child: FlatButton(
onPressed: ()=> initPlatformState(),
child: Text('Press Me'),
child: Column(
children: <Widget>[
RaisedButton(
onPressed: _buildThumbToFile, child: Text('Build To File')),
RaisedButton(
onPressed: _buildThumbToCache, child: Text('Build to Cache')),
],
),
),
),
Expand Down
23 changes: 5 additions & 18 deletions lib/thumbnails.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,13 @@ import 'package:flutter/services.dart';
import 'package:thumbnails/validators.dart';

enum ThumbFormat { PNG, JPEG, WEBP }
class Thumbnails {
String videoFile;
String thumbOutputFile;
int imageType;
int quality;

Thumbnails(
{@required this.videoFile,
@required this.thumbOutputFile,
this.imageType,
this.quality});

class Thumbnails {
static const MethodChannel _channel = const MethodChannel('thumbnails');

static Future<void> getThumbnail(
static Future<String> getThumbnail(
{@required String videoFile,
@required String thumbOutputFile,
String thumbOutputFile,
ThumbFormat imageType,
int quality}) async {
var utilMap = <String, dynamic>{
Expand All @@ -30,10 +20,7 @@ class Thumbnails {
'thumbnailFormat': validateType(imageType),
'thumbnailQuality': validateQuality(quality)
};
await _channel.invokeMethod('getThumbnail', utilMap);
print('done!!');
String thumbnailPath = await _channel.invokeMethod('getThumbnail', utilMap);
return thumbnailPath;
}



}
1 change: 0 additions & 1 deletion lib/validators.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import 'package:thumbnails/thumbnails.dart';

const DEFAULT_THUMB_QUALITY = 50;
Expand Down

0 comments on commit 8909430

Please sign in to comment.