mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Implement basic Metrics Collector in Transformer
Added a new `EditingMediaMetrics` class that interacts with the platform's `MediaMetricsManager` through an `EditingSession` created when export starts. Currently, only the `finalState` of the export event is reported to the `EditingSession`. Future changes will collect additional metrics based on the export operation's output. PiperOrigin-RevId: 711721801
This commit is contained in:
parent
9b71f2a3ba
commit
cd5d5bde27
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 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.media3.transformer;
|
||||||
|
|
||||||
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.media.metrics.EditingEndedEvent;
|
||||||
|
import android.media.metrics.EditingSession;
|
||||||
|
import android.media.metrics.MediaMetricsManager;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A metrics collector that collects editing events and forwards them to an {@link EditingSession}
|
||||||
|
* created by {@link MediaMetricsManager}.
|
||||||
|
*/
|
||||||
|
@RequiresApi(35)
|
||||||
|
/* package */ final class EditingMetricsCollector {
|
||||||
|
|
||||||
|
private @MonotonicNonNull EditingSession editingSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance.
|
||||||
|
*
|
||||||
|
* <p>A new instance must be created before starting a new export.
|
||||||
|
*
|
||||||
|
* @param context The {@link Context}.
|
||||||
|
*/
|
||||||
|
public EditingMetricsCollector(Context context) {
|
||||||
|
@Nullable
|
||||||
|
MediaMetricsManager mediaMetricsManager =
|
||||||
|
(MediaMetricsManager) context.getSystemService(Context.MEDIA_METRICS_SERVICE);
|
||||||
|
if (mediaMetricsManager != null) {
|
||||||
|
editingSession = checkNotNull(mediaMetricsManager.createEditingSession());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called when export completes with success. */
|
||||||
|
public void onExportSuccess() {
|
||||||
|
if (editingSession == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
editingSession.reportEditingEndedEvent(
|
||||||
|
new EditingEndedEvent.Builder(EditingEndedEvent.FINAL_STATE_SUCCEEDED).build());
|
||||||
|
editingSession.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called when export completes with an error. */
|
||||||
|
public void onExportError() {
|
||||||
|
if (editingSession == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
editingSession.reportEditingEndedEvent(
|
||||||
|
new EditingEndedEvent.Builder(EditingEndedEvent.FINAL_STATE_ERROR).build());
|
||||||
|
editingSession.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called when export is cancelled. */
|
||||||
|
public void onExportCancelled() {
|
||||||
|
if (editingSession == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
editingSession.reportEditingEndedEvent(
|
||||||
|
new EditingEndedEvent.Builder(EditingEndedEvent.FINAL_STATE_CANCELED).build());
|
||||||
|
editingSession.close();
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@ package androidx.media3.transformer;
|
|||||||
import static androidx.media3.common.util.Assertions.checkArgument;
|
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
import static androidx.media3.common.util.Assertions.checkState;
|
import static androidx.media3.common.util.Assertions.checkState;
|
||||||
|
import static androidx.media3.common.util.Util.SDK_INT;
|
||||||
import static androidx.media3.common.util.Util.isRunningOnEmulator;
|
import static androidx.media3.common.util.Util.isRunningOnEmulator;
|
||||||
import static androidx.media3.extractor.AacUtil.AAC_LC_AUDIO_SAMPLE_COUNT;
|
import static androidx.media3.extractor.AacUtil.AAC_LC_AUDIO_SAMPLE_COUNT;
|
||||||
import static androidx.media3.transformer.ExportException.ERROR_CODE_MUXING_APPEND;
|
import static androidx.media3.transformer.ExportException.ERROR_CODE_MUXING_APPEND;
|
||||||
@ -771,6 +772,7 @@ public final class Transformer {
|
|||||||
private final HandlerWrapper applicationHandler;
|
private final HandlerWrapper applicationHandler;
|
||||||
private final ComponentListener componentListener;
|
private final ComponentListener componentListener;
|
||||||
private final ExportResult.Builder exportResultBuilder;
|
private final ExportResult.Builder exportResultBuilder;
|
||||||
|
private @MonotonicNonNull EditingMetricsCollector editingMetricsCollector;
|
||||||
|
|
||||||
@Nullable private TransformerInternal transformerInternal;
|
@Nullable private TransformerInternal transformerInternal;
|
||||||
@Nullable private MuxerWrapper remuxingMuxerWrapper;
|
@Nullable private MuxerWrapper remuxingMuxerWrapper;
|
||||||
@ -1168,6 +1170,9 @@ public final class Transformer {
|
|||||||
} finally {
|
} finally {
|
||||||
transformerInternal = null;
|
transformerInternal = null;
|
||||||
}
|
}
|
||||||
|
if (canCollectEditingMetrics()) {
|
||||||
|
checkNotNull(editingMetricsCollector).onExportCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
if (getResumeMetadataFuture != null && !getResumeMetadataFuture.isDone()) {
|
if (getResumeMetadataFuture != null && !getResumeMetadataFuture.isDone()) {
|
||||||
getResumeMetadataFuture.cancel(/* mayInterruptIfRunning= */ false);
|
getResumeMetadataFuture.cancel(/* mayInterruptIfRunning= */ false);
|
||||||
@ -1542,6 +1547,10 @@ public final class Transformer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean canCollectEditingMetrics() {
|
||||||
|
return SDK_INT >= 35 && usePlatformDiagnostics;
|
||||||
|
}
|
||||||
|
|
||||||
private void startInternal(
|
private void startInternal(
|
||||||
Composition composition,
|
Composition composition,
|
||||||
MuxerWrapper muxerWrapper,
|
MuxerWrapper muxerWrapper,
|
||||||
@ -1563,6 +1572,9 @@ public final class Transformer {
|
|||||||
context, new DefaultDecoderFactory.Builder(context).build(), clock);
|
context, new DefaultDecoderFactory.Builder(context).build(), clock);
|
||||||
}
|
}
|
||||||
DebugTraceUtil.reset();
|
DebugTraceUtil.reset();
|
||||||
|
if (canCollectEditingMetrics()) {
|
||||||
|
editingMetricsCollector = new EditingMetricsCollector(context);
|
||||||
|
}
|
||||||
transformerInternal =
|
transformerInternal =
|
||||||
new TransformerInternal(
|
new TransformerInternal(
|
||||||
context,
|
context,
|
||||||
@ -1590,6 +1602,9 @@ public final class Transformer {
|
|||||||
/* eventFlag= */ C.INDEX_UNSET,
|
/* eventFlag= */ C.INDEX_UNSET,
|
||||||
listener -> listener.onCompleted(checkNotNull(composition), exportResultBuilder.build()));
|
listener -> listener.onCompleted(checkNotNull(composition), exportResultBuilder.build()));
|
||||||
listeners.flushEvents();
|
listeners.flushEvents();
|
||||||
|
if (canCollectEditingMetrics()) {
|
||||||
|
checkNotNull(editingMetricsCollector).onExportSuccess();
|
||||||
|
}
|
||||||
transformerState = TRANSFORMER_STATE_PROCESS_FULL_INPUT;
|
transformerState = TRANSFORMER_STATE_PROCESS_FULL_INPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1600,6 +1615,9 @@ public final class Transformer {
|
|||||||
listener ->
|
listener ->
|
||||||
listener.onError(checkNotNull(composition), exportResultBuilder.build(), exception));
|
listener.onError(checkNotNull(composition), exportResultBuilder.build(), exception));
|
||||||
listeners.flushEvents();
|
listeners.flushEvents();
|
||||||
|
if (canCollectEditingMetrics()) {
|
||||||
|
checkNotNull(editingMetricsCollector).onExportError();
|
||||||
|
}
|
||||||
transformerState = TRANSFORMER_STATE_PROCESS_FULL_INPUT;
|
transformerState = TRANSFORMER_STATE_PROCESS_FULL_INPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user