aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Gultsch <daniel@gultsch.de>2016-07-11 21:24:33 +0200
committerDaniel Gultsch <daniel@gultsch.de>2016-07-11 21:24:33 +0200
commitbe4aa2afc96b86c89c2fc37735a4b0cf328d7415 (patch)
treea7ec3c89d324c232cad882ae95ff896b2a4e1b36
parent01a4d2ea25a0c76f62abc3ca74c0f6d8c7fd835e (diff)
show a preview for video files
-rw-r--r--art/play_video.svg59
-rwxr-xr-xart/render.rb1
-rw-r--r--src/main/java/eu/siacs/conversations/persistance/FileBackend.java140
-rw-r--r--src/main/res/drawable-hdpi/play_video.pngbin0 -> 3813 bytes
-rw-r--r--src/main/res/drawable-mdpi/play_video.pngbin0 -> 2432 bytes
-rw-r--r--src/main/res/drawable-xhdpi/play_video.pngbin0 -> 5087 bytes
-rw-r--r--src/main/res/drawable-xxhdpi/play_video.pngbin0 -> 7824 bytes
-rw-r--r--src/main/res/drawable-xxxhdpi/play_video.pngbin0 -> 10668 bytes
8 files changed, 176 insertions, 24 deletions
diff --git a/art/play_video.svg b/art/play_video.svg
new file mode 100644
index 00000000..083e7cfa
--- /dev/null
+++ b/art/play_video.svg
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48"
+ height="48"
+ viewBox="0 0 48 48"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="play_video.svg">
+ <metadata
+ id="metadata12">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs10" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1916"
+ inkscape:window-height="1156"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="4.9166667"
+ inkscape:cx="0.91525424"
+ inkscape:cy="24"
+ inkscape:window-x="0"
+ inkscape:window-y="20"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg2" />
+ <path
+ d="M0 0h48v48H0z"
+ fill="none"
+ id="path4" />
+ <path
+ d="M20 33l12-9-12-9v18zm4-29C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm0 36c-8.82 0-16-7.18-16-16S15.18 8 24 8s16 7.18 16 16-7.18 16-16 16z"
+ id="path6"
+ style="fill:#ffffff;fill-opacity:0.7019608;opacity:1;stroke:none;stroke-opacity:0.38039216" />
+</svg>
diff --git a/art/render.rb b/art/render.rb
index 2b2caacf..fe39e66b 100755
--- a/art/render.rb
+++ b/art/render.rb
@@ -13,6 +13,7 @@ resolutions = {
images = {
'ic_launcher.svg' => ['ic_launcher', 48],
'main_logo.svg' => ['main_logo', 200],
+ 'play_video.svg' => ['play_video', 96],
'conversations_mono.svg' => ['ic_notification', 24],
'ic_received_indicator.svg' => ['ic_received_indicator', 12],
'ic_send_text_offline.svg' => ['ic_send_text_offline', 36],
diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java
index 85b1ac90..d1935a18 100644
--- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java
+++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java
@@ -10,6 +10,7 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.RectF;
+import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
@@ -380,21 +381,43 @@ public class FileBackend {
if (thumbnail != null) {
return thumbnail;
}
- File file = getFile(message);
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inSampleSize = calcSampleSize(file, size);
- Bitmap fullsize = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
- if (fullsize == null) {
- throw new FileNotFoundException();
+ DownloadableFile file = getFile(message);
+ if (file.getMimeType().startsWith("video/")) {
+ thumbnail = getVideoPreview(file, size);
+ } else {
+ Bitmap fullsize = getFullsizeImagePreview(file, size);
+ if (fullsize == null) {
+ throw new FileNotFoundException();
+ }
+ thumbnail = resize(fullsize, size);
+ thumbnail = rotate(thumbnail, getRotation(file));
}
- thumbnail = resize(fullsize, size);
- thumbnail = rotate(thumbnail, getRotation(file));
this.mXmppConnectionService.getBitmapCache().put(uuid, thumbnail);
}
}
return thumbnail;
}
+ private Bitmap getFullsizeImagePreview(File file, int size) {
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inSampleSize = calcSampleSize(file, size);
+ return BitmapFactory.decodeFile(file.getAbsolutePath(), options);
+ }
+
+ private Bitmap getVideoPreview(File file, int size) {
+ MediaMetadataRetriever metadataRetriever = new MediaMetadataRetriever();
+ metadataRetriever.setDataSource(file.getAbsolutePath());
+ Bitmap frame = metadataRetriever.getFrameAtTime(0);
+ metadataRetriever.release();
+ frame = resize(frame, size);
+ Canvas canvas = new Canvas(frame);
+ Bitmap play = BitmapFactory.decodeResource(mXmppConnectionService.getResources(), R.drawable.play_video);
+ float x = (frame.getWidth() - play.getWidth()) / 2.0f;
+ float y = (frame.getHeight() - play.getHeight()) / 2.0f;
+ canvas.drawBitmap(play,x,y,null);
+ return frame;
+ }
+
public Uri getTakePhotoUri() {
StringBuilder pathBuilder = new StringBuilder();
pathBuilder.append(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM));
@@ -656,26 +679,95 @@ public class FileBackend {
public void updateFileParams(Message message, URL url) {
DownloadableFile file = getFile(message);
- if (message.getType() == Message.TYPE_IMAGE || file.getMimeType().startsWith("image/")) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(file.getAbsolutePath(), options);
- int rotation = getRotation(file);
- boolean rotated = rotation == 90 || rotation == 270;
- int imageHeight = rotated ? options.outWidth : options.outHeight;
- int imageWidth = rotated ? options.outHeight : options.outWidth;
- if (url == null) {
- message.setBody(Long.toString(file.getSize()) + '|' + imageWidth + '|' + imageHeight);
- } else {
- message.setBody(url.toString()+"|"+Long.toString(file.getSize()) + '|' + imageWidth + '|' + imageHeight);
+ boolean image = message.getType() == Message.TYPE_IMAGE || file.getMimeType().startsWith("image/");
+ boolean video = message.getMimeType().startsWith("video/");
+ if (image || video) {
+ try {
+ Dimensions dimensions = image ? getImageDimensions(file) : getVideoDimensions(file);
+ if (url == null) {
+ message.setBody(Long.toString(file.getSize()) + '|' + dimensions.width + '|' + dimensions.height);
+ } else {
+ message.setBody(url.toString() + "|" + Long.toString(file.getSize()) + '|' + dimensions.width + '|' + dimensions.height);
+ }
+ return;
+ } catch (NotAVideoFile notAVideoFile) {
+ Log.d(Config.LOGTAG,"file with mime type "+file.getMimeType()+" was not a video file");
+ //fall threw
}
+ }
+ if (url != null) {
+ message.setBody(url.toString()+"|"+Long.toString(file.getSize()));
} else {
- if (url != null) {
- message.setBody(url.toString()+"|"+Long.toString(file.getSize()));
- } else {
- message.setBody(Long.toString(file.getSize()));
+ message.setBody(Long.toString(file.getSize()));
+ }
+
+ }
+
+ private Dimensions getImageDimensions(File file) {
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeFile(file.getAbsolutePath(), options);
+ int rotation = getRotation(file);
+ boolean rotated = rotation == 90 || rotation == 270;
+ int imageHeight = rotated ? options.outWidth : options.outHeight;
+ int imageWidth = rotated ? options.outHeight : options.outWidth;
+ return new Dimensions(imageHeight, imageWidth);
+ }
+
+ private Dimensions getVideoDimensions(File file) throws NotAVideoFile {
+ MediaMetadataRetriever metadataRetriever = new MediaMetadataRetriever();
+ metadataRetriever.setDataSource(file.getAbsolutePath());
+ String hasVideo = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO);
+ if (hasVideo == null) {
+ throw new NotAVideoFile();
+ }
+ int rotation = extractRotationFromMediaRetriever(metadataRetriever);
+ boolean rotated = rotation == 90 || rotation == 270;
+ int height;
+ try {
+ String h = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
+ height = Integer.parseInt(h);
+ } catch (Exception e) {
+ height = -1;
+ }
+ int width;
+ try {
+ String w = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
+ width = Integer.parseInt(w);
+ } catch (Exception e) {
+ width = -1;
+ }
+ metadataRetriever.release();
+ Log.d(Config.LOGTAG,"extracted video dims "+width+"x"+height);
+ return rotated ? new Dimensions(width, height) : new Dimensions(height, width);
+ }
+
+ private int extractRotationFromMediaRetriever(MediaMetadataRetriever metadataRetriever) {
+ int rotation;
+ if (Build.VERSION.SDK_INT >= 17) {
+ String r = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
+ try {
+ rotation = Integer.parseInt(r);
+ } catch (Exception e) {
+ rotation = 0;
}
+ } else {
+ rotation = 0;
}
+ return rotation;
+ }
+
+ private class Dimensions {
+ public final int width;
+ public final int height;
+
+ public Dimensions(int height, int width) {
+ this.width = width;
+ this.height = height;
+ }
+ }
+
+ private class NotAVideoFile extends Exception {
}
diff --git a/src/main/res/drawable-hdpi/play_video.png b/src/main/res/drawable-hdpi/play_video.png
new file mode 100644
index 00000000..70831fe4
--- /dev/null
+++ b/src/main/res/drawable-hdpi/play_video.png
Binary files differ
diff --git a/src/main/res/drawable-mdpi/play_video.png b/src/main/res/drawable-mdpi/play_video.png
new file mode 100644
index 00000000..96ab3988
--- /dev/null
+++ b/src/main/res/drawable-mdpi/play_video.png
Binary files differ
diff --git a/src/main/res/drawable-xhdpi/play_video.png b/src/main/res/drawable-xhdpi/play_video.png
new file mode 100644
index 00000000..d4e6d614
--- /dev/null
+++ b/src/main/res/drawable-xhdpi/play_video.png
Binary files differ
diff --git a/src/main/res/drawable-xxhdpi/play_video.png b/src/main/res/drawable-xxhdpi/play_video.png
new file mode 100644
index 00000000..562a1b62
--- /dev/null
+++ b/src/main/res/drawable-xxhdpi/play_video.png
Binary files differ
diff --git a/src/main/res/drawable-xxxhdpi/play_video.png b/src/main/res/drawable-xxxhdpi/play_video.png
new file mode 100644
index 00000000..16f4d2a1
--- /dev/null
+++ b/src/main/res/drawable-xxxhdpi/play_video.png
Binary files differ