mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-26 06:07:32 +00:00
Update max video duration for MMS.
This commit is contained in:
@@ -47,6 +47,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|||||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
|
||||||
|
import org.thoughtcrime.securesms.video.VideoUtil;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
@@ -237,11 +238,15 @@ public class CameraXFragment extends Fragment implements CameraFragment {
|
|||||||
|
|
||||||
camera.setCaptureMode(CameraXView.CaptureMode.MIXED);
|
camera.setCaptureMode(CameraXView.CaptureMode.MIXED);
|
||||||
|
|
||||||
|
int maxDuration = VideoUtil.getMaxVideoDurationInSeconds(requireContext(), viewModel.getMediaConstraints());
|
||||||
|
Log.d(TAG, "Max duration: " + maxDuration + " sec");
|
||||||
|
|
||||||
captureButton.setVideoCaptureListener(new CameraXVideoCaptureHelper(
|
captureButton.setVideoCaptureListener(new CameraXVideoCaptureHelper(
|
||||||
this,
|
this,
|
||||||
captureButton,
|
captureButton,
|
||||||
camera,
|
camera,
|
||||||
videoFileDescriptor,
|
videoFileDescriptor,
|
||||||
|
maxDuration,
|
||||||
new CameraXVideoCaptureHelper.Callback() {
|
new CameraXVideoCaptureHelper.Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void onVideoRecordStarted() {
|
public void onVideoRecordStarted() {
|
||||||
@@ -266,14 +271,20 @@ public class CameraXFragment extends Fragment implements CameraFragment {
|
|||||||
Log.w(TAG, "Video capture is not supported on this device.", e);
|
Log.w(TAG, "Video capture is not supported on this device.", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.i(TAG, "Video capture not supported. API: " + Build.VERSION.SDK_INT + ", MFD: " + MemoryFileDescriptor.supported() + ", Camera: " + CameraXUtil.getLowestSupportedHardwareLevel(requireContext()));
|
Log.i(TAG, "Video capture not supported. " +
|
||||||
|
"API: " + Build.VERSION.SDK_INT + ", " +
|
||||||
|
"MFD: " + MemoryFileDescriptor.supported() + ", " +
|
||||||
|
"Camera: " + CameraXUtil.getLowestSupportedHardwareLevel(requireContext()) + ", " +
|
||||||
|
"MaxDuration: " + VideoUtil.getMaxVideoDurationInSeconds(requireContext(), viewModel.getMediaConstraints()) + " sec");
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.onCameraControlsInitialized();
|
viewModel.onCameraControlsInitialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isVideoRecordingSupported(@NonNull Context context) {
|
private boolean isVideoRecordingSupported(@NonNull Context context) {
|
||||||
return MediaConstraints.isVideoTranscodeAvailable() && CameraXUtil.isMixedModeSupported(context);
|
return MediaConstraints.isVideoTranscodeAvailable() &&
|
||||||
|
CameraXUtil.isMixedModeSupported(context) &&
|
||||||
|
VideoUtil.getMaxVideoDurationInSeconds(context, viewModel.getMediaConstraints()) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayVideoRecordingTooltipIfNecessary(CameraButtonView captureButton) {
|
private void displayVideoRecordingTooltipIfNecessary(CameraButtonView captureButton) {
|
||||||
|
@@ -40,11 +40,10 @@ class CameraXVideoCaptureHelper implements CameraButtonView.VideoCaptureListener
|
|||||||
private final @NonNull CameraXView camera;
|
private final @NonNull CameraXView camera;
|
||||||
private final @NonNull Callback callback;
|
private final @NonNull Callback callback;
|
||||||
private final @NonNull MemoryFileDescriptor memoryFileDescriptor;
|
private final @NonNull MemoryFileDescriptor memoryFileDescriptor;
|
||||||
|
private final @NonNull ValueAnimator updateProgressAnimator;
|
||||||
|
|
||||||
private boolean isRecording;
|
private boolean isRecording;
|
||||||
private ValueAnimator cameraMetricsAnimator;
|
private ValueAnimator cameraMetricsAnimator;
|
||||||
private final ValueAnimator updateProgressAnimator = ValueAnimator.ofFloat(0f, 1f)
|
|
||||||
.setDuration(VideoUtil.VIDEO_MAX_LENGTH_S * 1000);
|
|
||||||
|
|
||||||
private final VideoCapture.OnVideoSavedListener videoSavedListener = new VideoCapture.OnVideoSavedListener() {
|
private final VideoCapture.OnVideoSavedListener videoSavedListener = new VideoCapture.OnVideoSavedListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -74,12 +73,14 @@ class CameraXVideoCaptureHelper implements CameraButtonView.VideoCaptureListener
|
|||||||
@NonNull CameraButtonView captureButton,
|
@NonNull CameraButtonView captureButton,
|
||||||
@NonNull CameraXView camera,
|
@NonNull CameraXView camera,
|
||||||
@NonNull MemoryFileDescriptor memoryFileDescriptor,
|
@NonNull MemoryFileDescriptor memoryFileDescriptor,
|
||||||
|
int maxVideoDurationSec,
|
||||||
@NonNull Callback callback)
|
@NonNull Callback callback)
|
||||||
{
|
{
|
||||||
this.fragment = fragment;
|
this.fragment = fragment;
|
||||||
this.camera = camera;
|
this.camera = camera;
|
||||||
this.memoryFileDescriptor = memoryFileDescriptor;
|
this.memoryFileDescriptor = memoryFileDescriptor;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
this.updateProgressAnimator = ValueAnimator.ofFloat(0f, 1f).setDuration(maxVideoDurationSec * 1000);
|
||||||
|
|
||||||
updateProgressAnimator.setInterpolator(new LinearInterpolator());
|
updateProgressAnimator.setInterpolator(new LinearInterpolator());
|
||||||
updateProgressAnimator.addUpdateListener(anim -> captureButton.setProgress(anim.getAnimatedFraction()));
|
updateProgressAnimator.addUpdateListener(anim -> captureButton.setProgress(anim.getAnimatedFraction()));
|
||||||
|
@@ -455,6 +455,10 @@ class MediaSendViewModel extends ViewModel {
|
|||||||
return FeatureFlags.VIEW_ONCE_SENDING && viewOnceState == ViewOnceState.ENABLED;
|
return FeatureFlags.VIEW_ONCE_SENDING && viewOnceState == ViewOnceState.ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull MediaConstraints getMediaConstraints() {
|
||||||
|
return mediaConstraints;
|
||||||
|
}
|
||||||
|
|
||||||
private @NonNull List<Media> getSelectedMediaOrDefault() {
|
private @NonNull List<Media> getSelectedMediaOrDefault() {
|
||||||
return selectedMedia.getValue() == null ? Collections.emptyList()
|
return selectedMedia.getValue() == null ? Collections.emptyList()
|
||||||
: selectedMedia.getValue();
|
: selectedMedia.getValue();
|
||||||
|
@@ -1,12 +1,15 @@
|
|||||||
package org.thoughtcrime.securesms.video;
|
package org.thoughtcrime.securesms.video;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.media.MediaFormat;
|
import android.media.MediaFormat;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Size;
|
import android.util.Size;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.mms.MediaConstraints;
|
||||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||||
|
|
||||||
public final class VideoUtil {
|
public final class VideoUtil {
|
||||||
@@ -18,6 +21,8 @@ public final class VideoUtil {
|
|||||||
public static final int VIDEO_SHORT_WIDTH = 720;
|
public static final int VIDEO_SHORT_WIDTH = 720;
|
||||||
public static final int VIDEO_MAX_LENGTH_S = 30;
|
public static final int VIDEO_MAX_LENGTH_S = 30;
|
||||||
|
|
||||||
|
private static final int TOTAL_BYTES_PER_SECOND = (VIDEO_BIT_RATE / 8) + (AUDIO_BIT_RATE / 8);
|
||||||
|
|
||||||
@RequiresApi(21)
|
@RequiresApi(21)
|
||||||
public static final String VIDEO_MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
|
public static final String VIDEO_MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
|
||||||
public static final String AUDIO_MIME_TYPE = "audio/mp4a-latm";
|
public static final String AUDIO_MIME_TYPE = "audio/mp4a-latm";
|
||||||
@@ -33,6 +38,13 @@ public final class VideoUtil {
|
|||||||
: new Size(VIDEO_LONG_WIDTH, VIDEO_SHORT_WIDTH);
|
: new Size(VIDEO_LONG_WIDTH, VIDEO_SHORT_WIDTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getMaxVideoDurationInSeconds(@NonNull Context context, @NonNull MediaConstraints mediaConstraints) {
|
||||||
|
int allowedSize = mediaConstraints.getCompressedVideoMaxSize(context);
|
||||||
|
int duration = (int) Math.floor((float) allowedSize / TOTAL_BYTES_PER_SECOND);
|
||||||
|
|
||||||
|
return Math.min(duration, VIDEO_MAX_LENGTH_S);
|
||||||
|
}
|
||||||
|
|
||||||
@RequiresApi(21)
|
@RequiresApi(21)
|
||||||
private static Size screenSize() {
|
private static Size screenSize() {
|
||||||
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
|
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
|
||||||
|
Reference in New Issue
Block a user