OutputFileOptions.java
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.camera.view.video;
import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
import androidx.core.util.Preconditions;
import com.google.auto.value.AutoValue;
import java.io.File;
/**
* Options for saving newly captured video.
*
* <p> this class is used to configure save location and metadata. Save location can be
* either a {@link File}, {@link MediaStore}. The metadata will be
* stored with the saved video.
*/
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
@ExperimentalVideo
@AutoValue
public abstract class OutputFileOptions {
// Empty metadata object used as a placeholder for no user-supplied metadata.
// Should be initialized to all default values.
private static final Metadata EMPTY_METADATA = Metadata.builder().build();
// Restrict constructor to same package
OutputFileOptions() {
}
/**
* Creates options to write captured video to a {@link File}.
*
* @param file save location of the video.
*/
@NonNull
public static Builder builder(@NonNull File file) {
return new AutoValue_OutputFileOptions.Builder().setMetadata(EMPTY_METADATA).setFile(file);
}
/**
* Creates options to write captured video to a {@link ParcelFileDescriptor}.
*
* <p>Using a ParcelFileDescriptor to record a video is only supported for Android 8.0 or
* above.
*
* @param fileDescriptor to save the video.
* @throws IllegalArgumentException when the device is not running Android 8.0 or above.
*/
@NonNull
public static Builder builder(@NonNull ParcelFileDescriptor fileDescriptor) {
Preconditions.checkArgument(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O,
"Using a ParcelFileDescriptor to record a video is only supported for Android 8"
+ ".0 or above.");
return new AutoValue_OutputFileOptions.Builder().setMetadata(
EMPTY_METADATA).setFileDescriptor(fileDescriptor);
}
/**
* Creates options to write captured video to {@link MediaStore}.
*
* Example:
*
* <pre>{@code
*
* ContentValues contentValues = new ContentValues();
* contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "NEW_VIDEO");
* contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
*
* OutputFileOptions options = OutputFileOptions.builder(
* getContentResolver(),
* MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
* contentValues).build();
*
* }</pre>
*
* @param contentResolver to access {@link MediaStore}
* @param saveCollection The URI of the table to insert into.
* @param contentValues to be included in the created video file.
*/
@NonNull
public static Builder builder(@NonNull ContentResolver contentResolver,
@NonNull Uri saveCollection,
@NonNull ContentValues contentValues) {
return new AutoValue_OutputFileOptions.Builder()
.setMetadata(EMPTY_METADATA)
.setContentResolver(contentResolver)
.setSaveCollection(saveCollection).setContentValues(contentValues);
}
/**
* Returns the File object which is set by the {@link OutputFileOptions.Builder}.
*/
@Nullable
abstract File getFile();
/**
* Returns the ParcelFileDescriptor object which is set by the
* {@link OutputFileOptions.Builder}.
*/
@Nullable
abstract ParcelFileDescriptor getFileDescriptor();
/**
* Returns the content resolver which is set by the {@link OutputFileOptions.Builder}.
*/
@Nullable
abstract ContentResolver getContentResolver();
/**
* Returns the URI which is set by the {@link OutputFileOptions.Builder}.
*/
@Nullable
abstract Uri getSaveCollection();
/**
* Returns the content values which is set by the {@link OutputFileOptions.Builder}.
*/
@Nullable
abstract ContentValues getContentValues();
/** Returns the metadata which is set by the {@link OutputFileOptions.Builder}. */
@NonNull
public abstract Metadata getMetadata();
/**
* Checking the caller wants to save video to MediaStore.
*/
private boolean isSavingToMediaStore() {
return getSaveCollection() != null && getContentResolver() != null
&& getContentValues() != null;
}
/**
* Checking the caller wants to save video to a File.
*/
private boolean isSavingToFile() {
return getFile() != null;
}
/**
* Checking the caller wants to save video to a ParcelFileDescriptor.
*/
private boolean isSavingToFileDescriptor() {
return getFileDescriptor() != null;
}
/**
* Converts to a {@link androidx.camera.core.VideoCapture.OutputFileOptions}.
*
* @hide
*/
@RestrictTo(LIBRARY)
@SuppressWarnings("deprecation")
@NonNull
public androidx.camera.core.VideoCapture.OutputFileOptions toVideoCaptureOutputFileOptions() {
androidx.camera.core.VideoCapture.OutputFileOptions.Builder
internalOutputFileOptionsBuilder;
if (isSavingToFile()) {
internalOutputFileOptionsBuilder =
new androidx.camera.core.VideoCapture.OutputFileOptions.Builder(
Preconditions.checkNotNull(getFile()));
} else if (isSavingToFileDescriptor()) {
internalOutputFileOptionsBuilder =
new androidx.camera.core.VideoCapture.OutputFileOptions.Builder(
Preconditions.checkNotNull(getFileDescriptor()).getFileDescriptor());
} else {
Preconditions.checkState(isSavingToMediaStore());
internalOutputFileOptionsBuilder =
new androidx.camera.core.VideoCapture.OutputFileOptions.Builder(
Preconditions.checkNotNull(getContentResolver()),
Preconditions.checkNotNull(getSaveCollection()),
Preconditions.checkNotNull(getContentValues()));
}
androidx.camera.core.VideoCapture.Metadata internalMetadata =
new androidx.camera.core.VideoCapture.Metadata();
internalMetadata.location = getMetadata().getLocation();
internalOutputFileOptionsBuilder.setMetadata(internalMetadata);
return internalOutputFileOptionsBuilder.build();
}
/**
* Builder class for {@link OutputFileOptions}.
*/
@AutoValue.Builder
@SuppressWarnings("StaticFinalBuilder")
public abstract static class Builder {
// Restrict construction to same package
Builder() {
}
abstract Builder setFile(@Nullable File file);
abstract Builder setFileDescriptor(@Nullable ParcelFileDescriptor fileDescriptor);
abstract Builder setContentResolver(@Nullable ContentResolver contentResolver);
abstract Builder setSaveCollection(@Nullable Uri uri);
abstract Builder setContentValues(@Nullable ContentValues contentValues);
/**
* Sets the metadata to be stored with the saved video.
*
* @param metadata Metadata to be stored with the saved video.
*/
@NonNull
public abstract Builder setMetadata(@NonNull Metadata metadata);
/**
* Builds {@link OutputFileOptions}.
*/
@NonNull
public abstract OutputFileOptions build();
}
}