mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 09:17:44 +00:00
Improve video thumbnail generation and handling on send side
For direct attach only // FREEBIE
This commit is contained in:
parent
ad4657df1f
commit
8e7c7a9c54
@ -355,7 +355,7 @@ public class ConversationItem extends LinearLayout
|
|||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
mediaThumbnailStub.get().setImageResource(masterSecret,
|
mediaThumbnailStub.get().setImageResource(masterSecret,
|
||||||
((MmsMessageRecord)messageRecord).getSlideDeck().getThumbnailSlide(),
|
((MmsMessageRecord)messageRecord).getSlideDeck().getThumbnailSlide(),
|
||||||
showControls);
|
showControls, false);
|
||||||
mediaThumbnailStub.get().setThumbnailClickListener(new ThumbnailClickListener());
|
mediaThumbnailStub.get().setThumbnailClickListener(new ThumbnailClickListener());
|
||||||
mediaThumbnailStub.get().setDownloadClickListener(downloadClickListener);
|
mediaThumbnailStub.get().setDownloadClickListener(downloadClickListener);
|
||||||
mediaThumbnailStub.get().setOnLongClickListener(passthroughClickListener);
|
mediaThumbnailStub.get().setOnLongClickListener(passthroughClickListener);
|
||||||
|
@ -72,7 +72,7 @@ public class MediaAdapter extends CursorRecyclerViewAdapter<ViewHolder> {
|
|||||||
Slide slide = MediaUtil.getSlideForAttachment(getContext(), mediaRecord.getAttachment());
|
Slide slide = MediaUtil.getSlideForAttachment(getContext(), mediaRecord.getAttachment());
|
||||||
|
|
||||||
if (slide != null) {
|
if (slide != null) {
|
||||||
imageView.setImageResource(masterSecret, slide, false);
|
imageView.setImageResource(masterSecret, slide, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
imageView.setOnClickListener(new OnMediaClickListener(mediaRecord));
|
imageView.setOnClickListener(new OnMediaClickListener(mediaRecord));
|
||||||
|
@ -99,7 +99,7 @@ public class ThumbnailView extends FrameLayout {
|
|||||||
this.backgroundColorHint = color;
|
this.backgroundColorHint = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setImageResource(@NonNull MasterSecret masterSecret, @NonNull Slide slide, boolean showControls) {
|
public void setImageResource(@NonNull MasterSecret masterSecret, @NonNull Slide slide, boolean showControls, boolean isPreview) {
|
||||||
if (showControls) {
|
if (showControls) {
|
||||||
getTransferControls().setSlide(slide);
|
getTransferControls().setSlide(slide);
|
||||||
getTransferControls().setDownloadClickListener(new DownloadClickDispatcher());
|
getTransferControls().setDownloadClickListener(new DownloadClickDispatcher());
|
||||||
@ -107,7 +107,9 @@ public class ThumbnailView extends FrameLayout {
|
|||||||
getTransferControls().setVisibility(View.GONE);
|
getTransferControls().setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slide.getThumbnailUri() != null && slide.hasPlayOverlay() && slide.getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_DONE) {
|
if (slide.getThumbnailUri() != null && slide.hasPlayOverlay() &&
|
||||||
|
(slide.getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_DONE || isPreview))
|
||||||
|
{
|
||||||
this.playOverlay.setVisibility(View.VISIBLE);
|
this.playOverlay.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
this.playOverlay.setVisibility(View.GONE);
|
this.playOverlay.setVisibility(View.GONE);
|
||||||
|
@ -50,6 +50,8 @@ import org.thoughtcrime.securesms.util.Util;
|
|||||||
import org.thoughtcrime.securesms.video.EncryptedMediaDataSource;
|
import org.thoughtcrime.securesms.video.EncryptedMediaDataSource;
|
||||||
import org.whispersystems.libsignal.InvalidMessageException;
|
import org.whispersystems.libsignal.InvalidMessageException;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -527,8 +529,20 @@ public class AttachmentDatabase extends Database {
|
|||||||
AttachmentId attachmentId = new AttachmentId(rowId, uniqueId);
|
AttachmentId attachmentId = new AttachmentId(rowId, uniqueId);
|
||||||
|
|
||||||
if (partData != null) {
|
if (partData != null) {
|
||||||
Log.w(TAG, "Submitting thumbnail generation job...");
|
if (MediaUtil.hasVideoThumbnail(attachment.getDataUri())) {
|
||||||
thumbnailExecutor.submit(new ThumbnailFetchCallable(masterSecret.getMasterSecret().get(), attachmentId));
|
Bitmap bitmap = MediaUtil.getVideoThumbnail(context, attachment.getDataUri());
|
||||||
|
|
||||||
|
if (bitmap != null) {
|
||||||
|
ThumbnailData thumbnailData = new ThumbnailData(bitmap);
|
||||||
|
updateAttachmentThumbnail(masterSecret.getMasterSecret().get(), attachmentId, thumbnailData.toDataStream(), thumbnailData.getAspectRatio());
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "Retrieving video thumbnail failed, submitting thumbnail generation job...");
|
||||||
|
thumbnailExecutor.submit(new ThumbnailFetchCallable(masterSecret.getMasterSecret().get(), attachmentId));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "Submitting thumbnail generation job...");
|
||||||
|
thumbnailExecutor.submit(new ThumbnailFetchCallable(masterSecret.getMasterSecret().get(), attachmentId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return attachmentId;
|
return attachmentId;
|
||||||
|
@ -247,7 +247,7 @@ public class AttachmentManager {
|
|||||||
documentView.setDocument((DocumentSlide) slide, false);
|
documentView.setDocument((DocumentSlide) slide, false);
|
||||||
removableMediaView.display(documentView, false);
|
removableMediaView.display(documentView, false);
|
||||||
} else {
|
} else {
|
||||||
thumbnail.setImageResource(masterSecret, slide, false);
|
thumbnail.setImageResource(masterSecret, slide, false, true);
|
||||||
removableMediaView.display(thumbnail, mediaType == MediaType.IMAGE);
|
removableMediaView.display(thumbnail, mediaType == MediaType.IMAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,13 +2,17 @@ package org.thoughtcrime.securesms.mms;
|
|||||||
|
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.bumptech.glide.load.data.StreamLocalUriFetcher;
|
import com.bumptech.glide.load.data.StreamLocalUriFetcher;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
|
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -28,6 +32,16 @@ public class DecryptableStreamLocalUriFetcher extends StreamLocalUriFetcher {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InputStream loadResource(Uri uri, ContentResolver contentResolver) throws FileNotFoundException {
|
protected InputStream loadResource(Uri uri, ContentResolver contentResolver) throws FileNotFoundException {
|
||||||
|
if (MediaUtil.hasVideoThumbnail(uri)) {
|
||||||
|
Bitmap thumbnail = MediaUtil.getVideoThumbnail(context, uri);
|
||||||
|
|
||||||
|
if (thumbnail != null) {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, baos);
|
||||||
|
return new ByteArrayInputStream(baos.toByteArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return PartAuthority.getAttachmentStream(context, masterSecret, uri);
|
return PartAuthority.getAttachmentStream(context, masterSecret, uri);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
|
@ -24,6 +24,7 @@ import android.support.annotation.NonNull;
|
|||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||||
|
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||||
import org.thoughtcrime.securesms.util.ResUtil;
|
import org.thoughtcrime.securesms.util.ResUtil;
|
||||||
|
|
||||||
import ws.com.google.android.mms.ContentType;
|
import ws.com.google.android.mms.ContentType;
|
||||||
@ -31,7 +32,7 @@ import ws.com.google.android.mms.ContentType;
|
|||||||
public class VideoSlide extends Slide {
|
public class VideoSlide extends Slide {
|
||||||
|
|
||||||
public VideoSlide(Context context, Uri uri, long dataSize) {
|
public VideoSlide(Context context, Uri uri, long dataSize) {
|
||||||
super(context, constructAttachmentFromUri(context, uri, ContentType.VIDEO_UNSPECIFIED, dataSize, false, null));
|
super(context, constructAttachmentFromUri(context, uri, ContentType.VIDEO_UNSPECIFIED, dataSize, MediaUtil.hasVideoThumbnail(uri), null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public VideoSlide(Context context, Attachment attachment) {
|
public VideoSlide(Context context, Attachment attachment) {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package org.thoughtcrime.securesms.util;
|
package org.thoughtcrime.securesms.util;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.provider.MediaStore;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@ -162,6 +164,33 @@ public class MediaUtil {
|
|||||||
return !TextUtils.isEmpty(contentType) && contentType.trim().startsWith("video/");
|
return !TextUtils.isEmpty(contentType) && contentType.trim().startsWith("video/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasVideoThumbnail(Uri uri) {
|
||||||
|
Log.w(TAG, "Checking: " + uri);
|
||||||
|
|
||||||
|
if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
|
||||||
|
return uri.getLastPathSegment().contains("video");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @Nullable Bitmap getVideoThumbnail(Context context, Uri uri) {
|
||||||
|
if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
|
||||||
|
long videoId = Long.parseLong(uri.getLastPathSegment().split(":")[1]);
|
||||||
|
|
||||||
|
return MediaStore.Video.Thumbnails.getThumbnail(context.getContentResolver(),
|
||||||
|
videoId,
|
||||||
|
MediaStore.Images.Thumbnails.MINI_KIND,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static @Nullable String getDiscreteMimeType(@NonNull String mimeType) {
|
public static @Nullable String getDiscreteMimeType(@NonNull String mimeType) {
|
||||||
final String[] sections = mimeType.split("/", 2);
|
final String[] sections = mimeType.split("/", 2);
|
||||||
return sections.length > 1 ? sections[0] : null;
|
return sections.length > 1 ? sections[0] : null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user