Commit d98e3312 by rohks Committed by Tianyi Feng

Add fields streaming format(sf), stream type(st) and version(v)

Added these CMCD-Session fields to Common Media Client Data (CMCD) logging.

#minor-release

PiperOrigin-RevId: 547435498
(cherry picked from commit d82a86fba56e23ab5037d281f6586e7aa8f2b237)
parent 6a3c3380
......@@ -66,7 +66,10 @@ public final class CmcdConfiguration {
KEY_BUFFER_LENGTH,
KEY_CONTENT_ID,
KEY_SESSION_ID,
KEY_MAXIMUM_REQUESTED_BITRATE
KEY_MAXIMUM_REQUESTED_BITRATE,
KEY_STREAMING_FORMAT,
KEY_STREAM_TYPE,
KEY_VERSION
})
@Documented
@Target(TYPE_USE)
......@@ -84,6 +87,9 @@ public final class CmcdConfiguration {
public static final String KEY_CONTENT_ID = "cid";
public static final String KEY_SESSION_ID = "sid";
public static final String KEY_MAXIMUM_REQUESTED_BITRATE = "rtp";
public static final String KEY_STREAMING_FORMAT = "sf";
public static final String KEY_STREAM_TYPE = "st";
public static final String KEY_VERSION = "v";
/**
* Factory for {@link CmcdConfiguration} instances.
......@@ -205,7 +211,7 @@ public final class CmcdConfiguration {
}
/**
* Whether logging bitrate is allowed based on the {@linkplain RequestConfig request
* Returns whether logging bitrate is allowed based on the {@linkplain RequestConfig request
* configuration}.
*/
public boolean isBitrateLoggingAllowed() {
......@@ -213,7 +219,7 @@ public final class CmcdConfiguration {
}
/**
* Whether logging buffer length is allowed based on the {@linkplain RequestConfig request
* Returns whether logging buffer length is allowed based on the {@linkplain RequestConfig request
* configuration}.
*/
public boolean isBufferLengthLoggingAllowed() {
......@@ -221,7 +227,7 @@ public final class CmcdConfiguration {
}
/**
* Whether logging content ID is allowed based on the {@linkplain RequestConfig request
* Returns whether logging content ID is allowed based on the {@linkplain RequestConfig request
* configuration}.
*/
public boolean isContentIdLoggingAllowed() {
......@@ -229,7 +235,7 @@ public final class CmcdConfiguration {
}
/**
* Whether logging session ID is allowed based on the {@linkplain RequestConfig request
* Returns whether logging session ID is allowed based on the {@linkplain RequestConfig request
* configuration}.
*/
public boolean isSessionIdLoggingAllowed() {
......@@ -237,10 +243,26 @@ public final class CmcdConfiguration {
}
/**
* Whether logging maximum requested throughput is allowed based on the {@linkplain RequestConfig
* request configuration}.
* Returns whether logging maximum requested throughput is allowed based on the {@linkplain
* RequestConfig request configuration}.
*/
public boolean isMaximumRequestThroughputLoggingAllowed() {
return requestConfig.isKeyAllowed(KEY_MAXIMUM_REQUESTED_BITRATE);
}
/**
* Returns whether logging streaming format is allowed based on the {@linkplain RequestConfig
* request configuration}.
*/
public boolean isStreamingFormatLoggingAllowed() {
return requestConfig.isKeyAllowed(KEY_STREAMING_FORMAT);
}
/**
* Returns whether logging stream type is allowed based on the {@linkplain RequestConfig request
* configuration}.
*/
public boolean isStreamTypeLoggingAllowed() {
return requestConfig.isKeyAllowed(KEY_STREAM_TYPE);
}
}
......@@ -16,14 +16,20 @@
package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.util.Assertions.checkArgument;
import static java.lang.annotation.ElementType.TYPE_USE;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.annotation.StringDef;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableMap;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Represents the data for CMCD (Common Media Client Data) in adaptive streaming formats DASH, HLS,
......@@ -41,6 +47,35 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
@Deprecated
public final class CmcdLog {
/** Indicates the streaming format used for media content. */
@Retention(RetentionPolicy.SOURCE)
@StringDef({STREAMING_FORMAT_DASH, STREAMING_FORMAT_HLS, STREAMING_FORMAT_SS})
@Documented
@Target(TYPE_USE)
public @interface StreamingFormat {}
/** Indicates the type of streaming for media content. */
@Retention(RetentionPolicy.SOURCE)
@StringDef({STREAM_TYPE_VOD, STREAM_TYPE_LIVE})
@Documented
@Target(TYPE_USE)
public @interface StreamType {}
/** Represents the Dynamic Adaptive Streaming over HTTP (DASH) format. */
public static final String STREAMING_FORMAT_DASH = "d";
/** Represents the HTTP Live Streaming (HLS) format. */
public static final String STREAMING_FORMAT_HLS = "h";
/** Represents the Smooth Streaming (SS) format. */
public static final String STREAMING_FORMAT_SS = "s";
/** Represents the Video on Demand (VOD) stream type. */
public static final String STREAM_TYPE_VOD = "v";
/** Represents the Live Streaming stream type. */
public static final String STREAM_TYPE_LIVE = "l";
/**
* Creates a new instance.
*
......@@ -48,11 +83,17 @@ public final class CmcdLog {
* @param trackSelection The {@linkplain ExoTrackSelection track selection}.
* @param bufferedDurationUs The duration of media currently buffered from the current playback
* position, in microseconds.
* @param streamingFormat The streaming format of the media content. Must be one of the allowed
* streaming formats specified by the {@link StreamingFormat} annotation.
* @param isLive {@code true} if the media content is being streamed live, {@code false}
* otherwise.
*/
public static CmcdLog createInstance(
CmcdConfiguration cmcdConfiguration,
ExoTrackSelection trackSelection,
long bufferedDurationUs) {
long bufferedDurationUs,
@StreamingFormat String streamingFormat,
boolean isLive) {
ImmutableMap<@CmcdConfiguration.HeaderKey String, String> customData =
cmcdConfiguration.requestConfig.getCustomData();
int bitrateKbps = trackSelection.getSelectedFormat().bitrate / 1000;
......@@ -80,6 +121,12 @@ public final class CmcdLog {
if (cmcdConfiguration.isSessionIdLoggingAllowed()) {
cmcdSession.setSessionId(cmcdConfiguration.sessionId);
}
if (cmcdConfiguration.isStreamingFormatLoggingAllowed()) {
cmcdSession.setStreamingFormat(streamingFormat);
}
if (cmcdConfiguration.isStreamTypeLoggingAllowed()) {
cmcdSession.setStreamType(isLive ? STREAM_TYPE_LIVE : STREAM_TYPE_VOD);
}
CmcdLog.CmcdStatus.Builder cmcdStatus =
new CmcdLog.CmcdStatus.Builder()
......@@ -292,6 +339,8 @@ public final class CmcdLog {
public static final class Builder {
@Nullable private String contentId;
@Nullable private String sessionId;
@Nullable private String streamingFormat;
@Nullable private String streamType;
@Nullable private String customData;
/**
......@@ -316,6 +365,20 @@ public final class CmcdLog {
return this;
}
/** Sets the {@link CmcdSession#streamingFormat}. The default value is {@code null}. */
@CanIgnoreReturnValue
public Builder setStreamingFormat(@Nullable @StreamingFormat String streamingFormat) {
this.streamingFormat = streamingFormat;
return this;
}
/** Sets the {@link CmcdSession#streamType}. The default value is {@code null}. */
@CanIgnoreReturnValue
public Builder setStreamType(@Nullable @StreamType String streamType) {
this.streamType = streamType;
return this;
}
/** Sets the {@link CmcdSession#customData}. The default value is {@code null}. */
@CanIgnoreReturnValue
public CmcdSession.Builder setCustomData(@Nullable String customData) {
......@@ -329,6 +392,13 @@ public final class CmcdLog {
}
/**
* The version of this specification used for interpreting the defined key names and values. If
* this key is omitted, the client and server MUST interpret the values as being defined by
* version 1. Client SHOULD omit this field if the version is 1.
*/
public static final int VERSION = 1;
/**
* A GUID identifying the current content, or {@code null} if unset.
*
* <p>This value is consistent across multiple different sessions and devices and is defined and
......@@ -343,6 +413,19 @@ public final class CmcdLog {
*/
@Nullable public final String sessionId;
/**
* The streaming format that defines the current request. d = MPEG DASH, h = HTTP Live Streaming
* (HLS), s = Smooth Streaming and o = other. If the streaming format being requested is
* unknown, then this key MUST NOT be used.
*/
@Nullable public final String streamingFormat;
/**
* Type of stream. v = all segments are available – e.g., VOD and l = segments become available
* over time – e.g., LIVE.
*/
@Nullable public final String streamType;
/**
* Custom data where the values of the keys are expected to be invariant over the life of the
* session, or {@code null} if unset.
*
......@@ -354,6 +437,8 @@ public final class CmcdLog {
private CmcdSession(Builder builder) {
this.contentId = builder.contentId;
this.sessionId = builder.sessionId;
this.streamingFormat = builder.streamingFormat;
this.streamType = builder.streamType;
this.customData = builder.customData;
}
......@@ -374,6 +459,18 @@ public final class CmcdLog {
headerValue.append(
Util.formatInvariant("%s=\"%s\",", CmcdConfiguration.KEY_SESSION_ID, sessionId));
}
if (!TextUtils.isEmpty(this.streamingFormat)) {
headerValue.append(
Util.formatInvariant(
"%s=%s,", CmcdConfiguration.KEY_STREAMING_FORMAT, streamingFormat));
}
if (!TextUtils.isEmpty(this.streamType)) {
headerValue.append(
Util.formatInvariant("%s=%s,", CmcdConfiguration.KEY_STREAM_TYPE, streamType));
}
if (VERSION != 1) {
headerValue.append(Util.formatInvariant("%s=%d,", CmcdConfiguration.KEY_VERSION, VERSION));
}
if (!TextUtils.isEmpty(customData)) {
headerValue.append(Util.formatInvariant("%s,", customData));
}
......
......@@ -60,7 +60,11 @@ public class CmcdLogTest {
.thenReturn(new Format.Builder().setPeakBitrate(840_000).build());
CmcdLog cmcdLog =
CmcdLog.createInstance(
cmcdConfiguration, trackSelection, /* bufferedDurationUs= */ 1_760_000);
cmcdConfiguration,
trackSelection,
/* bufferedDurationUs= */ 1_760_000,
CmcdLog.STREAMING_FORMAT_DASH,
true);
ImmutableMap<@CmcdConfiguration.HeaderKey String, String> requestHeaders =
cmcdLog.getHttpRequestHeaders();
......@@ -72,7 +76,7 @@ public class CmcdLogTest {
"CMCD-Request",
"bl=1800,key2=\"stringValue\"",
"CMCD-Session",
"cid=\"mediaId\",sid=\"sessionId\"",
"cid=\"mediaId\",sid=\"sessionId\",sf=d,st=l",
"CMCD-Status",
"rtp=1700");
}
......
......@@ -380,7 +380,12 @@ public class DefaultDashChunkSource implements DashChunkSource {
CmcdLog cmcdLog =
cmcdConfiguration == null
? null
: CmcdLog.createInstance(cmcdConfiguration, trackSelection, bufferedDurationUs);
: CmcdLog.createInstance(
cmcdConfiguration,
trackSelection,
bufferedDurationUs,
CmcdLog.STREAMING_FORMAT_DASH,
manifest.dynamic);
RepresentationHolder representationHolder =
updateSelectedBaseUrl(trackSelection.getSelectedIndex());
......
......@@ -318,7 +318,7 @@ public class DefaultDashChunkSourceTest {
"CMCD-Request",
"bl=0",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\"");
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=d,st=v");
}
@Test
......@@ -363,7 +363,7 @@ public class DefaultDashChunkSourceTest {
"CMCD-Request",
"bl=0",
"CMCD-Session",
"cid=\"mediaIdcontentIdSuffix\"",
"cid=\"mediaIdcontentIdSuffix\",sf=d,st=v",
"CMCD-Status",
"rtp=3500");
}
......@@ -409,7 +409,7 @@ public class DefaultDashChunkSourceTest {
"CMCD-Request",
"bl=0,key2=\"stringValue\"",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",key3=1",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=d,st=v,key3=1",
"CMCD-Status",
"key4=5.0");
}
......
......@@ -491,7 +491,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
CmcdLog cmcdLog =
cmcdConfiguration == null
? null
: CmcdLog.createInstance(cmcdConfiguration, trackSelection, bufferedDurationUs);
: CmcdLog.createInstance(
cmcdConfiguration,
trackSelection,
bufferedDurationUs,
CmcdLog.STREAMING_FORMAT_HLS,
!playlist.hasEndTag);
// Check if the media segment or its initialization segment are fully encrypted.
@Nullable
......
......@@ -214,7 +214,7 @@ public class HlsChunkSourceTest {
"CMCD-Request",
"bl=0",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\"");
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=h,st=v");
}
@Test
......@@ -260,7 +260,7 @@ public class HlsChunkSourceTest {
"CMCD-Request",
"bl=0",
"CMCD-Session",
"cid=\"mediaIdcontentIdSuffix\"",
"cid=\"mediaIdcontentIdSuffix\",sf=h,st=v",
"CMCD-Status",
"rtp=4000");
}
......@@ -307,7 +307,7 @@ public class HlsChunkSourceTest {
"CMCD-Request",
"bl=0,key2=\"stringValue\"",
"CMCD-Session",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",key3=1",
"cid=\"mediaId\",sid=\"" + cmcdConfiguration.sessionId + "\",sf=h,st=v,key3=1",
"CMCD-Status",
"key4=5.0");
}
......
......@@ -290,7 +290,12 @@ public class DefaultSsChunkSource implements SsChunkSource {
CmcdLog cmcdLog =
cmcdConfiguration == null
? null
: CmcdLog.createInstance(cmcdConfiguration, trackSelection, bufferedDurationUs);
: CmcdLog.createInstance(
cmcdConfiguration,
trackSelection,
bufferedDurationUs,
CmcdLog.STREAMING_FORMAT_SS,
manifest.isLive);
out.chunk =
newMediaChunk(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment