parent
9a3fcda3b8
commit
d86adc52f3
46
android/src/main/java/com/brentvatne/common/api/AdsProps.kt
Normal file
46
android/src/main/java/com/brentvatne/common/api/AdsProps.kt
Normal file
@ -0,0 +1,46 @@
|
||||
package com.brentvatne.common.api
|
||||
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import com.brentvatne.common.toolbox.DebugLog
|
||||
import com.brentvatne.common.toolbox.ReactBridgeUtils
|
||||
import com.facebook.react.bridge.ReadableMap
|
||||
|
||||
class AdsProps {
|
||||
var adTagUrl: Uri? = null
|
||||
var adLanguage: String? = null
|
||||
|
||||
/** return true if this and src are equals */
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other == null || other !is AdsProps) return false
|
||||
return (
|
||||
adTagUrl == other.adTagUrl &&
|
||||
adLanguage == other.adLanguage
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PROP_AD_TAG_URL = "adTagUrl"
|
||||
private const val PROP_AD_LANGUAGE = "adLanguage"
|
||||
|
||||
@JvmStatic
|
||||
fun parse(src: ReadableMap?): AdsProps {
|
||||
val adsProps = AdsProps()
|
||||
DebugLog.w("olivier", "uri: parse AdsProps")
|
||||
|
||||
if (src != null) {
|
||||
val uriString = ReactBridgeUtils.safeGetString(src, PROP_AD_TAG_URL)
|
||||
if (TextUtils.isEmpty(uriString)) {
|
||||
adsProps.adTagUrl = null
|
||||
} else {
|
||||
adsProps.adTagUrl = Uri.parse(uriString)
|
||||
}
|
||||
val languageString = ReactBridgeUtils.safeGetString(src, PROP_AD_LANGUAGE)
|
||||
if (!TextUtils.isEmpty(languageString)) {
|
||||
adsProps.adLanguage = languageString
|
||||
}
|
||||
}
|
||||
return adsProps
|
||||
}
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetBool
|
||||
import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetInt
|
||||
import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetMap
|
||||
import com.brentvatne.common.toolbox.ReactBridgeUtils.safeGetString
|
||||
import com.brentvatne.react.BuildConfig
|
||||
import com.facebook.react.bridge.ReadableMap
|
||||
import java.util.Locale
|
||||
import java.util.Objects
|
||||
@ -65,6 +66,11 @@ class Source {
|
||||
*/
|
||||
var cmcdProps: CMCDProps? = null
|
||||
|
||||
/**
|
||||
* Ads playback properties
|
||||
*/
|
||||
var adsProps: AdsProps? = null
|
||||
|
||||
/**
|
||||
* The list of sideLoaded text tracks
|
||||
*/
|
||||
@ -84,7 +90,8 @@ class Source {
|
||||
drmProps == other.drmProps &&
|
||||
contentStartTime == other.contentStartTime &&
|
||||
cmcdProps == other.cmcdProps &&
|
||||
sideLoadedTextTracks == other.sideLoadedTextTracks
|
||||
sideLoadedTextTracks == other.sideLoadedTextTracks &&
|
||||
adsProps == other.adsProps
|
||||
)
|
||||
}
|
||||
|
||||
@ -149,6 +156,7 @@ class Source {
|
||||
private const val PROP_SRC_HEADERS = "requestHeaders"
|
||||
private const val PROP_SRC_DRM = "drm"
|
||||
private const val PROP_SRC_CMCD = "cmcd"
|
||||
private const val PROP_SRC_ADS = "ad"
|
||||
private const val PROP_SRC_TEXT_TRACKS_ALLOW_CHUNKLESS_PREPARATION = "textTracksAllowChunklessPreparation"
|
||||
private const val PROP_SRC_TEXT_TRACKS = "textTracks"
|
||||
|
||||
@ -210,6 +218,9 @@ class Source {
|
||||
source.extension = safeGetString(src, PROP_SRC_TYPE, null)
|
||||
source.drmProps = parse(safeGetMap(src, PROP_SRC_DRM))
|
||||
source.cmcdProps = CMCDProps.parse(safeGetMap(src, PROP_SRC_CMCD))
|
||||
if (BuildConfig.USE_EXOPLAYER_IMA) {
|
||||
source.adsProps = AdsProps.parse(safeGetMap(src, PROP_SRC_ADS))
|
||||
}
|
||||
source.textTracksAllowChunklessPreparation = safeGetBool(src, PROP_SRC_TEXT_TRACKS_ALLOW_CHUNKLESS_PREPARATION, true)
|
||||
source.sideLoadedTextTracks = SideLoadedTextTrackList.parse(safeGetArray(src, PROP_SRC_TEXT_TRACKS))
|
||||
|
||||
|
@ -102,6 +102,7 @@ import androidx.media3.extractor.metadata.id3.TextInformationFrame;
|
||||
import androidx.media3.session.MediaSessionService;
|
||||
import androidx.media3.ui.LegacyPlayerControlView;
|
||||
|
||||
import com.brentvatne.common.api.AdsProps;
|
||||
import com.brentvatne.common.api.BufferConfig;
|
||||
import com.brentvatne.common.api.BufferingStrategy;
|
||||
import com.brentvatne.common.api.ControlsConfig;
|
||||
@ -240,8 +241,6 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
private boolean playInBackground = false;
|
||||
private boolean mReportBandwidth = false;
|
||||
private boolean controls;
|
||||
private Uri adTagUrl;
|
||||
private String adLanguage;
|
||||
|
||||
private boolean showNotificationControls = false;
|
||||
// \ End props
|
||||
@ -827,16 +826,23 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
mediaSourceFactory.setDataSourceFactory(RNVSimpleCache.INSTANCE.getCacheFactory(buildHttpDataSourceFactory(true)));
|
||||
}
|
||||
|
||||
ImaSdkSettings imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings();
|
||||
imaSdkSettings.setLanguage(adLanguage);
|
||||
if (BuildConfig.USE_EXOPLAYER_IMA) {
|
||||
AdsProps adProps = source.getAdsProps();
|
||||
|
||||
// Create an AdsLoader.
|
||||
ImaAdsLoader.Builder imaLoaderBuilder = new ImaAdsLoader
|
||||
.Builder(themedReactContext)
|
||||
.setAdEventListener(this)
|
||||
.setAdErrorListener(this);
|
||||
|
||||
if (adProps != null && adProps.getAdLanguage() != null) {
|
||||
ImaSdkSettings imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings();
|
||||
imaSdkSettings.setLanguage(adProps.getAdLanguage());
|
||||
imaLoaderBuilder.setImaSdkSettings(imaSdkSettings);
|
||||
}
|
||||
adsLoader = imaLoaderBuilder.build();
|
||||
}
|
||||
|
||||
// Create an AdsLoader.
|
||||
adsLoader = new ImaAdsLoader
|
||||
.Builder(themedReactContext)
|
||||
.setImaSdkSettings(imaSdkSettings)
|
||||
.setAdEventListener(this)
|
||||
.setAdErrorListener(this)
|
||||
.build();
|
||||
mediaSourceFactory.setLocalAdInsertionComponents(unusedAdTagUri -> adsLoader, exoPlayerView);
|
||||
|
||||
player = new ExoPlayer.Builder(getContext(), renderersFactory)
|
||||
@ -904,7 +910,11 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
ArrayList<MediaSource> mediaSourceList = buildTextSources();
|
||||
MediaSource videoSource = buildMediaSource(runningSource.getUri(), runningSource.getExtension(), drmSessionManager, runningSource.getCropStartMs(), runningSource.getCropEndMs());
|
||||
MediaSource mediaSourceWithAds = null;
|
||||
if (adTagUrl != null && BuildConfig.USE_EXOPLAYER_IMA) {
|
||||
Uri adTagUrl = null;
|
||||
if (source.getAdsProps() != null) {
|
||||
adTagUrl = source.getAdsProps().getAdTagUrl();
|
||||
}
|
||||
if (adTagUrl != null && adsLoader != null) {
|
||||
DefaultMediaSourceFactory mediaSourceFactory = new DefaultMediaSourceFactory(mediaDataSourceFactory)
|
||||
.setLocalAdInsertionComponents(unusedAdTagUri -> adsLoader, exoPlayerView);
|
||||
DataSpec adTagDataSpec = new DataSpec(adTagUrl);
|
||||
@ -1105,11 +1115,13 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
if (customMetadata != null) {
|
||||
mediaItemBuilder.setMediaMetadata(customMetadata);
|
||||
}
|
||||
|
||||
if (adTagUrl != null) {
|
||||
mediaItemBuilder.setAdsConfiguration(
|
||||
new MediaItem.AdsConfiguration.Builder(adTagUrl).build()
|
||||
);
|
||||
if (source.getAdsProps() != null) {
|
||||
Uri adTagUrl = source.getAdsProps().getAdTagUrl();
|
||||
if (adTagUrl != null) {
|
||||
mediaItemBuilder.setAdsConfiguration(
|
||||
new MediaItem.AdsConfiguration.Builder(adTagUrl).build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MediaItem.LiveConfiguration.Builder liveConfiguration = ConfigurationUtils.getLiveConfiguration(bufferConfig);
|
||||
@ -1261,8 +1273,8 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
|
||||
if (adsLoader != null) {
|
||||
adsLoader.release();
|
||||
adsLoader = null;
|
||||
}
|
||||
adsLoader = null;
|
||||
progressHandler.removeMessages(SHOW_PROGRESS);
|
||||
audioBecomingNoisyReceiver.removeListener();
|
||||
bandwidthMeter.removeEventListener(this);
|
||||
@ -1926,15 +1938,6 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
mReportBandwidth = reportBandwidth;
|
||||
}
|
||||
|
||||
public void setAdTagUrl(final Uri uri) {
|
||||
DebugLog.w(TAG, "setAdTagUrl" + uri);
|
||||
adTagUrl = uri;
|
||||
}
|
||||
|
||||
public void setAdLanguage(final String language) {
|
||||
adLanguage = language;
|
||||
}
|
||||
|
||||
private void reloadSource() {
|
||||
playerNeedsSource = true;
|
||||
initializePlayer();
|
||||
|
@ -1,8 +1,6 @@
|
||||
package com.brentvatne.exoplayer
|
||||
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import com.brentvatne.common.api.BufferConfig
|
||||
import com.brentvatne.common.api.BufferingStrategy
|
||||
@ -26,8 +24,6 @@ class ReactExoplayerViewManager(private val config: ReactExoplayerConfig) : View
|
||||
private const val TAG = "ExoViewManager"
|
||||
private const val REACT_CLASS = "RCTVideo"
|
||||
private const val PROP_SRC = "src"
|
||||
private const val PROP_AD_TAG_URL = "adTagUrl"
|
||||
private const val PROP_AD_LANGUAGE = "adLanguage"
|
||||
private const val PROP_RESIZE_MODE = "resizeMode"
|
||||
private const val PROP_REPEAT = "repeat"
|
||||
private const val PROP_SELECTED_AUDIO_TRACK = "selectedAudioTrack"
|
||||
@ -92,26 +88,6 @@ class ReactExoplayerViewManager(private val config: ReactExoplayerConfig) : View
|
||||
videoView.setSrc(Source.parse(src, context))
|
||||
}
|
||||
|
||||
@ReactProp(name = PROP_AD_TAG_URL)
|
||||
fun setAdTagUrl(videoView: ReactExoplayerView, uriString: String?) {
|
||||
if (TextUtils.isEmpty(uriString)) {
|
||||
videoView.setAdTagUrl(null)
|
||||
return
|
||||
}
|
||||
val adTagUrl = Uri.parse(uriString)
|
||||
videoView.setAdTagUrl(adTagUrl)
|
||||
}
|
||||
|
||||
@ReactProp(name = PROP_AD_LANGUAGE)
|
||||
fun setAdLanguage(videoView: ReactExoplayerView, languageString: String?) {
|
||||
if (TextUtils.isEmpty(languageString)) {
|
||||
videoView.setAdLanguage(null) // Maybe "en" default?
|
||||
return
|
||||
}
|
||||
|
||||
videoView.setAdLanguage(languageString)
|
||||
}
|
||||
|
||||
@ReactProp(name = PROP_RESIZE_MODE)
|
||||
fun setResizeMode(videoView: ReactExoplayerView, resizeMode: String) {
|
||||
when (resizeMode) {
|
||||
|
@ -8,6 +8,9 @@ This page shows the list of available properties to configure player
|
||||
|
||||
### `adTagUrl`
|
||||
|
||||
> [!WARNING]
|
||||
> Deprecated, use source.ad.adTagUrl instead
|
||||
|
||||
<PlatformsList types={['Android', 'iOS']} />
|
||||
|
||||
Sets the VAST uri to play AVOD ads.
|
||||
@ -858,6 +861,26 @@ source={{
|
||||
}}
|
||||
```
|
||||
|
||||
### `ad`
|
||||
|
||||
<PlatformsList types={['Android', 'iOS']} />
|
||||
|
||||
Sets the ad configuration.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
ad: {
|
||||
adTagUrl="https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpostoptimizedpodbumper&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator="
|
||||
adLanguage="fr"
|
||||
}
|
||||
```
|
||||
|
||||
See: [./ads.md] for more informations
|
||||
|
||||
Note: You need enable IMA SDK in gradle or pod file - [enable client side ads insertion](/installation)
|
||||
|
||||
|
||||
#### `contentStartTime`
|
||||
|
||||
<PlatformsList types={['Android']} />
|
||||
|
@ -265,8 +265,7 @@ const VideoPlayer: FC<Props> = ({}) => {
|
||||
<Video
|
||||
showNotificationControls={showNotificationControls}
|
||||
ref={videoRef}
|
||||
// source={currentSrc as ReactVideoSource}
|
||||
adTagUrl={additional?.adTagUrl}
|
||||
// source={currentSrc as ReactVideoSource}
|
||||
drm={additional?.drm}
|
||||
style={viewStyle}
|
||||
rate={rate}
|
||||
|
@ -107,6 +107,14 @@ export const srcAllPlatformList = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description: '(mp4) big buck bunny With Ads',
|
||||
ad: {
|
||||
adTagUrl:
|
||||
'https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpostoptimizedpodbumper&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator=',
|
||||
},
|
||||
uri: 'https://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4',
|
||||
},
|
||||
];
|
||||
|
||||
export const srcIosList: SampleVideoSource[] = [];
|
||||
@ -133,12 +141,6 @@ export const srcAndroidList: SampleVideoSource[] = [
|
||||
uri: 'http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=51AF5F39AB0CEC3E5497CD9C900EBFEAECCCB5C7.8506521BFC350652163895D4C26DEE124209AA9E&key=ik0',
|
||||
type: 'mpd',
|
||||
},
|
||||
{
|
||||
description: '(mp4) big buck bunny With Ads',
|
||||
adTagUrl:
|
||||
'https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpostoptimizedpodbumper&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator=',
|
||||
uri: 'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4',
|
||||
},
|
||||
{
|
||||
description: 'WV: Secure SD & HD (cbcs,MP4,H264)',
|
||||
uri: 'https://storage.googleapis.com/wvmedia/cbcs/h264/tears/tears_aes_cbcs.mpd',
|
||||
|
18
ios/Video/DataStructures/AdParams.swift
Normal file
18
ios/Video/DataStructures/AdParams.swift
Normal file
@ -0,0 +1,18 @@
|
||||
struct AdParams {
|
||||
let adTagUrl: String?
|
||||
let adLanguage: String?
|
||||
|
||||
let json: NSDictionary?
|
||||
|
||||
init(_ json: NSDictionary!) {
|
||||
guard json != nil else {
|
||||
self.json = nil
|
||||
adTagUrl = nil
|
||||
adLanguage = nil
|
||||
return
|
||||
}
|
||||
self.json = json
|
||||
adTagUrl = json["adTagUrl"] as? String
|
||||
adLanguage = json["adLanguage"] as? String
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ struct VideoSource {
|
||||
/* DRM */
|
||||
let drm: DRMParams
|
||||
var textTracks: [TextTrack] = []
|
||||
let adParams: AdParams
|
||||
|
||||
let json: NSDictionary?
|
||||
|
||||
@ -29,6 +30,7 @@ struct VideoSource {
|
||||
self.cropEnd = nil
|
||||
self.customMetadata = nil
|
||||
self.drm = DRMParams(nil)
|
||||
adParams = AdParams(nil)
|
||||
return
|
||||
}
|
||||
self.json = json
|
||||
@ -56,5 +58,6 @@ struct VideoSource {
|
||||
self.textTracks = (json["textTracks"] as? NSArray)?.map { trackDict in
|
||||
return TextTrack(trackDict as? NSDictionary)
|
||||
} ?? []
|
||||
adParams = AdParams(json["ad"] as? NSDictionary)
|
||||
}
|
||||
}
|
||||
|
@ -86,8 +86,6 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
||||
}
|
||||
|
||||
/* IMA Ads */
|
||||
private var _adTagUrl: String?
|
||||
private var _adLanguage: String?
|
||||
#if USE_GOOGLE_IMA
|
||||
private var _imaAdsManager: RCTIMAAdsManager!
|
||||
/* Playhead used by the SDK to track content video progress and insert mid-rolls. */
|
||||
@ -374,7 +372,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
||||
|
||||
if currentTimeSecs >= 0 {
|
||||
#if USE_GOOGLE_IMA
|
||||
if !_didRequestAds && currentTimeSecs >= 0.0001 && _adTagUrl != nil {
|
||||
if !_didRequestAds && currentTimeSecs >= 0.0001 && _source?.adParams.adTagUrl != nil {
|
||||
_imaAdsManager.requestAds()
|
||||
_didRequestAds = true
|
||||
}
|
||||
@ -527,7 +525,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
||||
}
|
||||
|
||||
#if USE_GOOGLE_IMA
|
||||
if _adTagUrl != nil {
|
||||
if _source?.adParams.adTagUrl != nil {
|
||||
// Set up your content playhead and contentComplete callback.
|
||||
_contentPlayhead = IMAAVPlayerContentPlayhead(avPlayer: _player!)
|
||||
|
||||
@ -1216,16 +1214,11 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
||||
// MARK: - RCTIMAAdsManager
|
||||
|
||||
func getAdLanguage() -> String? {
|
||||
return _adLanguage
|
||||
return _source?.adParams.adLanguage
|
||||
}
|
||||
|
||||
func getAdTagUrl() -> String? {
|
||||
return _adTagUrl
|
||||
}
|
||||
|
||||
@objc
|
||||
func setAdTagUrl(_ adTagUrl: String?) {
|
||||
_adTagUrl = adTagUrl
|
||||
return _source?.adParams.adTagUrl
|
||||
}
|
||||
|
||||
#if USE_GOOGLE_IMA
|
||||
|
@ -5,8 +5,6 @@
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(src, NSDictionary);
|
||||
RCT_EXPORT_VIEW_PROPERTY(drm, NSDictionary);
|
||||
RCT_EXPORT_VIEW_PROPERTY(adTagUrl, NSString);
|
||||
RCT_EXPORT_VIEW_PROPERTY(adLanguage, NSString);
|
||||
RCT_EXPORT_VIEW_PROPERTY(maxBitRate, float);
|
||||
RCT_EXPORT_VIEW_PROPERTY(resizeMode, NSString);
|
||||
RCT_EXPORT_VIEW_PROPERTY(repeat, BOOL);
|
||||
|
@ -91,6 +91,8 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
||||
useSecureView,
|
||||
viewType,
|
||||
shutterColor,
|
||||
adTagUrl,
|
||||
adLanguage,
|
||||
onLoadStart,
|
||||
onLoad,
|
||||
onError,
|
||||
@ -225,6 +227,12 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
||||
const selectedContentStartTime =
|
||||
_source.contentStartTime || contentStartTime;
|
||||
|
||||
const _ad =
|
||||
_source.ad ||
|
||||
(adTagUrl || adLanguage
|
||||
? {adTagUrl: adTagUrl, adLanguage: adLanguage}
|
||||
: undefined);
|
||||
|
||||
return {
|
||||
uri,
|
||||
isNetwork,
|
||||
@ -240,6 +248,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
||||
contentStartTime: selectedContentStartTime,
|
||||
metadata: resolvedSource.metadata,
|
||||
drm: _drm,
|
||||
ad: _ad,
|
||||
cmcd: _cmcd,
|
||||
textTracks: _textTracks,
|
||||
textTracksAllowChunklessPreparation:
|
||||
@ -247,10 +256,12 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
||||
};
|
||||
},
|
||||
[
|
||||
adLanguage,
|
||||
adTagUrl,
|
||||
contentStartTime,
|
||||
drm,
|
||||
localSourceEncryptionKeyScheme,
|
||||
source,
|
||||
source?.cmcd,
|
||||
textTracks,
|
||||
],
|
||||
);
|
||||
|
@ -26,6 +26,11 @@ type VideoMetadata = Readonly<{
|
||||
imageUri?: string;
|
||||
}>;
|
||||
|
||||
export type AdsConfig = Readonly<{
|
||||
adTagUrl?: string;
|
||||
adLanguage?: string;
|
||||
}>;
|
||||
|
||||
export type VideoSrc = Readonly<{
|
||||
uri?: string;
|
||||
isNetwork?: boolean;
|
||||
@ -44,6 +49,7 @@ export type VideoSrc = Readonly<{
|
||||
cmcd?: NativeCmcdConfiguration; // android
|
||||
textTracksAllowChunklessPreparation?: boolean; // android
|
||||
textTracks?: TextTracks;
|
||||
ad?: AdsConfig;
|
||||
}>;
|
||||
|
||||
type DRMType = WithDefault<string, 'widevine'>;
|
||||
@ -319,8 +325,6 @@ export type OnControlsVisibilityChange = Readonly<{
|
||||
|
||||
export interface VideoNativeProps extends ViewProps {
|
||||
src?: VideoSrc;
|
||||
adTagUrl?: string;
|
||||
adLanguage?: string;
|
||||
allowsExternalPlayback?: boolean; // ios, true
|
||||
disableFocus?: boolean; // android
|
||||
maxBitRate?: Float;
|
||||
|
@ -38,6 +38,7 @@ export type ReactVideoSourceProperties = {
|
||||
cmcd?: Cmcd; // android
|
||||
textTracksAllowChunklessPreparation?: boolean;
|
||||
textTracks?: TextTracks;
|
||||
ad?: AdConfig;
|
||||
};
|
||||
|
||||
export type ReactVideoSource = Readonly<
|
||||
@ -73,6 +74,11 @@ export enum DRMType {
|
||||
FAIRPLAY = 'fairplay',
|
||||
}
|
||||
|
||||
export type AdConfig = Readonly<{
|
||||
adTagUrl?: string;
|
||||
adLanguage?: ISO639_1;
|
||||
}>;
|
||||
|
||||
export type Drm = Readonly<{
|
||||
type?: DRMType;
|
||||
licenseServer?: string;
|
||||
@ -276,7 +282,9 @@ export interface ReactVideoProps extends ReactVideoEvents, ViewProps {
|
||||
/** @deprecated Use source.drm */
|
||||
drm?: Drm;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
/** @deprecated Use source.ad.adTagUrl */
|
||||
adTagUrl?: string;
|
||||
/** @deprecated Use source.ad.adLanguage */
|
||||
adLanguage?: ISO639_1;
|
||||
audioOutput?: AudioOutput; // Mobile
|
||||
automaticallyWaitsToMinimizeStalling?: boolean; // iOS
|
||||
|
Loading…
Reference in New Issue
Block a user