React native youtube - component not visible - react-native

I cannot see the player, when mounting to my page:
return (
<YouTube
apiKey="xxx"
videoId={youtubeVideo} // The YouTube video ID
play={false} // control playback of video with true/false
fullscreen={false} // control whether the video should play in fullscreen or inline
loop={false} // control whether the video should loop when ended
onReady={e => console.log('ready')}
onChangeState={e => console.log('onchange')}
onChangeQuality={e => console.log('change quality')}
onError={e => console.log(e.error)}
style={{ alignSelf: "stretch", height: 300 }}
/>
);
I get console logs for the onReady callback but no video. How can I display my video?
Are there any better alternatives? Having looked into these two packages, react-native-youtube and react-native-vimeo. Both haven't been maintained for a while and have various issues.
What is the best way to embed video from youtube that fits guidelines for both Play and App Stores? With lots of video based apps on the Play stores, how does everyone else do it?

Is your YouTube component wrapped inside a parent view with flex ? I'm using the same package in my app and it seems to be working fine and this is pretty much how I've got it set up.
// Parent view (page container)
<View style={{ flex : 1 }}>
...
<Youtube
apiKey={API_KEY}
videoId={videoID}
style={{ marginTop : 15, height : 250, alignSelf : 'stretch' }} />
...
</View>

Related

How to play YouTube videos in React native player?

I want to play some YouTube videos in my react native app using a native player as we don't want to show youtube branding in the player. Is there any possible way to do this?
If not, what's the best way to play youtube videos in react native app without showing youtube branding?
You can do this using react-native-webview.
<WebView
javaScriptEnabled={true}
domStorageEnabled={true}
scrollEnabled={false}
source={{
uri: `${"YOUR YOUTUBE URL"}?controls=0&showinfo=0&wmode=transparent&rel=0&mode=opaque`,
}}
style={{
height: 200,
width: Dimensions.get('window').width - 80,
}}
onError={(err) => {
console.log(err, 'this is errr');
}}
/>

React Native View Shot not capturing video of live stream on ios

I am using React Native View Shot and I need our product to be able to capture live streaming from a m3u8 uri from React Native video package.
Currently on android it is capturing the screen fine, but on IOS there seems to be an issue of View Shot capturing just a blank video. How it looks on IOS
The livestream is the one playing below and the screenshot is the one taken of the video.
Are they just not compatible, or how would I resolve the issue of capturing a screenshot of a live stream on ios?
<TouchableOpacity onPress={()=>saveCapturedImage()} style={capturedShot ? styles.capturedShotStyle : styles.beforeShotStyle}>
{capturedShot ? <Text/> : <Text>Click to capture shot</Text> }
</TouchableOpacity>
<Image style={capturedShot ? styles.captureContainerPost : styles.captureContainerPre} source={capturedShot ? {uri: capturedShot } : null} />
{/* Viewshot component from React Native Viewshot */}
<ViewShot ref={viewShotRef} options={{ format: "jpg", quality: 0.9 }}>
{/* Video component from React Native Video, resizeMode cover to get full height on the component. Add pause controls for default, and controls can be toggled true/false */}
{videoUri && <Video
source={{
uri: videoUri,
}}
style={{
width: "100%",
height: "100%",
}}
resizeMode="cover"
controls={true}
paused = {false}
/>}
</ViewShot>
If anyone else wants an answer for this problem in future, I wrapped View shot capturing screen over a react native webview component playing a video on ios. It took a photo of a paused Youtube video playing. But even though View Shot captured a WebView of a video embedded, the content of the video was empty.
Not sure if this is because of RN View Shot, have emailed the founder of the package. Or does Ios block video content playing?
<View collapsable={false} style=Template:Height: "80%">
<WebView
originWhitelist={["*"]}
source={{
html:
'<iframe playsinline controls autoplay src="https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8" ></iframe>',
}}
useWebKit={true}
originWhitelist={["*"]}
allowsInlineMediaPlayback={true}
style={{
height: 600,
width: 400,
}}
/>
</View>
</ViewShot>
But if anyone finds a better alternative solution let me know.

Unable to inspect/interact with iOS react native app elements in Appium

I am trying to locate the below highlighted meeting information. However in appium inspector all the elements are combined and shown in a single container.
Three elements highlighted in red has different test id's but when I try to inspect it shows all three as one element. Hence I am not able to interact with any specific element on iOS.
I can inspect the same three elements as different elements in android app. It works fine for android.
p.s - I have also tried to inspect elements using accessibility inspector. the result is the same.
The app is developed in react native for Android and iOS.
Appium desktop version- 1.18.0-2
code snippet-
<Card.Content>
<Title
accessibilityLabel="testID-meetingTitle"
testID="testID-meetingTitle"
>
{item.name}
</Title>
<Text
style={{ fontSize: 14, lineHeight: 20, color: "rgba(0,0,0,0.6)" }}
testID-meetingTitle
accessibilityLabel="testID-meetingInformation"
testID="testID-meetingInformation"
>
{item.date}
</Text>
</Card.Content>
Please let me know if there is any solution for the same..
You should NOT specify accessibilityLabel for ios
separate props for ios and android like so:
export default function testID(id) {
return Platform.OS === 'android'
? {
accessible : true,
accessibilityLabel: id,
}
: {
testID: id,
};
}
and then
<Text
{...otherProps}
{...testID('testID-meetingInformation')}
/>

