StreamingTranscoder sample app.

This commit is contained in:
Nicholas Tinsley
2024-01-12 18:18:01 -05:00
committed by Greyson Parrelli
parent 750fd4efe1
commit c7609f9a2a
46 changed files with 880 additions and 254 deletions

View File

@@ -1,52 +0,0 @@
package org.thoughtcrime.securesms.media;
import android.content.Context;
import android.media.MediaDataSource;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import org.thoughtcrime.securesms.attachments.AttachmentId;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.mms.PartUriParser;
import org.thoughtcrime.securesms.providers.BlobProvider;
import java.io.IOException;
@RequiresApi(api = 23)
public final class DecryptableUriMediaInput {
private DecryptableUriMediaInput() {
}
public static @NonNull MediaInput createForUri(@NonNull Context context, @NonNull Uri uri) throws IOException {
if (BlobProvider.isAuthority(uri)) {
return new MediaInput.MediaDataSourceMediaInput(BlobProvider.getInstance().getMediaDataSource(context, uri));
}
if (PartAuthority.isLocalUri(uri)) {
return createForAttachmentUri(context, uri);
}
return new MediaInput.UriMediaInput(context, uri);
}
private static @NonNull MediaInput createForAttachmentUri(@NonNull Context context, @NonNull Uri uri) {
AttachmentId partId = new PartUriParser(uri).getPartId();
if (!partId.isValid()) {
throw new AssertionError();
}
MediaDataSource mediaDataSource = SignalDatabase.attachments().mediaDataSourceFor(partId, true);
if (mediaDataSource == null) {
throw new AssertionError();
}
return new MediaInput.MediaDataSourceMediaInput(mediaDataSource);
}
}

View File

@@ -0,0 +1,40 @@
package org.thoughtcrime.securesms.media
import android.content.Context
import android.net.Uri
import androidx.annotation.RequiresApi
import org.thoughtcrime.securesms.database.SignalDatabase.Companion.attachments
import org.thoughtcrime.securesms.mms.PartAuthority
import org.thoughtcrime.securesms.mms.PartUriParser
import org.thoughtcrime.securesms.providers.BlobProvider
import org.thoughtcrime.securesms.video.videoconverter.MediaInput
import org.thoughtcrime.securesms.video.videoconverter.mediadatasource.MediaDataSourceMediaInput
import java.io.IOException
/**
* A media input source that is decrypted on the fly.
*/
@RequiresApi(api = 23)
object DecryptableUriMediaInput {
@JvmStatic
@Throws(IOException::class)
fun createForUri(context: Context, uri: Uri): MediaInput {
if (BlobProvider.isAuthority(uri)) {
return MediaDataSourceMediaInput(BlobProvider.getInstance().getMediaDataSource(context, uri))
}
return if (PartAuthority.isLocalUri(uri)) {
createForAttachmentUri(uri)
} else {
UriMediaInput(context, uri)
}
}
private fun createForAttachmentUri(uri: Uri): MediaInput {
val partId = PartUriParser(uri).partId
if (!partId.isValid) {
throw AssertionError()
}
val mediaDataSource = attachments.mediaDataSourceFor(partId, true) ?: throw AssertionError()
return MediaDataSourceMediaInput(mediaDataSource)
}
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.media
import android.media.MediaExtractor
import org.thoughtcrime.securesms.video.videoconverter.MediaInput
import java.io.File
import java.io.IOException
/**
* A media input source that the system reads directly from the file.
*/
class FileMediaInput(private val file: File) : MediaInput {
@Throws(IOException::class)
override fun createExtractor(): MediaExtractor {
val extractor = MediaExtractor()
extractor.setDataSource(file.absolutePath)
return extractor
}
override fun close() {}
}

View File

@@ -1,83 +0,0 @@
package org.thoughtcrime.securesms.media;
import android.content.Context;
import android.media.MediaDataSource;
import android.media.MediaExtractor;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
public abstract class MediaInput implements Closeable {
@NonNull
public abstract MediaExtractor createExtractor() throws IOException;
public static class FileMediaInput extends MediaInput {
private final File file;
public FileMediaInput(@NonNull File file) {
this.file = file;
}
@Override
public @NonNull MediaExtractor createExtractor() throws IOException {
final MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(file.getAbsolutePath());
return extractor;
}
@Override
public void close() {
}
}
public static class UriMediaInput extends MediaInput {
private final Uri uri;
private final Context context;
public UriMediaInput(@NonNull Context context, @NonNull Uri uri) {
this.uri = uri;
this.context = context;
}
@Override
public @NonNull MediaExtractor createExtractor() throws IOException {
final MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(context, uri, null);
return extractor;
}
@Override
public void close() {
}
}
@RequiresApi(23)
public static class MediaDataSourceMediaInput extends MediaInput {
private final MediaDataSource mediaDataSource;
public MediaDataSourceMediaInput(@NonNull MediaDataSource mediaDataSource) {
this.mediaDataSource = mediaDataSource;
}
@Override
public @NonNull MediaExtractor createExtractor() throws IOException {
final MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(mediaDataSource);
return extractor;
}
@Override
public void close() throws IOException {
mediaDataSource.close();
}
}
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.media
import android.content.Context
import android.media.MediaExtractor
import android.net.Uri
import org.thoughtcrime.securesms.video.videoconverter.MediaInput
import java.io.IOException
/**
* A media input source defined by a [Uri] that the system can parse and access.
*/
class UriMediaInput(private val context: Context, private val uri: Uri) : MediaInput {
@Throws(IOException::class)
override fun createExtractor(): MediaExtractor {
val extractor = MediaExtractor()
extractor.setDataSource(context, uri, null)
return extractor
}
override fun close() {}
}