fix(android): revert media3 update, back to 1.1.1 (#3369)

* fix: revert last media3 upgrade

---------

Co-authored-by: olivier <olivier.bouillet@ifeelsmart.com>
This commit is contained in:
Olivier Bouillet 2023-11-22 15:03:57 +01:00 committed by GitHub
parent 11f62013e3
commit 5beef383cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 760 additions and 1563 deletions

View File

@ -4,5 +4,5 @@ RNVideo_targetSdkVersion=31
RNVideo_compileSdkVersion=31 RNVideo_compileSdkVersion=31
RNVideo_ndkversion=21.4.7075529 RNVideo_ndkversion=21.4.7075529
RNVideo_buildToolsVersion=30.0.2 RNVideo_buildToolsVersion=30.0.2
RNVideo_media3Version=1.2.0 RNVideo_media3Version=1.1.1
RNVideo_RNVUseExoplayerIMA=false RNVideo_RNVUseExoplayerIMA=false

13
examples/basic/.eslintrc Normal file
View File

@ -0,0 +1,13 @@
{
"plugins": ["@typescript-eslint"],
"extends": [
"@react-native",
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"parserOptions": {
"requireConfigFile": false
}
}

View File

@ -29,7 +29,6 @@ public class MainApplication extends Application implements ReactApplication {
protected List<ReactPackage> getPackages() { protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable") @SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages(); List<ReactPackage> packages = new PackageList(this).getPackages();
packages.add(new ReactVideoPackage());
// Packages that cannot be autolinked yet can be added manually here, for example: // Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage()); // packages.add(new MyReactNativePackage());
return packages; return packages;

View File

@ -34,6 +34,9 @@
"prettier": "^2.4.1", "prettier": "^2.4.1",
"typescript": "4.8.4" "typescript": "4.8.4"
}, },
"resolutions": {
"@types/react": "^18.0.24"
},
"engines": { "engines": {
"node": ">=16" "node": ">=16"
} }

View File

@ -1,4 +1,4 @@
import React, { FunctionComponent } from 'react'; import React, {FunctionComponent} from 'react';
import { import {
StyleSheet, StyleSheet,
@ -7,21 +7,26 @@ import {
TouchableOpacity, TouchableOpacity,
View, View,
} from 'react-native'; } from 'react-native';
import {ResizeMode} from 'react-native-video';
export type MultiValueControlPropType = number | string | ResizeMode;
/* /*
* MultiValueControl displays a list clickable text view * MultiValueControl displays a list clickable text view
*/ */
interface MultiValueControlType<T> { interface MultiValueControlType<T> {
// a list a string or number to be displayed // a list a string or number to be displayed
values: Array<T> values: Array<T>;
// The selected value in values // The selected value in values
selected?: T selected?: T;
// callback to press onPress // callback to press onPress
onPress: (arg: T) => any onPress: (arg: MultiValueControlPropType) => void;
} }
const MultiValueControl: FunctionComponent<MultiValueControlType<any>> = ({ values, selected, onPress }) => { const MultiValueControl: FunctionComponent<
MultiValueControlType<MultiValueControlPropType>
> = ({values, selected, onPress}) => {
const selectedStyle: TextStyle = StyleSheet.flatten([ const selectedStyle: TextStyle = StyleSheet.flatten([
styles.option, styles.option,
{fontWeight: 'bold'}, {fontWeight: 'bold'},
@ -32,20 +37,23 @@ const MultiValueControl: FunctionComponent<MultiValueControlType<any>> = ({ valu
{fontWeight: 'normal'}, {fontWeight: 'normal'},
]); ]);
return <View style={styles.container}> return (
{values.map((value: string | number) => { <View style={styles.container}>
const _style = value === selected ? selectedStyle : unselectedStyle {values.map((value: MultiValueControlPropType) => {
return ( const _style = value === selected ? selectedStyle : unselectedStyle;
<TouchableOpacity return (
key={value} <TouchableOpacity
onPress={() => { key={value}
onPress?.(value) onPress={() => {
}}> onPress?.(value);
}}>
<Text style={_style}>{value}</Text> <Text style={_style}>{value}</Text>
</TouchableOpacity>) </TouchableOpacity>
})} );
</View> })}
} </View>
);
};
const styles = StyleSheet.create({ const styles = StyleSheet.create({
option: { option: {

View File

@ -9,23 +9,29 @@ import {
} from 'react-native'; } from 'react-native';
/* /*
* ToggleControl displays a 2 states clickable text * ToggleControl displays a 2 states clickable text
*/ */
interface ToggleControlType { interface ToggleControlType {
// boolean indicating if text is selected state // boolean indicating if text is selected state
isSelected?: boolean isSelected?: boolean;
// value of text when selected // value of text when selected
selectedText?: string selectedText?: string;
// value of text when NOT selected // value of text when NOT selected
unselectedText?: string unselectedText?: string;
// default text if no only one text field is needed // default text if no only one text field is needed
text?: string text?: string;
// callback called when pressing the component // callback called when pressing the component
onPress: () => any onPress: () => void;
} }
const ToggleControl = ({ isSelected, selectedText, unselectedText, text, onPress }: ToggleControlType) => { const ToggleControl = ({
isSelected,
selectedText,
unselectedText,
text,
onPress,
}: ToggleControlType) => {
const selectedStyle: TextStyle = StyleSheet.flatten([ const selectedStyle: TextStyle = StyleSheet.flatten([
styles.controlOption, styles.controlOption,
{fontWeight: 'bold'}, {fontWeight: 'bold'},
@ -36,17 +42,16 @@ const ToggleControl = ({ isSelected, selectedText, unselectedText, text, onPress
{fontWeight: 'normal'}, {fontWeight: 'normal'},
]); ]);
const style = isSelected ? selectedStyle : unselectedStyle; const style = isSelected ? selectedStyle : unselectedStyle;
const _text = text ? text : isSelected ? selectedText : unselectedText; const _text = text ? text : isSelected ? selectedText : unselectedText;
return ( return (
<View style={styles.resizeModeControl}> <View style={styles.resizeModeControl}>
<TouchableOpacity <TouchableOpacity onPress={onPress}>
onPress={onPress}>
<Text style={style}>{_text}</Text> <Text style={style}>{_text}</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
); );
} };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
controlOption: { controlOption: {

View File

@ -30,13 +30,42 @@ import Video, {
OnAudioFocusChangedData, OnAudioFocusChangedData,
OnVideoErrorData, OnVideoErrorData,
VideoRef, VideoRef,
ResizeMode ResizeMode,
SelectedTrack,
} from 'react-native-video'; } from 'react-native-video';
import ToggleControl from './ToggleControl'; import ToggleControl from './ToggleControl';
import MultiValueControl from './MultiValueControl'; import MultiValueControl, {
MultiValueControlPropType,
} from './MultiValueControl';
interface StateType {
rate: number;
volume: number;
muted: boolean;
resizeMode: ResizeMode;
duration: number;
currentTime: number;
videoWidth: number;
videoHeight: number;
paused: boolean;
fullscreen: true;
decoration: true;
isLoading: boolean;
seekerFillWidth: number;
seekerPosition: number;
seekerOffset: number;
seeking: boolean;
audioTracks: Array<AudioTrack>;
textTracks: Array<TextTrack>;
selectedAudioTrack: SelectedTrack | undefined;
selectedTextTrack: SelectedTrack | undefined;
srcListId: number;
loop: boolean;
showRNVControls: boolean;
}
class VideoPlayer extends Component { class VideoPlayer extends Component {
state = { state: StateType = {
rate: 1, rate: 1,
volume: 1, volume: 1,
muted: false, muted: false,
@ -86,12 +115,11 @@ class VideoPlayer extends Component {
}, },
{ {
description: 'another bunny (can be saved)', description: 'another bunny (can be saved)',
uri: 'https://rawgit.com/mediaelement/mediaelement-files/master/big_buck_bunny.mp4' uri: 'https://rawgit.com/mediaelement/mediaelement-files/master/big_buck_bunny.mp4',
} },
]; ];
srcIosList = [ srcIosList = [];
]
srcAndroidList = [ srcAndroidList = [
{ {
@ -119,9 +147,8 @@ class VideoPlayer extends Component {
}, },
]; ];
srcList = this.srcAllPlatformList.concat( srcList = this.srcAllPlatformList.concat(
Platform.OS === 'android' ? this.srcAndroidList : this.srcIosList, Platform.OS === 'android' ? this.srcAndroidList : this.srcIosList,
); );
video?: VideoRef; video?: VideoRef;
@ -135,11 +162,11 @@ class VideoPlayer extends Component {
this.toast( this.toast(
true, true,
'Widevine level: ' + 'Widevine level: ' +
widevineLevel + widevineLevel +
'\n hevc: ' + '\n hevc: ' +
hevc + hevc +
'\n avc: ' + '\n avc: ' +
avc, avc,
); );
}, },
); );
@ -276,7 +303,7 @@ class VideoPlayer extends Component {
} }
} }
goToChannel(channel: any) { goToChannel(channel: number) {
this.setState({ this.setState({
srcListId: channel, srcListId: channel,
duration: 0.0, duration: 0.0,
@ -500,15 +527,15 @@ class VideoPlayer extends Component {
); );
} }
onRateSelected = (value: string | number) => { onRateSelected = (value: MultiValueControlPropType) => {
this.setState({rate: value}); this.setState({rate: value});
} };
onVolumeSelected = (value: string | number) => { onVolumeSelected = (value: MultiValueControlPropType) => {
this.setState({volume: value}); this.setState({volume: value});
} };
onResizeModeSelected = (value: ResizeMode) => { onResizeModeSelected = (value: MultiValueControlPropType) => {
this.setState({resizeMode: value}); this.setState({resizeMode: value});
} };
renderOverlay() { renderOverlay() {
return ( return (
@ -526,7 +553,7 @@ class VideoPlayer extends Component {
onPress={() => { onPress={() => {
this.channelDown(); this.channelDown();
}} }}
text='ChDown' text="ChDown"
/> />
</View> </View>
<View style={styles.rightControls}> <View style={styles.rightControls}>
@ -534,8 +561,8 @@ class VideoPlayer extends Component {
onPress={() => { onPress={() => {
this.channelUp(); this.channelUp();
}} }}
text='ChUp' text="ChUp"
/> />
</View> </View>
<View style={styles.bottomControls}> <View style={styles.bottomControls}>
<View style={styles.generalControls}> <View style={styles.generalControls}>
@ -545,38 +572,38 @@ class VideoPlayer extends Component {
onPress={() => { onPress={() => {
this.popupInfo(); this.popupInfo();
}} }}
text='decoderInfo' text="decoderInfo"
/> />
</View> </View>
) : null} ) : null}
<ToggleControl <ToggleControl
isSelected={this.state.paused} isSelected={this.state.paused}
onPress={() => { onPress={() => {
this.setState({paused: !this.state.paused}); this.setState({paused: !this.state.paused});
}} }}
selectedText='pause' selectedText="pause"
unselectedText='playing' unselectedText="playing"
/> />
<ToggleControl <ToggleControl
isSelected={this.state.loop} isSelected={this.state.loop}
onPress={() => { onPress={() => {
this.setState({loop: !this.state.loop}); this.setState({loop: !this.state.loop});
}} }}
selectedText='loop enable' selectedText="loop enable"
unselectedText='loop disable' unselectedText="loop disable"
/> />
<ToggleControl <ToggleControl
onPress={() => { onPress={() => {
this.toggleFullscreen(); this.toggleFullscreen();
}} }}
text='fullscreen' text="fullscreen"
/> />
<ToggleControl <ToggleControl
onPress={() => { onPress={() => {
this.toggleDecoration(); this.toggleDecoration();
}} }}
text='decoration' text="decoration"
/> />
</View> </View>
<View style={styles.generalControls}> <View style={styles.generalControls}>
<MultiValueControl <MultiValueControl
@ -590,21 +617,27 @@ class VideoPlayer extends Component {
selected={this.state.volume} selected={this.state.volume}
/> />
<MultiValueControl <MultiValueControl
values={[ResizeMode.COVER, ResizeMode.CONTAIN, ResizeMode.STRETCH]} values={[
ResizeMode.COVER,
ResizeMode.CONTAIN,
ResizeMode.STRETCH,
]}
onPress={this.onResizeModeSelected} onPress={this.onResizeModeSelected}
selected={this.state.resizeMode} selected={this.state.resizeMode}
/> />
<ToggleControl <ToggleControl
isSelected={this.state.paused} isSelected={this.state.paused}
onPress={() => { onPress={() => {
this.video?.save({}).then((response) => { this.video
?.save({})
.then(response => {
console.log('Downloaded URI', response); console.log('Downloaded URI', response);
}).catch((error) => { })
console.log('error during save ', error) .catch(error => {
console.log('error during save ', error);
}); });
} }}
} text="save"
text='save'
/> />
</View> </View>
{this.renderSeekBar()} {this.renderSeekBar()}
@ -616,7 +649,7 @@ class VideoPlayer extends Component {
<Picker <Picker
style={styles.picker} style={styles.picker}
selectedValue={this.state.selectedAudioTrack?.value} selectedValue={this.state.selectedAudioTrack?.value}
onValueChange={(itemValue, itemIndex) => { onValueChange={itemValue => {
console.log('on audio value change ' + itemValue); console.log('on audio value change ' + itemValue);
this.setState({ this.setState({
selectedAudioTrack: { selectedAudioTrack: {
@ -643,7 +676,7 @@ class VideoPlayer extends Component {
<Picker <Picker
style={styles.picker} style={styles.picker}
selectedValue={this.state.selectedTextTrack?.value} selectedValue={this.state.selectedTextTrack?.value}
onValueChange={(itemValue, itemIndex) => { onValueChange={itemValue => {
console.log('on value change ' + itemValue); console.log('on value change ' + itemValue);
this.setState({ this.setState({
selectedTextTrack: { selectedTextTrack: {
@ -701,7 +734,7 @@ class VideoPlayer extends Component {
onAudioBecomingNoisy={this.onAudioBecomingNoisy} onAudioBecomingNoisy={this.onAudioBecomingNoisy}
onAudioFocusChanged={this.onAudioFocusChanged} onAudioFocusChanged={this.onAudioFocusChanged}
onLoadStart={this.onVideoLoadStart} onLoadStart={this.onVideoLoadStart}
onVideoAspectRatio={this.onAspectRatio} onAspectRatio={this.onAspectRatio}
onReadyForDisplay={this.onReadyForDisplay} onReadyForDisplay={this.onReadyForDisplay}
onBuffer={this.onVideoBuffer} onBuffer={this.onVideoBuffer}
repeat={this.state.loop} repeat={this.state.loop}

View File

@ -1,17 +1,16 @@
'use strict'; 'use strict';
import React, { import React, {Component} from 'react';
Component
} from 'react';
import { import {
StyleSheet, StyleSheet,
Text, Text,
TextStyle,
TouchableOpacity, TouchableOpacity,
View, View,
} from 'react-native'; } from 'react-native';
import Video from 'react-native-video'; import Video, {ResizeMode} from 'react-native-video';
class VideoPlayer extends Component { class VideoPlayer extends Component {
constructor(props: any) { constructor(props: any) {
@ -24,10 +23,10 @@ class VideoPlayer extends Component {
rate: 1, rate: 1,
volume: 1, volume: 1,
muted: false, muted: false,
resizeMode: 'contain', resizeMode: ResizeMode.CONTAIN,
duration: 0.0, duration: 0.0,
currentTime: 0.0, currentTime: 0.0,
paused: 0, paused: false,
}; };
onLoad(data: any) { onLoad(data: any) {
@ -47,39 +46,54 @@ class VideoPlayer extends Component {
} }
renderRateControl(rate: number) { renderRateControl(rate: number) {
const isSelected = (this.state.rate == rate); const isSelected = this.state.rate === rate;
const style: TextStyle = StyleSheet.flatten([
styles.controlOption,
{fontWeight: isSelected ? 'bold' : 'normal'},
]);
return ( return (
<TouchableOpacity onPress={() => { this.setState({rate: rate}) }}> <TouchableOpacity
<Text style={[styles.controlOption, {fontWeight: isSelected ? "bold" : "normal"}]}> onPress={() => {
{rate}x this.setState({rate: rate});
</Text> }}>
<Text style={style}>{rate}x</Text>
</TouchableOpacity> </TouchableOpacity>
) );
} }
renderResizeModeControl(resizeMode: string) { renderResizeModeControl(resizeMode: string) {
const isSelected = (this.state.resizeMode == resizeMode); const isSelected = this.state.resizeMode === resizeMode;
const style: TextStyle = StyleSheet.flatten([
styles.controlOption,
{fontWeight: isSelected ? 'bold' : 'normal'},
]);
return ( return (
<TouchableOpacity onPress={() => { this.setState({resizeMode: resizeMode}) }}> <TouchableOpacity
<Text style={[styles.controlOption, {fontWeight: isSelected ? "bold" : "normal"}]}> onPress={() => {
{resizeMode} this.setState({resizeMode: resizeMode});
</Text> }}>
<Text style={style}>{resizeMode}</Text>
</TouchableOpacity> </TouchableOpacity>
) );
} }
renderVolumeControl(volume: number) { renderVolumeControl(volume: number) {
const isSelected = (this.state.volume == volume); const isSelected = this.state.volume === volume;
const style: TextStyle = StyleSheet.flatten([
styles.controlOption,
{fontWeight: isSelected ? 'bold' : 'normal'},
]);
return ( return (
<TouchableOpacity onPress={() => { this.setState({volume: volume}) }}> <TouchableOpacity
<Text style={[styles.controlOption, {fontWeight: isSelected ? "bold" : "normal"}]}> onPress={() => {
{volume * 100}% this.setState({volume: volume});
</Text> }}>
<Text style={style}>{volume * 100}%</Text>
</TouchableOpacity> </TouchableOpacity>
) );
} }
render() { render() {
@ -88,18 +102,26 @@ class VideoPlayer extends Component {
return ( return (
<View style={styles.container}> <View style={styles.container}>
<TouchableOpacity style={styles.fullScreen} onPress={() => {this.setState({paused: !this.state.paused})}}> <TouchableOpacity
<Video source={require('./broadchurch.mp4')} style={styles.fullScreen}
style={styles.fullScreen} onPress={() => {
rate={this.state.rate} this.setState({paused: !this.state.paused});
paused={this.state.paused} }}>
volume={this.state.volume} <Video
muted={this.state.muted} source={require('./broadchurch.mp4')}
resizeMode={this.state.resizeMode} style={styles.fullScreen}
onLoad={this.onLoad} rate={this.state.rate}
onProgress={this.onProgress} paused={this.state.paused}
onEnd={() => { console.log('Done!') }} volume={this.state.volume}
repeat={true} /> muted={this.state.muted}
resizeMode={this.state.resizeMode}
onLoad={this.onLoad}
onProgress={this.onProgress}
onEnd={() => {
console.log('Done!');
}}
repeat={true}
/>
</TouchableOpacity> </TouchableOpacity>
<View style={styles.controls}> <View style={styles.controls}>
@ -127,8 +149,12 @@ class VideoPlayer extends Component {
<View style={styles.trackingControls}> <View style={styles.trackingControls}>
<View style={styles.progress}> <View style={styles.progress}>
<View style={[styles.innerProgressCompleted, {flex: flexCompleted}]} /> <View
<View style={[styles.innerProgressRemaining, {flex: flexRemaining}]} /> style={[styles.innerProgressCompleted, {flex: flexCompleted}]}
/>
<View
style={[styles.innerProgressRemaining, {flex: flexRemaining}]}
/>
</View> </View>
</View> </View>
</View> </View>
@ -137,7 +163,6 @@ class VideoPlayer extends Component {
} }
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
@ -153,7 +178,7 @@ const styles = StyleSheet.create({
right: 0, right: 0,
}, },
controls: { controls: {
backgroundColor: "transparent", backgroundColor: 'transparent',
borderRadius: 5, borderRadius: 5,
position: 'absolute', position: 'absolute',
bottom: 20, bottom: 20,
@ -200,7 +225,7 @@ const styles = StyleSheet.create({
controlOption: { controlOption: {
alignSelf: 'center', alignSelf: 'center',
fontSize: 11, fontSize: 11,
color: "white", color: 'white',
paddingLeft: 2, paddingLeft: 2,
paddingRight: 2, paddingRight: 2,
lineHeight: 12, lineHeight: 12,
@ -212,4 +237,4 @@ const styles = StyleSheet.create({
justifyContent: 'center', justifyContent: 'center',
}, },
}); });
export default VideoPlayer export default VideoPlayer;

View File

@ -5,6 +5,6 @@
"react-native-video": ["../../src/index"] "react-native-video": ["../../src/index"]
} }
}, },
"include": ["src"], "include": ["src", "**/*.js"],
"exclude": ["node_modules"] "exclude": ["node_modules"],
} }

File diff suppressed because it is too large Load Diff