Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

.packages
.pub/
*.lock

build/

Expand Down
24 changes: 20 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# video_thumbnail

This plugin generates thumbnail from video file or URL. It returns image in memory or writes into a file. It offers rich options to control the image format, resolution and quality. Supports iOS and Android.
[![pub ver](https://img.shields.io/badge/pub-v0.5.3-blue)](https://pub.dev/packages/video_thumbnail)
[![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/justsoft/)

[![pub ver](https://img.shields.io/badge/pub-v0.5.3-blue)](https://pub.dev/packages/video_thumbnail)
[![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/justsoft/)
This plugin generates thumbnail from video file or URL. It returns image in memory or writes into a file. It offers rich options to control the image format, resolution and quality. Supports iOS and Android.

![video-file](https://github.com/justsoft/video_thumbnail/blob/master/video_file.png?raw=true) ![video-url](https://github.com/justsoft/video_thumbnail/blob/master/video_url.png?raw=true)
![video-file](screenshots/video_file.jpg) ![video-url](screenshots/video_url.jpg)

## Methods
|function|parameter|description|return|
Expand All @@ -21,14 +21,30 @@ Warning:

**Installing**
add [video_thumbnail](https://pub.dev/packages/video_thumbnail) as a dependency in your pubspec.yaml file.

```yaml
dependencies:
video_thumbnail: ^0.5.3
```

**import**
```dart
import 'package:video_thumbnail/video_thumbnail.dart';
```

**Image Provider with flutter memory caching capability**
```dart
Image(
image: VideoThumbnailImage(
videoUri,
timeMs: 10,
maxWidth: 100,
imageFormat: ImageFormat.PNG,
),
fit: BoxFit.cover,
)
```

**Generate a thumbnail in memory from video file**
```dart
final uint8list = await VideoThumbnail.thumbnailData(
Expand Down
1 change: 1 addition & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Miscellaneous
*.class
*.log
*.lock
*.pyc
*.swp
.DS_Store
Expand Down
4 changes: 2 additions & 2 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 29
compileSdkVersion 33

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
Expand All @@ -39,7 +39,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "xyz.justsoft.video_thumbnail_example"
minSdkVersion 16
targetSdkVersion 29
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
Expand Down
3 changes: 2 additions & 1 deletion example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="adjustResize"
android:exported="true">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
Expand Down
6 changes: 3 additions & 3 deletions example/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.1.2'
}
}

allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}

Expand Down
2 changes: 1 addition & 1 deletion example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
47 changes: 29 additions & 18 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'dart:io';

import 'package:video_thumbnail/video_thumbnail.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:video_thumbnail/video_thumbnail.dart';

void main() => runApp(MyApp());

Expand Down Expand Up @@ -314,6 +313,7 @@ class _DemoHomeState extends State<DemoHome> {
),
)
];
double pr = MediaQuery.of(context).devicePixelRatio;
return Scaffold(
appBar: AppBar(
title: const Text('Thumbnail Plugin example'),
Expand All @@ -336,12 +336,27 @@ class _DemoHomeState extends State<DemoHome> {
focusNode: _editNode,
keyboardType: TextInputType.url,
textInputAction: TextInputAction.done,
onEditingComplete: () {
_editNode.unfocus();
},
onEditingComplete: () => _editNode.unfocus(),
),
),
..._settings,
Container(
height: 60,
color: Colors.grey[200],
margin: EdgeInsets.only(bottom: 10),
child: ListView.builder(
itemExtent: 30,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => Image(
image: VideoThumbnailImage(
_video.text,
timeMs: (100 * index) % 3000,
maxWidth: (30 * pr).toInt(),
),
fit: BoxFit.cover,
),
),
),
for (var i in _settings) i,
Expanded(
child: Container(
color: Colors.grey[300],
Expand Down Expand Up @@ -369,7 +384,7 @@ class _DemoHomeState extends State<DemoHome> {
)
],
),
for (var i in _settings) i,
..._settings,
],
),
),
Expand All @@ -379,11 +394,9 @@ class _DemoHomeState extends State<DemoHome> {
children: <Widget>[
FloatingActionButton(
onPressed: () async {
File video =
await ImagePicker.pickVideo(source: ImageSource.camera);
setState(() {
_video.text = video.path;
});
final video =
await ImagePicker().getVideo(source: ImageSource.camera);
setState(() => _video.text = video.path);
},
child: Icon(Icons.videocam),
tooltip: "Capture a video",
Expand All @@ -393,11 +406,9 @@ class _DemoHomeState extends State<DemoHome> {
),
FloatingActionButton(
onPressed: () async {
File video =
await ImagePicker.pickVideo(source: ImageSource.gallery);
setState(() {
_video.text = video?.path;
});
final video =
await ImagePicker().getVideo(source: ImageSource.gallery);
setState(() => _video.text = video?.path);
},
child: Icon(Icons.local_movies),
tooltip: "Pick a video",
Expand Down
Loading