itsnubix / react-native-video-controls

A React Native video component with controls
MIT License
637 stars 526 forks source link

How can I load a video from app-folder...for-example assets? #80

Closed Turtle0601 closed 6 years ago

Turtle0601 commented 6 years ago

Hi, I'll get the videos of the assets-file-folder from the react-native app.

How can i do this with this component?

Because, if i wrote the uri with URL to the folder, the video don't show, the player loads and loads, but don't play.

for Example: source={{ uri: '/Recovered References/BigBuckBunny_512kb.mp4'}}

And can i change the option, that the video only starts, if i touch the play-button.

Thanks for help

kylemilloy commented 6 years ago

To load a video from your app folder use require:

source={{uri: require(‘path/to/video.mp4’)}}

To stop auto play on the video pass the paused prop to the component:

paused={ true }

See more here about video props you can pass through to the video: https://github.com/react-native-community/react-native-video

Turtle0601 commented 6 years ago

Thanks for your help.

I have test it ...your the source example isn't works. But it was the right way and take me to the solution. I figured out, this:

source={require('./assets/BigBuckBunny_512kb0.mp4')}

and it works! :)

And thanks for the info-link! I don't know, can use the props from the normal video-component too. Very Helpful! :)

Best Regards

kylemilloy commented 6 years ago

Sorry about that...was texting you from my phone so was going off memory...glad you got it figured out.

Turtle0601 commented 6 years ago

No worries! However it was helpful.

:)

azanli commented 6 years ago

@kylemilloy Is there any way to use the same implementation as react-native-video as they use source={{ uri: 'path/to/file.mp4' }} regardless of whether it is a local or remote file. The reason I ask is because require() does not render dynamically set assets; so like require( uri ) doesn't work, it needs to be preset: require( 'path/to/local/file.mp4' ), which is an unusual use-case for video files.

kylemilloy commented 6 years ago

Of course. Pass it like any variable.

azanli commented 6 years ago

@kylemilloy Thank you for your prompt reply.

From my understanding, passing in a variable to require() is considered attempting to dynamically require assets. There is a big commotion about the metro bundler inability to do so at the moment in react-native issue #52.

In order to get around the require() method of this library, I simply removed the overriding source={ this.props.source } prop reference in the <Video /> component of VideoPlayer.js. So instead of:

                    <Video
                        { ...this.props }
                        ref={ videoPlayer => this.player.ref = videoPlayer }

                        resizeMode={ this.state.resizeMode }
                        volume={ this.state.volume }
                        paused={ this.state.paused }
                        muted={ this.state.muted }
                        rate={ this.state.rate }

                        onLoadStart={ this.events.onLoadStart }
                        onProgress={ this.events.onProgress }
                        onError={ this.events.onError }
                        onLoad={ this.events.onLoad }
                        onEnd={ this.events.onEnd }

                        style={[ styles.player.video, this.styles.videoStyle ]}

                        source={ this.props.source }
                    />

render the component without a source prop so it uses the underlying source prop of react-native-video which doesn't require the use of require() for local assets:

                    <Video
                        { ...this.props }
                        ref={ videoPlayer => this.player.ref = videoPlayer }

                        resizeMode={ this.state.resizeMode }
                        volume={ this.state.volume }
                        paused={ this.state.paused }
                        muted={ this.state.muted }
                        rate={ this.state.rate }

                        onLoadStart={ this.events.onLoadStart }
                        onProgress={ this.events.onProgress }
                        onError={ this.events.onError }
                        onLoad={ this.events.onLoad }
                        onEnd={ this.events.onEnd }

                        style={[ styles.player.video, this.styles.videoStyle ]}
                    />
kylemilloy commented 6 years ago

Sorry, I fail to see how this would make a difference...in the original code it's explicitly called out that source is passed, in the second we just rely on ...this.props.

How does this change this.props.source being used by the Video component?

azanli commented 6 years ago

The change this makes is now I am able to pass source={{ uri }} where uri is a local file path, to <VideoPlayer /> without needing to use a dynamic require() such as source={ require(uri) }.

Before I removed source={ this.props.source } from VideoPlayer.js, passing in source={{ uri }} would result in a "video unavailable" error as suggested by OP's issue.

I see what you mean that this change seems as though it is only coming full circle, but the exclusion of source really did make the difference for me to load a local file without needing to require() it. I'd be happy to make a PR with the updated changes.

kylemilloy commented 6 years ago

Yeah if you don't mind writing a PR I'd like to test this one myself. I'm having difficulty wrapping my head around how this changes anything. Maybe I'm reading your code wrong?

Here's what I'm understanding:

In the first we do:

<Video 
  { ...this.props }
  source={ this.props.source }
/>

We explicitly call out source and pass it on.

In the second we do:

<Video { ...this.props } />

And rely on passing the source with the spread operator with the rest of the props.

To me, it's the exact same thing...isn't it?

Like, you can do...

<VideoPlayer source={{ uri: 'path/to/file' }} />

...now already...or you can use require to import it from the RN directory.

Sorry again...maybe there's some black magic going on that I'm not aware of behind the scenes or maybe I just don't understand the problem.

raphaelluiz128 commented 4 years ago

if i remove the line with "source={this.props.source}", it's ok to use source={{uri: this.state.dir}} ? a dymamic local file ? i will select the file in a list and the path will stored in state dir, i have five videos and require is not dynamic