diff options
-rw-r--r-- | art/play_video.svg | 59 | ||||
-rwxr-xr-x | art/render.rb | 5 | ||||
-rw-r--r-- | src/main/java/eu/siacs/conversations/persistance/FileBackend.java | 140 | ||||
-rw-r--r-- | src/main/res/drawable-hdpi/play_video.png | bin | 0 -> 3813 bytes | |||
-rw-r--r-- | src/main/res/drawable-mdpi/play_video.png | bin | 0 -> 2432 bytes | |||
-rw-r--r-- | src/main/res/drawable-xhdpi/play_video.png | bin | 0 -> 5087 bytes | |||
-rw-r--r-- | src/main/res/drawable-xxhdpi/play_video.png | bin | 0 -> 7824 bytes | |||
-rw-r--r-- | src/main/res/drawable-xxxhdpi/play_video.png | bin | 0 -> 10668 bytes |
8 files changed, 178 insertions, 26 deletions
diff --git a/art/play_video.svg b/art/play_video.svg new file mode 100644 index 000000000..083e7cfad --- /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 0acadfd82..2d1e5abcd 100755 --- a/art/render.rb +++ b/art/render.rb @@ -11,8 +11,9 @@ resolutions = { } images = { - 'conversations_baloon.svg' => ['ic_launcher', 48], - 'conversations_baloon.svg' => ['main_logo', 200], + '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_read_indicator.svg' => ['ic_read_indicator', 12], diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 619e12680..9ef92a07e 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; @@ -406,21 +407,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)); @@ -682,26 +705,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 Binary files differnew file mode 100644 index 000000000..70831fe4b --- /dev/null +++ b/src/main/res/drawable-hdpi/play_video.png diff --git a/src/main/res/drawable-mdpi/play_video.png b/src/main/res/drawable-mdpi/play_video.png Binary files differnew file mode 100644 index 000000000..96ab3988a --- /dev/null +++ b/src/main/res/drawable-mdpi/play_video.png diff --git a/src/main/res/drawable-xhdpi/play_video.png b/src/main/res/drawable-xhdpi/play_video.png Binary files differnew file mode 100644 index 000000000..d4e6d6147 --- /dev/null +++ b/src/main/res/drawable-xhdpi/play_video.png diff --git a/src/main/res/drawable-xxhdpi/play_video.png b/src/main/res/drawable-xxhdpi/play_video.png Binary files differnew file mode 100644 index 000000000..562a1b623 --- /dev/null +++ b/src/main/res/drawable-xxhdpi/play_video.png diff --git a/src/main/res/drawable-xxxhdpi/play_video.png b/src/main/res/drawable-xxxhdpi/play_video.png Binary files differnew file mode 100644 index 000000000..16f4d2a18 --- /dev/null +++ b/src/main/res/drawable-xxxhdpi/play_video.png |