Why Flatlist isn't rendering properly when android build apk orientation changes?

I'm using expo to build a pantry service app and I'm fetching a list of items from a node pantry server then render them on the app using Flatlist.
Everything works as expected except for one thing and that is the flatlist rendering when Orientation changes.
When testing with the expo app it works flawlessly even when the orientation changes.
Problem: When building android apk and testing it on device flatlist no longer renders as expected and for instance:
-> When starting the app in portrait mode you can scroll all the way to the bottom but when you rotate the device I'm unable to scroll all the way to the bottom or it seems I can but the rest of the items seem to be clipped beyond the device display borders.
-> Conversely when I start the app in landscape mode I'm able to scroll to the bottom with no issue but when I change the orientation to portrait the flatlist renders only half way through the screen, I'm still able to scroll to the end of it.
I've tried passing to extraData as well add flexgrow to contentContainerStyle,I've also tried using ScrollView instead of View but there are no noticeable improvements.
const [refreshing,setRefreshing] = useState(false)
ScreenOrientation.addOrientationChangeListener(
evt => {
setCurrOrientation(evt.orientationInfo.orientation)
setRefreshing(!refreshing)
}
)
ScreenOrientation.getOrientationAsync().then(result => setCurrOrientation(result.orientation))
keyExtractor = (item, index) => index.toString()
renderItem = ({ item,index }) => (
<ListItem
key={index}
leftAvatar={{ source: { uri: BASE_URL + ':' + PORT + '/uploads/' + item.rowid + '/image.png' } }}
title={<Text style={{ fontFamily: 'fake-receipt' }}>{item.item_name}</Text>}
subtitle={<Text style={{ fontFamily: 'fake-receipt', color: 'grey', fontSize: 10 }}>{item.item_type}</Text>}
containerStyle={{ borderBottomColor: '#F0F0F0', borderBottomWidth: 1, borderBottomStartRadius: 10, borderTopStartRadius: 10 }}
onPress={() => {
setSelectedItemIndex(index);
setSelectedItemRowID(item.rowid);
setSelectedItemSugarCondition(item.sugar === 'yes' ? 'yes' : 'no');
setOverlayVisible(true);
}}
rightIcon={<IconFA name={'plus'}
size={20}
color='#26a69a'
/>}
/>
)
<View>
<FlatList
contentContainerStyle={{ flexGrow: 1 }}
extraData={refreshing}
keyExtractor={this.keyExtractor}
data={itemsList}
renderItem={this.renderItem}
/>
</View>
Its puzzling me how it works fine in the expo app but not the expo android build, any ideas how I can fix this or if there is a better alternative?
I'm using expo 3.0.10 and device is running Android 9 Pie
I have figured it out, I used Dimensions with another view and placed flatlist inside it, this rendered the flatlist properly after orientation.
<View style={{ backgroundColor: '#f1f1f1', flex: 1 }}>
<View style={{height:Dimensions.get('window').height - 80}}>
<FlatList
extraData={refreshing}
keyExtractor={this.keyExtractor}
data={itemsList}
renderItem={this.renderItem}
/>
</View>
</View>

Change parent of react native video component without unmounting

I am attempting to create picture in picture functionality on iPhone in react native using the react-native-video component. I have two elements, one is the video player, and the other is an image absolutely positioned on top of the player in the lower right corner.
<View style={{ position: 'relative' }}>
<View>
{ this.props.swapPip ? renderVideoPlayer() : renderPip() }
</View>
<View style={{ position: 'absolute', bottom: 16, right: 16 }}>
{ this.props.swapPip ? renderPip() : renderVideoPlayer() }
</View>
</View>
I would like to play the video, and then mid-play, and be able to switch the swapPip property so that the video is now the pip and the image is in the main view. The catch is the video must continue to play smoothly through the transition. Currently it is re-mounting each time the swap happens, losing the video and causing an annoying reload and other unwanted side effects. Is this possible to achieve?
Here is a rough image of the idea. The gray boxes represent the video player, the pink represents the image. Clicking on the smaller box (whatever color) will swap the two back and forth. Swapping should be allowed at any time, and if a video happens to be playing during a swap, playback should not be interrupted in any way.
I guess this turned out to be a dumb question, because zIndex is actually a thing in react-native now. Its in the docs and everything, and works exactly like you would expect:
const pipPosition = { position: 'absolute', bottom: 16, right: 16, zIndex: 99 };
const sourceAPosition = this.props.swapPip ? pipPosition : {};
const sourceBPosition = !this.props.swapPip ? pipPosition : {};
<View style={{ position: 'relative' }}>
<View style={sourceAPosition}>
{ renderSourceA() }
</View>
<View style={sourceBPosition}>
{ renderSourceB() }
</View>
</View>
For some reason I was under the impression zIndex did not exist/work in react-native, and that the ordering of your elements was the only way to accomplish layering...