chore(android): move contentStartTime into source prop (#4160)
This commit is contained in:
parent
b74cb59602
commit
24d90e9ec8
@ -38,6 +38,9 @@ class Source {
|
|||||||
/** Will crop content end at specified position */
|
/** Will crop content end at specified position */
|
||||||
var cropEndMs: Int = -1
|
var cropEndMs: Int = -1
|
||||||
|
|
||||||
|
/** Will virtually consider that content before contentStartTime is a preroll ad */
|
||||||
|
var contentStartTime: Int = -1
|
||||||
|
|
||||||
/** Allow to force stream content, necessary when uri doesn't contain content type (.mlp4, .m3u, ...) */
|
/** Allow to force stream content, necessary when uri doesn't contain content type (.mlp4, .m3u, ...) */
|
||||||
var extension: String? = null
|
var extension: String? = null
|
||||||
|
|
||||||
@ -79,6 +82,7 @@ class Source {
|
|||||||
startPositionMs == other.startPositionMs &&
|
startPositionMs == other.startPositionMs &&
|
||||||
extension == other.extension &&
|
extension == other.extension &&
|
||||||
drmProps == other.drmProps &&
|
drmProps == other.drmProps &&
|
||||||
|
contentStartTime == other.contentStartTime &&
|
||||||
cmcdProps == other.cmcdProps &&
|
cmcdProps == other.cmcdProps &&
|
||||||
sideLoadedTextTracks == other.sideLoadedTextTracks
|
sideLoadedTextTracks == other.sideLoadedTextTracks
|
||||||
)
|
)
|
||||||
@ -139,6 +143,7 @@ class Source {
|
|||||||
private const val PROP_SRC_START_POSITION = "startPosition"
|
private const val PROP_SRC_START_POSITION = "startPosition"
|
||||||
private const val PROP_SRC_CROP_START = "cropStart"
|
private const val PROP_SRC_CROP_START = "cropStart"
|
||||||
private const val PROP_SRC_CROP_END = "cropEnd"
|
private const val PROP_SRC_CROP_END = "cropEnd"
|
||||||
|
private const val PROP_SRC_CONTENT_START_TIME = "contentStartTime"
|
||||||
private const val PROP_SRC_TYPE = "type"
|
private const val PROP_SRC_TYPE = "type"
|
||||||
private const val PROP_SRC_METADATA = "metadata"
|
private const val PROP_SRC_METADATA = "metadata"
|
||||||
private const val PROP_SRC_HEADERS = "requestHeaders"
|
private const val PROP_SRC_HEADERS = "requestHeaders"
|
||||||
@ -201,6 +206,7 @@ class Source {
|
|||||||
source.startPositionMs = safeGetInt(src, PROP_SRC_START_POSITION, -1)
|
source.startPositionMs = safeGetInt(src, PROP_SRC_START_POSITION, -1)
|
||||||
source.cropStartMs = safeGetInt(src, PROP_SRC_CROP_START, -1)
|
source.cropStartMs = safeGetInt(src, PROP_SRC_CROP_START, -1)
|
||||||
source.cropEndMs = safeGetInt(src, PROP_SRC_CROP_END, -1)
|
source.cropEndMs = safeGetInt(src, PROP_SRC_CROP_END, -1)
|
||||||
|
source.contentStartTime = safeGetInt(src, PROP_SRC_CONTENT_START_TIME, -1)
|
||||||
source.extension = safeGetString(src, PROP_SRC_TYPE, null)
|
source.extension = safeGetString(src, PROP_SRC_TYPE, null)
|
||||||
source.drmProps = parse(safeGetMap(src, PROP_SRC_DRM))
|
source.drmProps = parse(safeGetMap(src, PROP_SRC_DRM))
|
||||||
source.cmcdProps = CMCDProps.parse(safeGetMap(src, PROP_SRC_CMCD))
|
source.cmcdProps = CMCDProps.parse(safeGetMap(src, PROP_SRC_CMCD))
|
||||||
|
@ -235,7 +235,6 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
private boolean disableFocus;
|
private boolean disableFocus;
|
||||||
private boolean focusable = true;
|
private boolean focusable = true;
|
||||||
private BufferingStrategy.BufferingStrategyEnum bufferingStrategy;
|
private BufferingStrategy.BufferingStrategyEnum bufferingStrategy;
|
||||||
private long contentStartTime = -1L;
|
|
||||||
private boolean disableDisconnectError;
|
private boolean disableDisconnectError;
|
||||||
private boolean preventsDisplaySleepDuringVideoPlayback = true;
|
private boolean preventsDisplaySleepDuringVideoPlayback = true;
|
||||||
private float mProgressUpdateInterval = 250.0f;
|
private float mProgressUpdateInterval = 250.0f;
|
||||||
@ -1436,7 +1435,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
ArrayList<Track> audioTracks = getAudioTrackInfo();
|
ArrayList<Track> audioTracks = getAudioTrackInfo();
|
||||||
ArrayList<Track> textTracks = getTextTrackInfo();
|
ArrayList<Track> textTracks = getTextTrackInfo();
|
||||||
|
|
||||||
if (this.contentStartTime != -1L) {
|
if (source.getContentStartTime() != -1) {
|
||||||
ExecutorService es = Executors.newSingleThreadExecutor();
|
ExecutorService es = Executors.newSingleThreadExecutor();
|
||||||
es.execute(() -> {
|
es.execute(() -> {
|
||||||
// To prevent ANRs caused by getVideoTrackInfo we run this on a different thread and notify the player only when we're done
|
// To prevent ANRs caused by getVideoTrackInfo we run this on a different thread and notify the player only when we're done
|
||||||
@ -1539,7 +1538,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
ExecutorService es = Executors.newSingleThreadExecutor();
|
ExecutorService es = Executors.newSingleThreadExecutor();
|
||||||
final DataSource dataSource = this.mediaDataSourceFactory.createDataSource();
|
final DataSource dataSource = this.mediaDataSourceFactory.createDataSource();
|
||||||
final Uri sourceUri = source.getUri();
|
final Uri sourceUri = source.getUri();
|
||||||
final long startTime = this.contentStartTime * 1000 - 100; // s -> ms with 100ms offset
|
final long startTime = source.getContentStartTime() * 1000 - 100; // s -> ms with 100ms offset
|
||||||
|
|
||||||
Future<ArrayList<VideoTrack>> result = es.submit(new Callable() {
|
Future<ArrayList<VideoTrack>> result = es.submit(new Callable() {
|
||||||
final DataSource ds = dataSource;
|
final DataSource ds = dataSource;
|
||||||
@ -2207,10 +2206,6 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
exoPlayerView.setFocusable(this.focusable);
|
exoPlayerView.setFocusable(this.focusable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContentStartTime(int contentStartTime) {
|
|
||||||
this.contentStartTime = contentStartTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShowNotificationControls(boolean showNotificationControls) {
|
public void setShowNotificationControls(boolean showNotificationControls) {
|
||||||
this.showNotificationControls = showNotificationControls;
|
this.showNotificationControls = showNotificationControls;
|
||||||
|
|
||||||
|
@ -49,7 +49,6 @@ class ReactExoplayerViewManager(private val config: ReactExoplayerConfig) : View
|
|||||||
private const val PROP_MIN_LOAD_RETRY_COUNT = "minLoadRetryCount"
|
private const val PROP_MIN_LOAD_RETRY_COUNT = "minLoadRetryCount"
|
||||||
private const val PROP_MAXIMUM_BIT_RATE = "maxBitRate"
|
private const val PROP_MAXIMUM_BIT_RATE = "maxBitRate"
|
||||||
private const val PROP_PLAY_IN_BACKGROUND = "playInBackground"
|
private const val PROP_PLAY_IN_BACKGROUND = "playInBackground"
|
||||||
private const val PROP_CONTENT_START_TIME = "contentStartTime"
|
|
||||||
private const val PROP_DISABLE_FOCUS = "disableFocus"
|
private const val PROP_DISABLE_FOCUS = "disableFocus"
|
||||||
private const val PROP_BUFFERING_STRATEGY = "bufferingStrategy"
|
private const val PROP_BUFFERING_STRATEGY = "bufferingStrategy"
|
||||||
private const val PROP_DISABLE_DISCONNECT_ERROR = "disableDisconnectError"
|
private const val PROP_DISABLE_DISCONNECT_ERROR = "disableDisconnectError"
|
||||||
@ -237,11 +236,6 @@ class ReactExoplayerViewManager(private val config: ReactExoplayerConfig) : View
|
|||||||
videoView.setFocusable(focusable)
|
videoView.setFocusable(focusable)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactProp(name = PROP_CONTENT_START_TIME, defaultInt = -1)
|
|
||||||
fun setContentStartTime(videoView: ReactExoplayerView, contentStartTime: Int) {
|
|
||||||
videoView.setContentStartTime(contentStartTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
@ReactProp(name = PROP_BUFFERING_STRATEGY)
|
@ReactProp(name = PROP_BUFFERING_STRATEGY)
|
||||||
fun setBufferingStrategy(videoView: ReactExoplayerView, bufferingStrategy: String) {
|
fun setBufferingStrategy(videoView: ReactExoplayerView, bufferingStrategy: String) {
|
||||||
val strategy = BufferingStrategy.parse(bufferingStrategy)
|
val strategy = BufferingStrategy.parse(bufferingStrategy)
|
||||||
|
@ -166,9 +166,13 @@ controlsStyles={{
|
|||||||
|
|
||||||
### `contentStartTime`
|
### `contentStartTime`
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Deprecated, use source.contentStartTime instead
|
||||||
|
|
||||||
<PlatformsList types={['Android']} />
|
<PlatformsList types={['Android']} />
|
||||||
|
|
||||||
The start time in ms for SSAI content. This determines at what time to load the video info like resolutions. Use this only when you have SSAI stream where ads resolution is not the same as content resolution.
|
The start time in ms for SSAI content. This determines at what time to load the video info like resolutions. Use this only when you have SSAI stream where ads resolution is not the same as content resolution.
|
||||||
|
Note: This feature only works on DASH streams
|
||||||
|
|
||||||
### `debug`
|
### `debug`
|
||||||
|
|
||||||
@ -833,6 +837,13 @@ source={{
|
|||||||
}}
|
}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `contentStartTime`
|
||||||
|
|
||||||
|
<PlatformsList types={['Android']} />
|
||||||
|
|
||||||
|
The start time in ms for SSAI content. This determines at what time to load the video info like resolutions. Use this only when you have SSAI stream where ads resolution is not the same as content resolution.
|
||||||
|
Note: This feature only works on DASH streams
|
||||||
|
|
||||||
#### `textTracksAllowChunklessPreparation`
|
#### `textTracksAllowChunklessPreparation`
|
||||||
<PlatformsList types={['Android']} />
|
<PlatformsList types={['Android']} />
|
||||||
|
|
||||||
|
@ -34,7 +34,12 @@ import Video, {
|
|||||||
} from 'react-native-video';
|
} from 'react-native-video';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import {type AdditionalSourceInfo} from './types';
|
import {type AdditionalSourceInfo} from './types';
|
||||||
import {bufferConfig, isAndroid, srcList, textTracksSelectionBy} from './constants';
|
import {
|
||||||
|
bufferConfig,
|
||||||
|
isAndroid,
|
||||||
|
srcList,
|
||||||
|
textTracksSelectionBy,
|
||||||
|
} from './constants';
|
||||||
import {Overlay, toast, VideoLoader} from './components';
|
import {Overlay, toast, VideoLoader} from './components';
|
||||||
import * as NavigationBar from 'expo-navigation-bar';
|
import * as NavigationBar from 'expo-navigation-bar';
|
||||||
|
|
||||||
@ -224,7 +229,7 @@ const VideoPlayer: FC<Props> = ({}) => {
|
|||||||
|
|
||||||
const onVideoBandwidthUpdate = (data: OnBandwidthUpdateData) => {
|
const onVideoBandwidthUpdate = (data: OnBandwidthUpdateData) => {
|
||||||
console.log('onVideoBandwidthUpdate', data);
|
console.log('onVideoBandwidthUpdate', data);
|
||||||
}
|
};
|
||||||
|
|
||||||
const onFullScreenExit = () => {
|
const onFullScreenExit = () => {
|
||||||
// iOS pauses video on exit from full screen
|
// iOS pauses video on exit from full screen
|
||||||
@ -284,7 +289,10 @@ const VideoPlayer: FC<Props> = ({}) => {
|
|||||||
bufferingStrategy={BufferingStrategyType.DEFAULT}
|
bufferingStrategy={BufferingStrategyType.DEFAULT}
|
||||||
debug={{enable: true, thread: true}}
|
debug={{enable: true, thread: true}}
|
||||||
subtitleStyle={{subtitlesFollowVideo: true}}
|
subtitleStyle={{subtitlesFollowVideo: true}}
|
||||||
controlsStyles={{hideNavigationBarOnFullScreenMode: true, hideNotificationBarOnFullScreenMode: true}}
|
controlsStyles={{
|
||||||
|
hideNavigationBarOnFullScreenMode: true,
|
||||||
|
hideNotificationBarOnFullScreenMode: true,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
)}
|
)}
|
||||||
|
@ -79,6 +79,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
poster,
|
poster,
|
||||||
posterResizeMode,
|
posterResizeMode,
|
||||||
renderLoader,
|
renderLoader,
|
||||||
|
contentStartTime,
|
||||||
drm,
|
drm,
|
||||||
textTracks,
|
textTracks,
|
||||||
selectedVideoTrack,
|
selectedVideoTrack,
|
||||||
@ -204,6 +205,9 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectedContentStartTime =
|
||||||
|
source.contentStartTime || contentStartTime;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
uri,
|
uri,
|
||||||
isNetwork,
|
isNetwork,
|
||||||
@ -216,6 +220,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
startPosition: resolvedSource.startPosition ?? -1,
|
startPosition: resolvedSource.startPosition ?? -1,
|
||||||
cropStart: resolvedSource.cropStart || 0,
|
cropStart: resolvedSource.cropStart || 0,
|
||||||
cropEnd: resolvedSource.cropEnd,
|
cropEnd: resolvedSource.cropEnd,
|
||||||
|
contentStartTime: selectedContentStartTime,
|
||||||
metadata: resolvedSource.metadata,
|
metadata: resolvedSource.metadata,
|
||||||
drm: _drm,
|
drm: _drm,
|
||||||
cmcd: _cmcd,
|
cmcd: _cmcd,
|
||||||
@ -223,7 +228,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
textTracksAllowChunklessPreparation:
|
textTracksAllowChunklessPreparation:
|
||||||
resolvedSource.textTracksAllowChunklessPreparation,
|
resolvedSource.textTracksAllowChunklessPreparation,
|
||||||
};
|
};
|
||||||
}, [drm, source, textTracks]);
|
}, [drm, source, textTracks, contentStartTime]);
|
||||||
|
|
||||||
const _selectedTextTrack = useMemo(() => {
|
const _selectedTextTrack = useMemo(() => {
|
||||||
if (!selectedTextTrack) {
|
if (!selectedTextTrack) {
|
||||||
|
@ -38,6 +38,7 @@ export type VideoSrc = Readonly<{
|
|||||||
startPosition?: Float;
|
startPosition?: Float;
|
||||||
cropStart?: Float;
|
cropStart?: Float;
|
||||||
cropEnd?: Float;
|
cropEnd?: Float;
|
||||||
|
contentStartTime?: Int32; // Android
|
||||||
metadata?: VideoMetadata;
|
metadata?: VideoMetadata;
|
||||||
drm?: Drm;
|
drm?: Drm;
|
||||||
cmcd?: NativeCmcdConfiguration; // android
|
cmcd?: NativeCmcdConfiguration; // android
|
||||||
@ -344,7 +345,6 @@ export interface VideoNativeProps extends ViewProps {
|
|||||||
debug?: DebugConfig;
|
debug?: DebugConfig;
|
||||||
showNotificationControls?: WithDefault<boolean, false>; // Android, iOS
|
showNotificationControls?: WithDefault<boolean, false>; // Android, iOS
|
||||||
bufferConfig?: BufferConfig; // Android
|
bufferConfig?: BufferConfig; // Android
|
||||||
contentStartTime?: Int32; // Android
|
|
||||||
currentPlaybackTime?: Double; // Android
|
currentPlaybackTime?: Double; // Android
|
||||||
disableDisconnectError?: boolean; // Android
|
disableDisconnectError?: boolean; // Android
|
||||||
focusable?: boolean; // Android
|
focusable?: boolean; // Android
|
||||||
|
@ -31,6 +31,7 @@ export type ReactVideoSourceProperties = {
|
|||||||
startPosition?: number;
|
startPosition?: number;
|
||||||
cropStart?: number;
|
cropStart?: number;
|
||||||
cropEnd?: number;
|
cropEnd?: number;
|
||||||
|
contentStartTime?: number; // Android
|
||||||
metadata?: VideoMetadata;
|
metadata?: VideoMetadata;
|
||||||
drm?: Drm;
|
drm?: Drm;
|
||||||
cmcd?: Cmcd; // android
|
cmcd?: Cmcd; // android
|
||||||
@ -265,6 +266,7 @@ export interface ReactVideoProps extends ReactVideoEvents, ViewProps {
|
|||||||
bufferConfig?: BufferConfig; // Android
|
bufferConfig?: BufferConfig; // Android
|
||||||
bufferingStrategy?: BufferingStrategyType;
|
bufferingStrategy?: BufferingStrategyType;
|
||||||
chapters?: Chapters[]; // iOS
|
chapters?: Chapters[]; // iOS
|
||||||
|
/** @deprecated Use source.contentStartTime */
|
||||||
contentStartTime?: number; // Android
|
contentStartTime?: number; // Android
|
||||||
controls?: boolean;
|
controls?: boolean;
|
||||||
currentPlaybackTime?: number; // Android
|
currentPlaybackTime?: number; // Android
|
||||||
|
Loading…
Reference in New Issue
Block a user