feat(android): Support Common Media Client Data (CMCD) (#4034)

* feat(VideoNativeComponent.ts): add support for cmcd configuration in VideoSrc type to enable cmcd feature on android
feat(video.ts): introduce CmcdMode enum and CmcdConfiguration type to define cmcd configuration options

* feat(Video.tsx): add support for CMCD configuration in Video component to handle Content Management and Delivery (CMCD) headers for Android platform.

* feat(CMCDProps.kt): add CMCDProps class to handle CMCD related properties and parsing logic for React Native module

* feat(CMCDConfig.kt): add CMCDConfig class to handle CMCD configuration for ExoPlayer with support for custom data and configuration options.

* feat(ReactExoplayerViewManager.java): add support for CMCD configuration in ReactExoplayerViewManager to enable Content Management and Control Data (CMCD) for better video playback optimization.

* feat(ReactExoplayerView.java): add support for setting CmcdConfiguration.Factory to customize CMCD configuration for media playback

* feat(Source.kt): add support for CMCD properties linked to the source to enhance functionality and data handling

* docs(props.mdx): add documentation for configuring CMCD parameters in the component, including usage examples and default values

* refactor(ReactExoplayerViewManager.java): remove unused PROP_CMCD and prevCmcdConfig variables to clean up code and improve readability

* refactor(Video.tsx): simplify cmcd configuration logic for better readability and maintainability

* docs(props.mdx): improve props documentation for clarity and consistency
feat(props.mdx): add definitions for CmcdMode enum and CmcdData type to enhance understanding of CMCD data structure and usage

* refactor(CMCDProps.kt): refactor CMCDProps class to data class for improved readability and immutability
-  update CMCDProps class to use List instead of Array for properties

* refactor(Video.tsx): refactor createCmcdHeader function to improve code readability and reduce duplication

* fix(CMCDProps.kt): remove import statement for CmcdConfiguration

* feat(ReactExoplayerView.java): add support for CMCD configuration in ReactExoplayerView component
feat(ReactExoplayerViewManager.java): remove redundant CMCD configuration logic from ReactExoplayerViewManager to simplify code and improve maintainability

* fix(Video.tsx): merge _cmcd memo into src memo for optimization
This commit is contained in:
Subin Yang
2024-08-22 17:47:51 +09:00
committed by GitHub
parent 65faba312d
commit ca795f298a
8 changed files with 249 additions and 3 deletions

View File

@@ -16,7 +16,9 @@ import type {
ImageResizeMode,
} from 'react-native';
import NativeVideoComponent from './specs/VideoNativeComponent';
import NativeVideoComponent, {
NativeCmcdConfiguration,
} from './specs/VideoNativeComponent';
import type {
OnAudioFocusChangedData,
OnAudioTracksData,
@@ -44,12 +46,13 @@ import {
} from './utils';
import NativeVideoManager from './specs/NativeVideoManager';
import type {VideoSaveData} from './specs/NativeVideoManager';
import {ViewType} from './types';
import {CmcdMode, ViewType} from './types';
import type {
OnLoadData,
OnTextTracksData,
OnReceiveAdEventData,
ReactVideoProps,
CmcdData,
} from './types';
export interface VideoRef {
@@ -176,6 +179,30 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
multiDrm: selectedDrm.multiDrm,
};
let _cmcd: NativeCmcdConfiguration | undefined;
if (Platform.OS === 'android' && source?.cmcd) {
const cmcd = source.cmcd;
if (typeof cmcd === 'boolean') {
_cmcd = cmcd ? {mode: CmcdMode.MODE_QUERY_PARAMETER} : undefined;
} else if (typeof cmcd === 'object' && !Array.isArray(cmcd)) {
const createCmcdHeader = (property?: CmcdData) =>
property ? generateHeaderForNative(property) : undefined;
_cmcd = {
mode: cmcd.mode ?? CmcdMode.MODE_QUERY_PARAMETER,
request: createCmcdHeader(cmcd.request),
session: createCmcdHeader(cmcd.session),
object: createCmcdHeader(cmcd.object),
status: createCmcdHeader(cmcd.status),
};
} else {
throw new Error(
'Invalid CMCD configuration: Expected a boolean or an object.',
);
}
}
return {
uri,
isNetwork,
@@ -190,6 +217,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
cropEnd: resolvedSource.cropEnd,
metadata: resolvedSource.metadata,
drm: _drm,
cmcd: _cmcd,
textTracksAllowChunklessPreparation:
resolvedSource.textTracksAllowChunklessPreparation,
};

View File

@@ -40,6 +40,7 @@ export type VideoSrc = Readonly<{
cropEnd?: Float;
metadata?: VideoMetadata;
drm?: Drm;
cmcd?: NativeCmcdConfiguration; // android
textTracksAllowChunklessPreparation?: boolean; // android
}>;
@@ -61,6 +62,15 @@ type Drm = Readonly<{
multiDrm?: WithDefault<boolean, false>; // android
}>;
type CmcdMode = WithDefault<Int32, 1>;
export type NativeCmcdConfiguration = Readonly<{
mode?: CmcdMode; // default: MODE_QUERY_PARAMETER
request?: Headers;
session?: Headers;
object?: Headers;
status?: Headers;
}>;
type TextTracks = ReadonlyArray<
Readonly<{
title: string;

View File

@@ -33,6 +33,7 @@ export type ReactVideoSourceProperties = {
cropEnd?: number;
metadata?: VideoMetadata;
drm?: Drm;
cmcd?: Cmcd; // android
textTracksAllowChunklessPreparation?: boolean;
};
@@ -87,6 +88,27 @@ export type Drm = Readonly<{
/* eslint-enable @typescript-eslint/no-unused-vars */
}>;
export enum CmcdMode {
MODE_REQUEST_HEADER = 0,
MODE_QUERY_PARAMETER = 1,
}
/**
* 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.
*
* @see https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf CTA-5004 Specification (Page 6, Section 3.1)
*/
export type CmcdData = Record<`${string}-${string}`, string | number>;
export type CmcdConfiguration = Readonly<{
mode?: CmcdMode; // default: MODE_QUERY_PARAMETER
request?: CmcdData;
session?: CmcdData;
object?: CmcdData;
status?: CmcdData;
}>;
export type Cmcd = boolean | CmcdConfiguration;
export enum BufferingStrategyType {
DEFAULT = 'Default',
DISABLE_BUFFERING = 'DisableBuffering',