Handle missing video duration.
On EncodingException, or no duration metadata found, when video < 100MB, continue with send.
This commit is contained in:
parent
9d98a779a8
commit
929ee04814
4 changed files with 57 additions and 9 deletions
|
@ -11,6 +11,7 @@ import org.thoughtcrime.securesms.R;
|
|||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
|
||||
import org.thoughtcrime.securesms.mms.MediaConstraints;
|
||||
import org.thoughtcrime.securesms.mms.MediaStream;
|
||||
|
@ -22,6 +23,8 @@ import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
|||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.video.InMemoryTranscoder;
|
||||
import org.thoughtcrime.securesms.video.VideoSourceException;
|
||||
import org.thoughtcrime.securesms.video.VideoSizeException;
|
||||
import org.thoughtcrime.securesms.video.videoconverter.EncodingException;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
@ -31,6 +34,8 @@ import java.util.List;
|
|||
|
||||
final class MediaResizer {
|
||||
|
||||
private static final String TAG = Log.tag(MediaResizer.class);
|
||||
|
||||
@NonNull private final Context context;
|
||||
@NonNull private final MediaConstraints constraints;
|
||||
|
||||
|
@ -114,7 +119,14 @@ final class MediaResizer {
|
|||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException | MmsException | EncodingException e) {
|
||||
} catch (VideoSourceException | EncodingException e) {
|
||||
if (attachment.getSize() > constraints.getVideoMaxSize(context)) {
|
||||
throw new UndeliverableMessageException("Duration not found, attachment too large to skip transcode", e);
|
||||
} else {
|
||||
Log.w(TAG, "Duration not found, video small enough to skip transcode", e);
|
||||
return attachment;
|
||||
}
|
||||
} catch (IOException | MmsException | VideoSizeException e) {
|
||||
throw new UndeliverableMessageException("Failed to transcode", e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import com.google.android.exoplayer2.util.MimeTypes;
|
|||
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.mms.MediaStream;
|
||||
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
||||
import org.thoughtcrime.securesms.util.MemoryFileDescriptor;
|
||||
import org.thoughtcrime.securesms.video.videoconverter.EncodingException;
|
||||
import org.thoughtcrime.securesms.video.videoconverter.MediaConverter;
|
||||
|
@ -53,12 +52,17 @@ public final class InMemoryTranscoder implements Closeable {
|
|||
/**
|
||||
* @param upperSizeLimit A upper size to transcode to. The actual output size can be up to 10% smaller.
|
||||
*/
|
||||
public InMemoryTranscoder(@NonNull Context context, @NonNull MediaDataSource dataSource, long upperSizeLimit) throws IOException {
|
||||
public InMemoryTranscoder(@NonNull Context context, @NonNull MediaDataSource dataSource, long upperSizeLimit) throws IOException, VideoSourceException {
|
||||
this.context = context;
|
||||
this.dataSource = dataSource;
|
||||
|
||||
final MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
|
||||
try {
|
||||
mediaMetadataRetriever.setDataSource(dataSource);
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(TAG, "Unable to read datasource", e);
|
||||
throw new VideoSourceException("Unable to read datasource", e);
|
||||
}
|
||||
|
||||
long upperSizeLimitWithMargin = (long) (upperSizeLimit / 1.1);
|
||||
|
||||
|
@ -80,7 +84,7 @@ public final class InMemoryTranscoder implements Closeable {
|
|||
: OUTPUT_FORMAT;
|
||||
}
|
||||
|
||||
public @NonNull MediaStream transcode(@NonNull Progress progress) throws IOException, UndeliverableMessageException, EncodingException {
|
||||
public @NonNull MediaStream transcode(@NonNull Progress progress) throws IOException, EncodingException, VideoSizeException {
|
||||
if (memoryFile != null) throw new AssertionError("Not expecting to reuse transcoder");
|
||||
|
||||
float durationSec = duration / 1000f;
|
||||
|
@ -107,7 +111,7 @@ public final class InMemoryTranscoder implements Closeable {
|
|||
numberFormat.format(inputBitRate)));
|
||||
|
||||
if (fileSizeEstimate > upperSizeLimit) {
|
||||
throw new UndeliverableMessageException("Size constraints could not be met!");
|
||||
throw new VideoSizeException("Size constraints could not be met!");
|
||||
}
|
||||
|
||||
memoryFile = MemoryFileDescriptor.newMemoryFileDescriptor(context,
|
||||
|
@ -153,7 +157,7 @@ public final class InMemoryTranscoder implements Closeable {
|
|||
numberFormat.format(bitRate(outSize, duration))));
|
||||
|
||||
if (outSize > upperSizeLimit) {
|
||||
throw new UndeliverableMessageException("Size constraints could not be met!");
|
||||
throw new VideoSizeException("Size constraints could not be met!");
|
||||
}
|
||||
|
||||
memoryFile.seek(0);
|
||||
|
@ -185,8 +189,20 @@ public final class InMemoryTranscoder implements Closeable {
|
|||
return Math.max(MINIMUM_TARGET_VIDEO_BITRATE, Math.min(MAXIMUM_TARGET_VIDEO_BITRATE, (int) bitRateToFixTarget));
|
||||
}
|
||||
|
||||
private static long getDuration(MediaMetadataRetriever mediaMetadataRetriever) {
|
||||
return Long.parseLong(mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
|
||||
private static long getDuration(MediaMetadataRetriever mediaMetadataRetriever) throws VideoSourceException {
|
||||
String durationString = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
|
||||
if (durationString == null) {
|
||||
throw new VideoSourceException("Cannot determine duration of video, null meta data");
|
||||
}
|
||||
try {
|
||||
long duration = Long.parseLong(durationString);
|
||||
if (duration <= 0) {
|
||||
throw new VideoSourceException("Cannot determine duration of video, meta data: " + durationString);
|
||||
}
|
||||
return duration;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new VideoSourceException("Cannot determine duration of video, meta data: " + durationString, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean containsLocation(MediaMetadataRetriever mediaMetadataRetriever) {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package org.thoughtcrime.securesms.video;
|
||||
|
||||
public final class VideoSizeException extends Exception {
|
||||
|
||||
VideoSizeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.thoughtcrime.securesms.video;
|
||||
|
||||
public final class VideoSourceException extends Exception {
|
||||
|
||||
VideoSourceException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
VideoSourceException(String message, Exception inner) {
|
||||
super(message, inner);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue