React-native-video: resizeMode not working in iOS 10

Created on 18 Sep 2016  路  19Comments  路  Source: react-native-video/react-native-video

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.

bug help wanted iOS

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)

    <Video source={{ uri: 'myVideo', type: 'mov' }}
            style={{ position: 'absolute', top: 0, left: 0, bottom: 0, right: 0 }}
            resizeMode='cover'
            muted
            repeat
            key='video2' />

All 19 comments

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nechmads picture nechmads  路  20Comments

cande1gut picture cande1gut  路  19Comments

jonathangreco picture jonathangreco  路  56Comments

nicoara picture nicoara  路  24Comments

doodirock picture doodirock  路  36Comments