Skip to content

Commit

Permalink
Introducing MockMediaTransformer (#13)
Browse files Browse the repository at this point in the history
Doesn't do any transcoding. Instead, synchronously "plays back" events on a listener. This should be very helpful with UI testing.
  • Loading branch information
izzytwosheds authored Jan 31, 2020
1 parent 34d66b8 commit cdb75af
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 3 deletions.
25 changes: 22 additions & 3 deletions litr/src/main/java/com/linkedin/android/litr/MediaTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,30 @@ public class MediaTransformer {
private Map<String, Future<?>> futureMap;

/**
* Instantiate MediaTransformer
* Instantiate MediaTransformer. Listener callbacks will be done on main UI thread.
* All transformations will be done on a single thread.
* @param context context with access to source and target URIs and other resources
*/
public MediaTransformer(@NonNull Context context) {
this(context, Looper.getMainLooper(), Executors.newSingleThreadExecutor());
}

/**
* Instantiate MediaTransformer
* @param context context with access to source and target URIs and other resources
* @param looper {@link Looper} of a thread to marshal listener callbacks to, null for current thread.
* @param executorService {@link ExecutorService} to use for transformation jobs
*/
public MediaTransformer(@NonNull Context context, @Nullable Looper looper, @Nullable ExecutorService executorService) {
this.context = context.getApplicationContext();

futureMap = new HashMap<>(DEFAULT_FUTURE_MAP_SIZE);
handler = new ProgressHandler(Looper.getMainLooper(), futureMap);
executorService = Executors.newSingleThreadExecutor();
this.executorService = executorService;
if (looper != null) {
handler = new ProgressHandler(looper, futureMap);
} else {
handler = new ProgressHandler(futureMap);
}
}

/**
Expand Down Expand Up @@ -341,6 +356,10 @@ static class ProgressHandler extends Handler {
private TransformationListener listener;
private List<TrackTransformationInfo> trackTransformationInfos;

private ProgressHandler(@NonNull Map<String, Future<?>> futureMap) {
this.futureMap = futureMap;
}

private ProgressHandler(Looper mainLooper, @NonNull Map<String, Future<?>> futureMap) {
super(mainLooper);
this.futureMap = futureMap;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.linkedin.android.litr.test;

import android.content.Context;
import android.media.MediaFormat;
import android.net.Uri;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.linkedin.android.litr.MediaTransformer;
import com.linkedin.android.litr.TrackTransform;
import com.linkedin.android.litr.TransformationListener;
import com.linkedin.android.litr.codec.Decoder;
import com.linkedin.android.litr.codec.Encoder;
import com.linkedin.android.litr.filter.GlFilter;
import com.linkedin.android.litr.io.MediaSource;
import com.linkedin.android.litr.io.MediaTarget;
import com.linkedin.android.litr.render.Renderer;

import java.util.List;

/**
* Mock transformer, meant to be used only in tests. Doesn't do any actual transformations.
*/
public class MockMediaTransformer extends MediaTransformer {

private List<TransformationEvent> transformationEvents;

public MockMediaTransformer(@NonNull Context context) {
super(context, null, null);
}

public void setEvents(@NonNull List<TransformationEvent> transformationEvents) {
this.transformationEvents = transformationEvents;
}

@Override
public void transform(@NonNull String requestId,
@NonNull Uri inputUri,
@NonNull String outputFilePath,
@Nullable MediaFormat targetVideoFormat,
@Nullable MediaFormat targetAudioFormat,
@NonNull TransformationListener listener,
@IntRange(from = GRANULARITY_NONE) int granularity,
@Nullable List<GlFilter> filters) {
playEvents(listener);
}

@Override
public void transform(@NonNull String requestId,
@NonNull MediaSource mediaSource,
@NonNull Decoder decoder,
@NonNull Renderer videoRenderer,
@NonNull Encoder encoder,
@NonNull MediaTarget mediaTarget,
@Nullable MediaFormat targetVideoFormat,
@Nullable MediaFormat targetAudioFormat,
@NonNull TransformationListener listener,
@IntRange(from = GRANULARITY_NONE) int granularity) {
playEvents(listener);
}

@Override
public void transform(@NonNull String requestId,
List<TrackTransform> trackTransforms,
@NonNull TransformationListener listener,
@IntRange(from = GRANULARITY_NONE) int granularity) {
playEvents(listener);
}

private void playEvents(@NonNull TransformationListener transformationListener) {
if (transformationEvents == null) {
// nothing to do
return;
}

for (TransformationEvent event : transformationEvents) {
switch (event.type) {
case TransformationEvent.TYPE_START:
transformationListener.onStarted(event.id);
break;
case TransformationEvent.TYPE_PROGRESS:
transformationListener.onProgress(event.id, event.progress);
break;
case TransformationEvent.TYPE_COMPLETED:
transformationListener.onCompleted(event.id, null);
break;
case TransformationEvent.TYPE_ERROR:
transformationListener.onError(event.id, event.cause, null);
break;
case TransformationEvent.TYPE_CANCELLED:
transformationListener.onCancelled(event.id, null);
break;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.linkedin.android.litr.test;

import androidx.annotation.FloatRange;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

public class TransformationEvent {

public static final int TYPE_START = 0;
public static final int TYPE_PROGRESS = 1;
public static final int TYPE_COMPLETED = 2;
public static final int TYPE_ERROR = 3;
public static final int TYPE_CANCELLED = 4;

@Retention(RetentionPolicy.SOURCE)
@IntDef({ TYPE_START, TYPE_PROGRESS, TYPE_COMPLETED, TYPE_ERROR, TYPE_CANCELLED})
@interface EventType {}

@NonNull public final String id;
@EventType public final int type;
public final float progress;
@Nullable public final Throwable cause;

public TransformationEvent(@NonNull String id,
@EventType int type,
@FloatRange(from = 0, to = 1) float progress,
@Nullable Throwable cause) {
this.id = id;
this.type = type;
this.progress = progress;
this.cause = cause;
}
}

0 comments on commit cdb75af

Please sign in to comment.