diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java index b5750762a7..843c4c1d6c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentCompressionJob.java @@ -249,10 +249,12 @@ public final class AttachmentCompressionJob extends BaseJob { throw new UndeliverableMessageException("Cannot get media data source for attachment."); } - allowSkipOnFailure = !transformProperties.getVideoEdited(); TranscoderOptions options = null; - if (transformProperties.videoTrim) { - options = new TranscoderOptions(transformProperties.videoTrimStartTimeUs, transformProperties.videoTrimEndTimeUs); + if (transformProperties != null) { + allowSkipOnFailure = !transformProperties.getVideoEdited(); + if (transformProperties.videoTrim) { + options = new TranscoderOptions(transformProperties.videoTrimStartTimeUs, transformProperties.videoTrimEndTimeUs); + } } if (FeatureFlags.useStreamingVideoMuxer()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/scribbles/VideoEditorHud.java b/app/src/main/java/org/thoughtcrime/securesms/scribbles/VideoEditorHud.java index d84faa53f8..62bfc7b624 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/scribbles/VideoEditorHud.java +++ b/app/src/main/java/org/thoughtcrime/securesms/scribbles/VideoEditorHud.java @@ -98,7 +98,7 @@ public final class VideoEditorHud extends LinearLayout { long size = tryGetUriSize(getContext(), uri, Long.MAX_VALUE); if (size > maxSendSize) { - videoTimeLine.setTimeLimit(VideoUtil.getMaxVideoUploadDurationInSeconds(), TimeUnit.SECONDS); + videoTimeLine.setTimeLimit(videoBitRateCalculator.getMaxVideoUploadDurationInSeconds(), TimeUnit.SECONDS); } videoTimeLine.setOnRangeChangeListener(new VideoThumbnailsRangeSelectorView.OnRangeChangeListener() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/video/InMemoryTranscoder.java b/app/src/main/java/org/thoughtcrime/securesms/video/InMemoryTranscoder.java index 438d426670..82b544fe9e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/video/InMemoryTranscoder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/video/InMemoryTranscoder.java @@ -27,6 +27,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.text.NumberFormat; import java.util.Locale; +import java.util.concurrent.TimeUnit; @RequiresApi(26) public final class InMemoryTranscoder implements Closeable { @@ -63,8 +64,13 @@ public final class InMemoryTranscoder implements Closeable { throw new VideoSourceException("Unable to read datasource", e); } + if (options != null && options.endTimeUs != 0) { + this.duration = TimeUnit.MICROSECONDS.toMillis(options.endTimeUs - options.startTimeUs); + } else { + this.duration = getDuration(mediaMetadataRetriever); + } + this.inSize = dataSource.getSize(); - this.duration = getDuration(mediaMetadataRetriever); this.inputBitRate = VideoBitRateCalculator.bitRate(inSize, duration); this.targetQuality = new VideoBitRateCalculator(upperSizeLimit).getTargetQuality(duration, inputBitRate); this.upperSizeLimit = upperSizeLimit; diff --git a/app/src/main/java/org/thoughtcrime/securesms/video/VideoUtil.java b/app/src/main/java/org/thoughtcrime/securesms/video/VideoUtil.java index ed8f53f160..b5c64af1f5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/video/VideoUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/video/VideoUtil.java @@ -29,10 +29,6 @@ public final class VideoUtil { return Math.min(duration, VideoConstants.VIDEO_MAX_RECORD_LENGTH_S); } - public static int getMaxVideoUploadDurationInSeconds() { - return Math.toIntExact(TimeUnit.MINUTES.toSeconds(10)); - } - private static Size screenSize() { DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); return new Size(metrics.widthPixels, metrics.heightPixels); diff --git a/video/lib/src/main/java/org/thoughtcrime/securesms/video/StreamingTranscoder.java b/video/lib/src/main/java/org/thoughtcrime/securesms/video/StreamingTranscoder.java index b1e7520715..d5e8ea11ab 100644 --- a/video/lib/src/main/java/org/thoughtcrime/securesms/video/StreamingTranscoder.java +++ b/video/lib/src/main/java/org/thoughtcrime/securesms/video/StreamingTranscoder.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.OutputStream; import java.text.NumberFormat; import java.util.Locale; +import java.util.concurrent.TimeUnit; @RequiresApi(26) public final class StreamingTranscoder { @@ -58,8 +59,13 @@ public final class StreamingTranscoder { throw new VideoSourceException("Unable to read datasource", e); } + if (options != null && options.endTimeUs != 0) { + this.duration = TimeUnit.MICROSECONDS.toMillis(options.endTimeUs - options.startTimeUs); + } else { + this.duration = getDuration(mediaMetadataRetriever); + } + this.inSize = dataSource.getSize(); - this.duration = getDuration(mediaMetadataRetriever); this.inputBitRate = VideoBitRateCalculator.bitRate(inSize, duration); this.targetQuality = new VideoBitRateCalculator(upperSizeLimit).getTargetQuality(duration, inputBitRate); this.upperSizeLimit = upperSizeLimit; diff --git a/video/lib/src/main/java/org/thoughtcrime/securesms/video/VideoBitRateCalculator.java b/video/lib/src/main/java/org/thoughtcrime/securesms/video/VideoBitRateCalculator.java index 016696982a..47bb0c7b79 100644 --- a/video/lib/src/main/java/org/thoughtcrime/securesms/video/VideoBitRateCalculator.java +++ b/video/lib/src/main/java/org/thoughtcrime/securesms/video/VideoBitRateCalculator.java @@ -7,11 +7,6 @@ import org.thoughtcrime.securesms.video.videoconverter.utils.VideoConstants; */ public final class VideoBitRateCalculator { - private static final int MAXIMUM_TARGET_VIDEO_BITRATE = VideoConstants.VIDEO_BIT_RATE; - private static final int LOW_RES_TARGET_VIDEO_BITRATE = 1_750_000; - private static final int MINIMUM_TARGET_VIDEO_BITRATE = 500_000; - private static final int LOW_RES_OUTPUT_FORMAT = 480; - private final long upperFileSizeLimitWithMargin; public VideoBitRateCalculator(long upperFileSizeLimit) { @@ -22,13 +17,13 @@ public final class VideoBitRateCalculator { * Gets the output quality of a video of the given {@param duration}. */ public TranscodingQuality getTargetQuality(long duration, int inputTotalBitRate) { - int maxVideoBitRate = Math.min(MAXIMUM_TARGET_VIDEO_BITRATE, inputTotalBitRate - VideoConstants.AUDIO_BIT_RATE); - int minVideoBitRate = Math.min(MINIMUM_TARGET_VIDEO_BITRATE, maxVideoBitRate); + int maxVideoBitRate = Math.min(VideoConstants.VIDEO_TARGET_BIT_RATE, inputTotalBitRate - VideoConstants.AUDIO_BIT_RATE); + int minVideoBitRate = Math.min(VideoConstants.VIDEO_MINIMUM_TARGET_BIT_RATE, maxVideoBitRate); int targetVideoBitRate = Math.max(minVideoBitRate, Math.min(getTargetVideoBitRate(upperFileSizeLimitWithMargin, duration), maxVideoBitRate)); int bitRateRange = maxVideoBitRate - minVideoBitRate; double quality = bitRateRange == 0 ? 1 : (targetVideoBitRate - minVideoBitRate) / (double) bitRateRange; - int outputResolution = targetVideoBitRate < LOW_RES_TARGET_VIDEO_BITRATE ? LOW_RES_OUTPUT_FORMAT : VideoConstants.VIDEO_SHORT_EDGE; + int outputResolution = targetVideoBitRate < VideoConstants.LOW_RES_TARGET_VIDEO_BITRATE ? VideoConstants.LOW_RES_OUTPUT_FORMAT : VideoConstants.VIDEO_SHORT_EDGE; return new TranscodingQuality(targetVideoBitRate, VideoConstants.AUDIO_BIT_RATE, Math.max(0, Math.min(quality, 1)), duration, outputResolution); } @@ -47,4 +42,8 @@ public final class VideoBitRateCalculator { return (int) (bytes * 8 / (durationMs / 1000f)); } + public int getMaxVideoUploadDurationInSeconds() { + long totalMinimumBitrate = VideoConstants.VIDEO_MINIMUM_TARGET_BIT_RATE + VideoConstants.AUDIO_BIT_RATE; + return Math.toIntExact((upperFileSizeLimitWithMargin * 8) / totalMinimumBitrate); + } } diff --git a/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/utils/VideoConstants.kt b/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/utils/VideoConstants.kt index 3a7f8ba010..9d55b90030 100644 --- a/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/utils/VideoConstants.kt +++ b/video/lib/src/main/java/org/thoughtcrime/securesms/video/videoconverter/utils/VideoConstants.kt @@ -7,13 +7,16 @@ package org.thoughtcrime.securesms.video.videoconverter.utils import android.media.MediaFormat object VideoConstants { - const val AUDIO_BIT_RATE = 192000 + const val AUDIO_BIT_RATE = 192_000 const val VIDEO_FRAME_RATE = 30 - const val VIDEO_BIT_RATE = 2000000 + const val VIDEO_TARGET_BIT_RATE = 2_000_000 + const val VIDEO_MINIMUM_TARGET_BIT_RATE = 500_000 + const val LOW_RES_TARGET_VIDEO_BITRATE = 1_750_000 + const val LOW_RES_OUTPUT_FORMAT = 480 const val VIDEO_SHORT_EDGE = 720 const val VIDEO_LONG_EDGE = 1280 const val VIDEO_MAX_RECORD_LENGTH_S = 60 - const val TOTAL_BYTES_PER_SECOND = VIDEO_BIT_RATE / 8 + AUDIO_BIT_RATE / 8 + const val TOTAL_BYTES_PER_SECOND = VIDEO_TARGET_BIT_RATE / 8 + AUDIO_BIT_RATE / 8 const val VIDEO_MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC const val AUDIO_MIME_TYPE = MediaFormat.MIMETYPE_AUDIO_AAC const val RECORDED_VIDEO_CONTENT_TYPE: String = "video/mp4"