diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 1748539bef..82a9e41dbd 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -7,6 +7,9 @@ * Add source prefix to all `Format.id` fields generated from `MergingMediaSource`. This helps to identify which source produced a `Format` ([#883](https://github.com/androidx/media/issues/883)). + * Fix the regex used for validating custom Common Media Client Data (CMCD) + key names by modifying it to only check for hyphen + ([#1028](https://github.com/androidx/media/issues/1028)). * Transformer: * Track Selection: * Extractors: diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/upstream/CmcdData.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/upstream/CmcdData.java index d84c592522..1ebd6727f9 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/upstream/CmcdData.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/upstream/CmcdData.java @@ -89,8 +89,12 @@ public final class CmcdData { /** Represents the object type for muxed audio and video content in a media container. */ public static final String OBJECT_TYPE_MUXED_AUDIO_AND_VIDEO = "av"; - private static final Pattern CUSTOM_KEY_NAME_PATTERN = - Pattern.compile("[a-zA-Z0-9]+(-[a-zA-Z0-9]+)+"); + /** + * Custom key names MUST carry a hyphenated prefix to ensure that there will not be a namespace + * collision with future revisions to this specification. Clients SHOULD use a reverse-DNS + * syntax when defining their own prefix. + */ + private static final Pattern CUSTOM_KEY_NAME_PATTERN = Pattern.compile(".*-.*"); private final CmcdConfiguration cmcdConfiguration; private final ExoTrackSelection trackSelection; diff --git a/libraries/exoplayer_dash/src/test/java/androidx/media3/exoplayer/dash/DefaultDashChunkSourceTest.java b/libraries/exoplayer_dash/src/test/java/androidx/media3/exoplayer/dash/DefaultDashChunkSourceTest.java index 7de944c718..37d89a3e78 100644 --- a/libraries/exoplayer_dash/src/test/java/androidx/media3/exoplayer/dash/DefaultDashChunkSourceTest.java +++ b/libraries/exoplayer_dash/src/test/java/androidx/media3/exoplayer/dash/DefaultDashChunkSourceTest.java @@ -459,8 +459,8 @@ public class DefaultDashChunkSourceTest { @CmcdConfiguration.HeaderKey String, String>() .put(CmcdConfiguration.KEY_CMCD_OBJECT, "key-1=1") .put(CmcdConfiguration.KEY_CMCD_REQUEST, "key-2=\"stringValue\"") - .put(CmcdConfiguration.KEY_CMCD_SESSION, "key-3=3") - .put(CmcdConfiguration.KEY_CMCD_STATUS, "key-4=5.0") + .put(CmcdConfiguration.KEY_CMCD_SESSION, "com.example-key3=3") + .put(CmcdConfiguration.KEY_CMCD_STATUS, "com.example.test-key4=5.0") .build(); } }; @@ -487,9 +487,11 @@ public class DefaultDashChunkSourceTest { "CMCD-Request", "bl=0,dl=0,key-2=\"stringValue\",mtp=1000,nor=\"..%2Fvideo_4000_700000.m4s\",nrr=\"0-\",su", "CMCD-Session", - "cid=\"mediaId\",key-3=3,sf=d,sid=\"" + cmcdConfiguration.sessionId + "\",st=v", + "cid=\"mediaId\",com.example-key3=3,sf=d,sid=\"" + + cmcdConfiguration.sessionId + + "\",st=v", "CMCD-Status", - "key-4=5.0"); + "com.example.test-key4=5.0"); } @Test @@ -505,7 +507,7 @@ public class DefaultDashChunkSourceTest { getCustomData() { return new ImmutableListMultimap.Builder< @CmcdConfiguration.HeaderKey String, String>() - .put(CmcdConfiguration.KEY_CMCD_OBJECT, "key-1=1") + .put(CmcdConfiguration.KEY_CMCD_OBJECT, "com.example.test-key-1=1") .put(CmcdConfiguration.KEY_CMCD_REQUEST, "key-2=\"stringValue\"") .build(); } @@ -534,9 +536,9 @@ public class DefaultDashChunkSourceTest { output.chunk.dataSpec.uri.getQueryParameter( CmcdConfiguration.CMCD_QUERY_PARAMETER_KEY))) .isEqualTo( - "bl=0,br=700,cid=\"mediaId\",d=4000,dl=0,key-1=1,key-2=\"stringValue\"," - + "mtp=1000,nor=\"..%2Fvideo_4000_700000.m4s\",nrr=\"0-\",ot=v,sf=d," - + "sid=\"sessionId\",st=v,su,tb=1300"); + "bl=0,br=700,cid=\"mediaId\",com.example.test-key-1=1,d=4000,dl=0," + + "key-2=\"stringValue\",mtp=1000,nor=\"..%2Fvideo_4000_700000.m4s\",nrr=\"0-\"," + + "ot=v,sf=d,sid=\"sessionId\",st=v,su,tb=1300"); } @Test diff --git a/libraries/exoplayer_hls/src/test/java/androidx/media3/exoplayer/hls/HlsChunkSourceTest.java b/libraries/exoplayer_hls/src/test/java/androidx/media3/exoplayer/hls/HlsChunkSourceTest.java index a038217103..303e4c1bb6 100644 --- a/libraries/exoplayer_hls/src/test/java/androidx/media3/exoplayer/hls/HlsChunkSourceTest.java +++ b/libraries/exoplayer_hls/src/test/java/androidx/media3/exoplayer/hls/HlsChunkSourceTest.java @@ -367,8 +367,8 @@ public class HlsChunkSourceTest { @CmcdConfiguration.HeaderKey String, String>() .put(CmcdConfiguration.KEY_CMCD_OBJECT, "key-1=1") .put(CmcdConfiguration.KEY_CMCD_REQUEST, "key-2=\"stringValue\"") - .put(CmcdConfiguration.KEY_CMCD_SESSION, "key-3=3") - .put(CmcdConfiguration.KEY_CMCD_STATUS, "key-4=5.0") + .put(CmcdConfiguration.KEY_CMCD_SESSION, "com.example-key3=3") + .put(CmcdConfiguration.KEY_CMCD_STATUS, "com.example.test-key4=5.0") .build(); } }; @@ -396,9 +396,11 @@ public class HlsChunkSourceTest { "CMCD-Request", "bl=0,dl=0,key-2=\"stringValue\",nor=\"..%2F3.mp4\",nrr=\"0-\",su", "CMCD-Session", - "cid=\"mediaId\",key-3=3,sf=h,sid=\"" + cmcdConfiguration.sessionId + "\",st=v", + "cid=\"mediaId\",com.example-key3=3,sf=h,sid=\"" + + cmcdConfiguration.sessionId + + "\",st=v", "CMCD-Status", - "key-4=5.0"); + "com.example.test-key4=5.0"); } @Test @@ -414,7 +416,7 @@ public class HlsChunkSourceTest { getCustomData() { return new ImmutableListMultimap.Builder< @CmcdConfiguration.HeaderKey String, String>() - .put(CmcdConfiguration.KEY_CMCD_OBJECT, "key-1=1") + .put(CmcdConfiguration.KEY_CMCD_OBJECT, "com.example.test-key-1=1") .put(CmcdConfiguration.KEY_CMCD_REQUEST, "key-2=\"stringValue\"") .build(); } @@ -444,8 +446,9 @@ public class HlsChunkSourceTest { output.chunk.dataSpec.uri.getQueryParameter( CmcdConfiguration.CMCD_QUERY_PARAMETER_KEY))) .isEqualTo( - "bl=0,br=800,cid=\"mediaId\",d=4000,dl=0,key-1=1,key-2=\"stringValue\"," - + "nor=\"..%2F3.mp4\",nrr=\"0-\",ot=v,sf=h,sid=\"sessionId\",st=v,su,tb=800"); + "bl=0,br=800,cid=\"mediaId\",com.example.test-key-1=1,d=4000,dl=0," + + "key-2=\"stringValue\",nor=\"..%2F3.mp4\",nrr=\"0-\",ot=v,sf=h," + + "sid=\"sessionId\",st=v,su,tb=800"); } private HlsChunkSource createHlsChunkSource(@Nullable CmcdConfiguration cmcdConfiguration) { diff --git a/libraries/exoplayer_smoothstreaming/src/test/java/androidx/media3/exoplayer/smoothstreaming/DefaultSsChunkSourceTest.java b/libraries/exoplayer_smoothstreaming/src/test/java/androidx/media3/exoplayer/smoothstreaming/DefaultSsChunkSourceTest.java index d04906cf70..89a7307ba0 100644 --- a/libraries/exoplayer_smoothstreaming/src/test/java/androidx/media3/exoplayer/smoothstreaming/DefaultSsChunkSourceTest.java +++ b/libraries/exoplayer_smoothstreaming/src/test/java/androidx/media3/exoplayer/smoothstreaming/DefaultSsChunkSourceTest.java @@ -210,8 +210,8 @@ public class DefaultSsChunkSourceTest { @CmcdConfiguration.HeaderKey String, String>() .put(CmcdConfiguration.KEY_CMCD_OBJECT, "key-1=1") .put(CmcdConfiguration.KEY_CMCD_REQUEST, "key-2=\"stringValue\"") - .put(CmcdConfiguration.KEY_CMCD_SESSION, "key-3=3") - .put(CmcdConfiguration.KEY_CMCD_STATUS, "key-4=5.0") + .put(CmcdConfiguration.KEY_CMCD_SESSION, "com.example-key3=3") + .put(CmcdConfiguration.KEY_CMCD_STATUS, "com.example.test-key4=5.0") .build(); } }; @@ -238,9 +238,11 @@ public class DefaultSsChunkSourceTest { "CMCD-Request", "bl=0,dl=0,key-2=\"stringValue\",mtp=1000,nor=\"..%2FFragments(video%3D19680000)\",su", "CMCD-Session", - "cid=\"mediaId\",key-3=3,sf=s,sid=\"" + cmcdConfiguration.sessionId + "\",st=v", + "cid=\"mediaId\",com.example-key3=3,sf=s,sid=\"" + + cmcdConfiguration.sessionId + + "\",st=v", "CMCD-Status", - "key-4=5.0"); + "com.example.test-key4=5.0"); } @Test @@ -256,7 +258,7 @@ public class DefaultSsChunkSourceTest { getCustomData() { return new ImmutableListMultimap.Builder< @CmcdConfiguration.HeaderKey String, String>() - .put(CmcdConfiguration.KEY_CMCD_OBJECT, "key-1=1") + .put(CmcdConfiguration.KEY_CMCD_OBJECT, "com.example.test-key-1=1") .put(CmcdConfiguration.KEY_CMCD_REQUEST, "key-2=\"stringValue\"") .build(); } @@ -285,9 +287,9 @@ public class DefaultSsChunkSourceTest { output.chunk.dataSpec.uri.getQueryParameter( CmcdConfiguration.CMCD_QUERY_PARAMETER_KEY))) .isEqualTo( - "bl=0,br=308,cid=\"mediaId\",d=1968,dl=0,key-1=1,key-2=\"stringValue\"," - + "mtp=1000,nor=\"..%2FFragments(video%3D19680000)\",ot=v,sf=s,sid=\"sessionId\"," - + "st=v,su,tb=1536"); + "bl=0,br=308,cid=\"mediaId\",com.example.test-key-1=1,d=1968,dl=0," + + "key-2=\"stringValue\",mtp=1000,nor=\"..%2FFragments(video%3D19680000)\",ot=v," + + "sf=s,sid=\"sessionId\",st=v,su,tb=1536"); } private SsChunkSource createSsChunkSource(