resizeMode='cover' in iOS 9.3 works as expected. In iOS 10.0 the video doesn't resize to take up the full Video component size so I have blank space at the top and bottom of the video.
What's actually really interesting is that if I have hot loading on and I switch resizeMode to container and then back to cover it works properly. It seems like it just doesn't resize when the video first loads.
Same issue with stretch - it does not resize on initial load.
If I add the repeat prop it will resize after the first loop.
I found a hackie workaround that maybe help someone till this is fixed.
componentDidMount() {
setTimeout(() => this.videoPlayer.seek(99999), 50)
}
render() {
<Video
ref={ref => this.videoPlayer = ref}
source={{ uri: 'video' }}
resizeMode="stretch"
repeat
paused={false}
volume={0}
style={styles.videoPlayer} />
}
Maybe this can be related to #331 and #297
@jpgarcia yeah that only works if you want to have the video repeat. Have you been able to get it to work without repeat?
nope :(
@jpgarcia expanding on your hack, here's a solution that is working for me for repeat and non-repeat videos. You can just import this component instead of react-native-video and it'll "fix" the issue.
import Video from 'react-native-video'
import React, { Component } from 'react'
const END_TIME = 9999999
export default class VideoPatch extends Component {
constructor (props) {
super(props)
this.state = { paused: false }
this.passedProps = {}
// Starts 1 because we're immediately going to skip to second play
this.playCount = 1
}
componentWillMount () {
// Store passed props that we're overriding
this.passedProps = {
repeat: this.props.repeat,
onEnd: this.props.onEnd,
onLoad: this.props.onLoad
}
}
componentWillReceiveProps (newProps) {
const { repeat, onEnd, onLoad } = newProps
// Updated passed props that we're overriding if they change
if (repeat || onEnd || onLoad) {
this.passedProps = {
repeat: repeat || this.passedProps.repeat,
onEnd: this.props.onEnd || this.passedProps.onEnd,
onLoad: this.props.onLoad || this.passedProps.onLoad
}
}
}
/**
* Cb on video end that handles when to end the video
*/
onEnd () {
if (this.passedProps.repeat) {
// If the video should repeat, emit onEnd immediately
this.passedProps.onEnd && this.passedProps.onEnd()
} else {
// If the video should not repeat, only emit onEnd after it's finished its second play
if (this.playCount === 2) {
this.setState({ paused: true })
this.passedProps.onEnd && this.passedProps.onEnd()
} else {
this.playCount++
}
}
}
/**
* Cb on video load
*/
onLoad () {
// This fixes video resize by seeking to end of the video
// Because the video resizes when it finishes the first time
this.refs.video.seek(END_TIME)
this.passedProps.onLoad && this.passedProps.onLoad()
}
render () {
return <Video
ref='video'
{...this.props}
paused={this.state.paused || this.passedProps.paused}
repeat
onEnd={() => this.onEnd()}
onLoad={() => this.onLoad()} />
}
}
Fair warning the above code is definitely a hack. It can mess up iOS <= 9.3 because it calls onEnd twice in the beginning so your video will never play. I'd recommend checking the Device version or using debounce.
@mattapperson I can try and look into a fix for this. Something I noticed was in iOS <= 9.3 the onLoad and onEnd are fired twice, whereas only once in iOS 10. Do you think that could have an effect on why this is occurring?
+1
I updated to ios10 today and have now the same issue
Is anyone currently working on this? If not, I'll probably try to dig into it and find a fix tomorrow. I'm not much of an iOS dev though, so if anyone has any pointers, they would be appreciated.
@maxschmeling I'm not working on it - was going to but haven't heard back from @mattapperson
Sorry I missed this thread... one sec while I take a look...
"Interesting" behaviour:
when I use the 'muted' property the video does resize as expected (we don't use any sound, it's a background video)
<Video source={{ uri: 'myVideo', type: 'mov' }}
style={{ position: 'absolute', top: 0, left: 0, bottom: 0, right: 0 }}
resizeMode='cover'
muted
repeat
key='video2' />
This bug is soooo odd... iPad pro does not seem to have this bug but all my other ios 10 devices do...
For me, even with muted and repeat property, cover mode doesn't work...
The oddest thing is that with several videos (same resolution, same format) they are displayed differently. Sometimes cover mode works sometimes it doesn't.
Did someone find a workaround while waiting for a fix ?
@tuxtux00 I set resizeMode to contain initially and then in the onLoad handler I set it to cover. This does work, but you typically can see the transition. It's good enough for me though for right now though.
@maxschmeling thanks for the workaround. Not sure if it helps me, I will give it a try.
How do you set it to cover onLoad ?
@tuxtux00 I have an initial state defined with resizeMode set to contain and then I use that as the value for the component (<Video resizeMode={this.state.resizeMode} />) and then in the onLoad handler I just call this.setState({ resizeMode: 'cover' }).
@maxschmeling Thanks !
@maxschmeling well, that didn't work for me.
I can see the transition but the video is still not in cover mode.
Hope someone finds a fix or workaround soon.
@maxschmeling's solution worked for me. @tuxtux00 want to post your code?
@mattapperson any plans for a less hacky solution?
@tuxtux00 here's a gist to a component I'm using following Max's suggestion https://gist.github.com/bsiddiqui/8794ad852d59317a6525318876c43740
If a device is iOS10, I use this component instead of react-native-video directly
Most helpful comment
"Interesting" behaviour:
when I use the 'muted' property the video does resize as expected (we don't use any sound, it's a background video)