UNPKG

42.5 kBMarkdownView Raw
1## react-native-video
2
3A `<Video>` component for react-native, as seen in
4[react-native-login](https://github.com/brentvatne/react-native-login)!
5
6Version 4.x requires react-native >= 0.57.0
7
8Version 3.x requires react-native >= 0.40.0
9
10### Version 4.0.0 breaking changes
11Version 4.0.0 changes some behaviors and may require updates to your Gradle files. See [Updating](#updating) for details.
12
13Version 4.0.0 now requires Android SDK 26+ and Gradle 3 plugin in order to support ExoPlayer 2.9.0. Google is dropping support for apps using SDKs older than 26 as of October 2018 and Gradle 2 as of January 2019. React Native 0.57 defaults to Gradle 3 & SDK 27.
14
15If you need to support an older React Native version, you should use react-native-video 3.2.1.
16
17### Version 3.0.0 breaking changes
18Version 3.0 features a number of changes to existing behavior. See [Updating](#updating) for changes.
19
20## Table of Contents
21
22* [Installation](#installation)
23* [Usage](#usage)
24* [iOS App Transport Security](#ios-app-transport-security)
25* [Audio Mixing](#audio-mixing)
26* [Android Expansion File Usage](#android-expansion-file-usage)
27* [Updating](#updating)
28
29## Installation
30
31Using npm:
32
33```shell
34npm install --save react-native-video
35```
36
37or using yarn:
38
39```shell
40yarn add react-native-video
41```
42
43Then follow the instructions for your platform to link react-native-video into your project:
44
45<details>
46 <summary>iOS</summary>
47
48### Standard Method
49
50Run `react-native link react-native-video` to link the react-native-video library.
51
52### Using CocoaPods (required to enable caching)
53
54Setup your Podfile like it is described in the [react-native documentation](https://facebook.github.io/react-native/docs/integration-with-existing-apps#configuring-cocoapods-dependencies).
55
56Depending on your requirements you have to choose between the two possible subpodspecs:
57
58Video only:
59
60```diff
61 pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
62+ `pod 'react-native-video', :path => '../node_modules/react-native-video/react-native-video.podspec'`
63end
64```
65
66Video with caching ([more info](docs/caching.md)):
67
68```diff
69 pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
70+ `pod 'react-native-video/VideoCaching', :path => '../node_modules/react-native-video/react-native-video.podspec'`
71end
72```
73
74</details>
75
76<details>
77 <summary>tvOS</summary>
78
79`react-native link react-native-video` doesn’t work properly with the tvOS target so we need to add the library manually.
80
81First select your project in Xcode.
82
83<img src="./docs/tvOS-step-1.jpg" width="40%">
84
85After that, select the tvOS target of your application and select « General » tab
86
87<img src="./docs/tvOS-step-2.jpg" width="40%">
88
89Scroll to « Linked Frameworks and Libraries » and tap on the + button
90
91<img src="./docs/tvOS-step-3.jpg" width="40%">
92
93Select RCTVideo-tvOS
94
95<img src="./docs/tvOS-step-4.jpg" width="40%">
96</details>
97
98<details>
99 <summary>Android</summary>
100
101Run `react-native link react-native-video` to link the react-native-video library.
102
103Or if you have trouble, make the following additions to the given files manually:
104
105**android/settings.gradle**
106
107The newer ExoPlayer library will work for most people.
108
109```gradle
110include ':react-native-video'
111project(':react-native-video').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android-exoplayer')
112```
113
114If you need to use the old Android MediaPlayer based player, use the following instead:
115
116```gradle
117include ':react-native-video'
118project(':react-native-video').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android')
119```
120
121
122**android/app/build.gradle**
123
124```gradle
125dependencies {
126 ...
127 compile project(':react-native-video')
128}
129```
130
131**MainApplication.java**
132
133On top, where imports are:
134
135```java
136import com.brentvatne.react.ReactVideoPackage;
137```
138
139Add the `ReactVideoPackage` class to your list of exported packages.
140
141```java
142@Override
143protected List<ReactPackage> getPackages() {
144 return Arrays.asList(
145 new MainReactPackage(),
146 new ReactVideoPackage()
147 );
148}
149```
150</details>
151
152<details>
153 <summary>Windows</summary>
154
155Make the following additions to the given files manually:
156
157**windows/myapp.sln**
158
159Add the `ReactNativeVideo` project to your solution.
160
1611. Open the solution in Visual Studio 2015
1622. Right-click Solution icon in Solution Explorer > Add > Existing Project
163 * UWP: Select `node_modules\react-native-video\windows\ReactNativeVideo\ReactNativeVideo.csproj`
164 * WPF: Select `node_modules\react-native-video\windows\ReactNativeVideo.Net46\ReactNativeVideo.Net46.csproj`
165
166**windows/myapp/myapp.csproj**
167
168Add a reference to `ReactNativeVideo` to your main application project. From Visual Studio 2015:
169
1701. Right-click main application project > Add > Reference...
171 * UWP: Check `ReactNativeVideo` from Solution Projects.
172 * WPF: Check `ReactNativeVideo.Net46` from Solution Projects.
173
174**MainPage.cs**
175
176Add the `ReactVideoPackage` class to your list of exported packages.
177```cs
178using ReactNative;
179using ReactNative.Modules.Core;
180using ReactNative.Shell;
181using ReactNativeVideo; // <-- Add this
182using System.Collections.Generic;
183...
184
185 public override List<IReactPackage> Packages
186 {
187 get
188 {
189 return new List<IReactPackage>
190 {
191 new MainReactPackage(),
192 new ReactVideoPackage(), // <-- Add this
193 };
194 }
195 }
196
197...
198```
199</details>
200
201<details>
202 <summary>react-native-dom</summary>
203
204Make the following additions to the given files manually:
205
206**dom/bootstrap.js**
207
208Import RCTVideoManager and add it to the list of nativeModules:
209
210```javascript
211import { RNDomInstance } from "react-native-dom";
212import { name as appName } from "../app.json";
213import RCTVideoManager from 'react-native-video/dom/RCTVideoManager'; // Add this
214
215// Path to RN Bundle Entrypoint ================================================
216const rnBundlePath = "./entry.bundle?platform=dom&dev=true";
217
218// React Native DOM Runtime Options =============================================
219const ReactNativeDomOptions = {
220 enableHotReload: false,
221 nativeModules: [RCTVideoManager] // Add this
222};
223```
224</details>
225
226## Usage
227
228```javascript
229// Load the module
230
231import Video from 'react-native-video';
232
233// Within your render function, assuming you have a file called
234// "background.mp4" in your project. You can include multiple videos
235// on a single screen if you like.
236
237<Video source={{uri: "background"}} // Can be a URL or a local file.
238 ref={(ref) => {
239 this.player = ref
240 }} // Store reference
241 onBuffer={this.onBuffer} // Callback when remote video is buffering
242 onError={this.videoError} // Callback when video cannot be loaded
243 style={styles.backgroundVideo} />
244
245// Later on in your styles..
246var styles = StyleSheet.create({
247 backgroundVideo: {
248 position: 'absolute',
249 top: 0,
250 left: 0,
251 bottom: 0,
252 right: 0,
253 },
254});
255```
256
257### Configurable props
258* [allowsExternalPlayback](#allowsexternalplayback)
259* [audioOnly](#audioonly)
260* [bufferConfig](#bufferconfig)
261* [controls](#controls)
262* [filter](#filter)
263* [filterEnabled](#filterEnabled)
264* [fullscreen](#fullscreen)
265* [fullscreenAutorotate](#fullscreenautorotate)
266* [fullscreenOrientation](#fullscreenorientation)
267* [headers](#headers)
268* [hideShutterView](#hideshutterview)
269* [id](#id)
270* [ignoreSilentSwitch](#ignoresilentswitch)
271* [maxBitRate](#maxbitrate)
272* [muted](#muted)
273* [paused](#paused)
274* [playInBackground](#playinbackground)
275* [playWhenInactive](#playwheninactive)
276* [poster](#poster)
277* [posterResizeMode](#posterresizemode)
278* [progressUpdateInterval](#progressupdateinterval)
279* [rate](#rate)
280* [repeat](#repeat)
281* [reportBandwidth](#reportbandwidth)
282* [resizeMode](#resizemode)
283* [selectedAudioTrack](#selectedaudiotrack)
284* [selectedTextTrack](#selectedtexttrack)
285* [selectedVideoTrack](#selectedvideotrack)
286* [source](#source)
287* [stereoPan](#stereopan)
288* [textTracks](#texttracks)
289* [useTextureView](#usetextureview)
290* [volume](#volume)
291
292### Event props
293* [onAudioBecomingNoisy](#onaudiobecomingnoisy)
294* [onBandwidthUpdate](#onbandwidthupdate)
295* [onEnd](#onend)
296* [onExternalPlaybackChange](#onexternalplaybackchange)
297* [onFullscreenPlayerWillPresent](#onfullscreenplayerwillpresent)
298* [onFullscreenPlayerDidPresent](#onfullscreenplayerdidpresent)
299* [onFullscreenPlayerWillDismiss](#onfullscreenplayerwilldismiss)
300* [onFullscreenPlayerDidDismiss](#onfullscreenplayerdiddismiss)
301* [onLoad](#onload)
302* [onLoadStart](#onloadstart)
303* [onProgress](#onprogress)
304* [onSeek](#onseek)
305* [onTimedMetadata](#ontimedmetadata)
306
307### Methods
308* [dismissFullscreenPlayer](#dismissfullscreenplayer)
309* [presentFullscreenPlayer](#presentfullscreenplayer)
310* [save](#save)
311* [seek](#seek)
312
313### Configurable props
314
315#### allowsExternalPlayback
316Indicates whether the player allows switching to external playback mode such as AirPlay or HDMI.
317* **true (default)** - allow switching to external playback mode
318* **false** - Don't allow switching to external playback mode
319
320Platforms: iOS
321
322#### audioOnly
323Indicates whether the player should only play the audio track and instead of displaying the video track, show the poster instead.
324* **false (default)** - Display the video as normal
325* **true** - Show the poster and play the audio
326
327For this to work, the poster prop must be set.
328
329Platforms: all
330
331#### bufferConfig
332Adjust the buffer settings. This prop takes an object with one or more of the properties listed below.
333
334Property | Type | Description
335--- | --- | ---
336minBufferMs | number | The default minimum duration of media that the player will attempt to ensure is buffered at all times, in milliseconds.
337maxBufferMs | number | The default maximum duration of media that the player will attempt to buffer, in milliseconds.
338bufferForPlaybackMs | number | The default duration of media that must be buffered for playback to start or resume following a user action such as a seek, in milliseconds.
339playbackAfterRebufferMs | number | The default duration of media that must be buffered for playback to resume after a rebuffer, in milliseconds. A rebuffer is defined to be caused by buffer depletion rather than a user action.
340
341This prop should only be set when you are setting the source, changing it after the media is loaded will cause it to be reloaded.
342
343Example with default values:
344```
345bufferConfig={{
346 minBufferMs: 15000,
347 maxBufferMs: 50000,
348 bufferForPlaybackMs: 2500,
349 bufferForPlaybackAfterRebufferMs: 5000
350}}
351```
352
353Platforms: Android ExoPlayer
354
355#### controls
356Determines whether to show player controls.
357* ** false (default)** - Don't show player controls
358* **true** - Show player controls
359
360Note on iOS, controls are always shown when in fullscreen mode.
361
362Controls are not available Android because the system does not provide a stock set of controls. You will need to build your own or use a package like [react-native-video-controls](https://github.com/itsnubix/react-native-video-controls) or [react-native-video-player](https://github.com/cornedor/react-native-video-player).
363
364Platforms: iOS, react-native-dom
365
366#### filter
367Add video filter
368* **FilterType.NONE (default)** - No Filter
369* **FilterType.INVERT** - CIColorInvert
370* **FilterType.MONOCHROME** - CIColorMonochrome
371* **FilterType.POSTERIZE** - CIColorPosterize
372* **FilterType.FALSE** - CIFalseColor
373* **FilterType.MAXIMUMCOMPONENT** - CIMaximumComponent
374* **FilterType.MINIMUMCOMPONENT** - CIMinimumComponent
375* **FilterType.CHROME** - CIPhotoEffectChrome
376* **FilterType.FADE** - CIPhotoEffectFade
377* **FilterType.INSTANT** - CIPhotoEffectInstant
378* **FilterType.MONO** - CIPhotoEffectMono
379* **FilterType.NOIR** - CIPhotoEffectNoir
380* **FilterType.PROCESS** - CIPhotoEffectProcess
381* **FilterType.TONAL** - CIPhotoEffectTonal
382* **FilterType.TRANSFER** - CIPhotoEffectTransfer
383* **FilterType.SEPIA** - CISepiaTone
384
385For more details on these filters refer to the [iOS docs](https://developer.apple.com/library/archive/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/uid/TP30000136-SW55).
386
387Notes:
3881. Using a filter can impact CPU usage. A workaround is to save the video with the filter and then load the saved video.
3892. Video filter is currently not supported on HLS playlists.
3903. `filterEnabled` must be set to `true`
391
392Platforms: iOS
393
394#### filterEnabled
395Enable video filter.
396
397* **false (default)** - Don't enable filter
398* **true** - Enable filter
399
400Platforms: iOS
401
402#### fullscreen
403Controls whether the player enters fullscreen on play.
404* **false (default)** - Don't display the video in fullscreen
405* **true** - Display the video in fullscreen
406
407Platforms: iOS
408
409#### fullscreenAutorotate
410If a preferred [fullscreenOrientation](#fullscreenorientation) is set, causes the video to rotate to that orientation but permits rotation of the screen to orientation held by user. Defaults to TRUE.
411
412Platforms: iOS
413
414#### fullscreenOrientation
415
416* **all (default)** -
417* **landscape**
418* **portrait**
419
420Platforms: iOS
421
422#### headers
423Pass headers to the HTTP client. Can be used for authorization.
424
425To enable this on iOS, you will need to manually edit RCTVideo.m and uncomment the header code in the playerItemForSource function. This is because the code used a private API and may cause your app to be rejected by the App Store. Use at your own risk.
426
427Example:
428```
429headers={{
430 Authorization: 'bearer some-token-value',
431 'X-Custom-Header': 'some value'
432}}
433```
434
435Platforms: Android ExoPlayer
436
437#### hideShutterView
438Controls whether the ExoPlayer shutter view (black screen while loading) is enabled.
439
440* **false (default)** - Show shutter view
441* **true** - Hide shutter view
442
443Platforms: Android ExoPlayer
444
445#### id
446Set the DOM id element so you can use document.getElementById on web platforms. Accepts string values.
447
448Example:
449```
450id="video"
451```
452
453Platforms: react-native-dom
454
455#### ignoreSilentSwitch
456Controls the iOS silent switch behavior
457* **"inherit" (default)** - Use the default AVPlayer behavior
458* **"ignore"** - Play audio even if the silent switch is set
459* **"obey"** - Don't play audio if the silent switch is set
460
461Platforms: iOS
462
463#### maxBitRate
464Sets the desired limit, in bits per second, of network bandwidth consumption when multiple video streams are available for a playlist.
465
466Default: 0. Don't limit the maxBitRate.
467
468Example:
469```
470maxBitRate={2000000} // 2 megabits
471```
472
473Platforms: Android ExoPlayer, iOS
474
475#### muted
476Controls whether the audio is muted
477* **false (default)** - Don't mute audio
478* **true** - Mute audio
479
480Platforms: all
481
482#### paused
483Controls whether the media is paused
484* **false (default)** - Don't pause the media
485* **true** - Pause the media
486
487Platforms: all
488
489#### playInBackground
490Determine whether the media should continue playing while the app is in the background. This allows customers to continue listening to the audio.
491* **false (default)** - Don't continue playing the media
492* **true** - Continue playing the media
493
494To use this feature on iOS, you must:
495* [Enable Background Audio](https://developer.apple.com/library/archive/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioSessionBasics/AudioSessionBasics.html#//apple_ref/doc/uid/TP40007875-CH3-SW3) in your Xcode project
496* Set the ignoreSilentSwitch prop to "ignore"
497
498Platforms: Android ExoPlayer, Android MediaPlayer, iOS
499
500#### playWhenInactive
501Determine whether the media should continue playing when notifications or the Control Center are in front of the video.
502* **false (default)** - Don't continue playing the media
503* **true** - Continue playing the media
504
505Platforms: iOS
506
507#### poster
508An image to display while the video is loading
509<br>Value: string with a URL for the poster, e.g. "https://baconmockup.com/300/200/"
510
511Platforms: all
512
513#### posterResizeMode
514Determines how to resize the poster image when the frame doesn't match the raw video dimensions.
515* **"contain" (default)** - Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or less than the corresponding dimension of the view (minus padding).
516* **"center"** - Center the image in the view along both dimensions. If the image is larger than the view, scale it down uniformly so that it is contained in the view.
517* **"cover"** - Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding).
518* **"none"** - Don't apply resize
519* **"repeat"** - Repeat the image to cover the frame of the view. The image will keep its size and aspect ratio. (iOS only)
520* **"stretch"** - Scale width and height independently, This may change the aspect ratio of the src.
521
522Platforms: all
523
524#### progressUpdateInterval
525Delay in milliseconds between onProgress events in milliseconds.
526
527Default: 250.0
528
529Platforms: all
530
531### rate
532Speed at which the media should play.
533* **0.0** - Pauses the video
534* **1.0** - Play at normal speed
535* **Other values** - Slow down or speed up playback
536
537Platforms: all
538
539Note: For Android MediaPlayer, rate is only supported on Android 6.0 and higher devices.
540
541#### repeat
542Determine whether to repeat the video when the end is reached
543* **false (default)** - Don't repeat the video
544* **true** - Repeat the video
545
546Platforms: all
547
548#### reportBandwidth
549Determine whether to generate onBandwidthUpdate events. This is needed due to the high frequency of these events on ExoPlayer.
550
551* **false (default)** - Generate onBandwidthUpdate events
552* **true** - Don't generate onBandwidthUpdate events
553
554Platforms: Android ExoPlayer
555
556#### resizeMode
557Determines how to resize the video when the frame doesn't match the raw video dimensions.
558* **"none" (default)** - Don't apply resize
559* **"contain"** - Scale the video uniformly (maintain the video's aspect ratio) so that both dimensions (width and height) of the video will be equal to or less than the corresponding dimension of the view (minus padding).
560* **"cover"** - Scale the video uniformly (maintain the video's aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding).
561* **"stretch"** - Scale width and height independently, This may change the aspect ratio of the src.
562
563Platforms: Android ExoPlayer, Android MediaPlayer, iOS, Windows UWP
564
565#### selectedAudioTrack
566Configure which audio track, if any, is played.
567
568```
569selectedAudioTrack={{
570 type: Type,
571 value: Value
572}}
573```
574
575Example:
576```
577selectedAudioTrack={{
578 type: "title",
579 value: "Dubbing"
580}}
581```
582
583Type | Value | Description
584--- | --- | ---
585"system" (default) | N/A | Play the audio track that matches the system language. If none match, play the first track.
586"disabled" | N/A | Turn off audio
587"title" | string | Play the audio track with the title specified as the Value, e.g. "French"
588"language" | string | Play the audio track with the language specified as the Value, e.g. "fr"
589"index" | number | Play the audio track with the index specified as the value, e.g. 0
590
591If a track matching the specified Type (and Value if appropriate) is unavailable, the first audio track will be played. If multiple tracks match the criteria, the first match will be used.
592
593Platforms: Android ExoPlayer, iOS
594
595#### selectedTextTrack
596Configure which text track (caption or subtitle), if any, is shown.
597
598```
599selectedTextTrack={{
600 type: Type,
601 value: Value
602}}
603```
604
605Example:
606```
607selectedTextTrack={{
608 type: "title",
609 value: "English Subtitles"
610}}
611```
612
613Type | Value | Description
614--- | --- | ---
615"system" (default) | N/A | Display captions only if the system preference for captions is enabled
616"disabled" | N/A | Don't display a text track
617"title" | string | Display the text track with the title specified as the Value, e.g. "French 1"
618"language" | string | Display the text track with the language specified as the Value, e.g. "fr"
619"index" | number | Display the text track with the index specified as the value, e.g. 0
620
621Both iOS & Android (only 4.4 and higher) offer Settings to enable Captions for hearing impaired people. If "system" is selected and the Captions Setting is enabled, iOS/Android will look for a caption that matches that customer's language and display it.
622
623If a track matching the specified Type (and Value if appropriate) is unavailable, no text track will be displayed. If multiple tracks match the criteria, the first match will be used.
624
625Platforms: Android ExoPlayer, iOS
626
627#### selectedVideoTrack
628Configure which video track should be played. By default, the player uses Adaptive Bitrate Streaming to automatically select the stream it thinks will perform best based on available bandwidth.
629
630```
631selectedVideoTrack={{
632 type: Type,
633 value: Value
634}}
635```
636
637Example:
638```
639selectedVideoTrack={{
640 type: "resolution",
641 value: 480
642}}
643```
644
645Type | Value | Description
646--- | --- | ---
647"auto" (default) | N/A | Let the player determine which track to play using ABR
648"disabled" | N/A | Turn off video
649"resolution" | number | Play the video track with the height specified, e.g. 480 for the 480p stream
650"index" | number | Play the video track with the index specified as the value, e.g. 0
651
652If a track matching the specified Type (and Value if appropriate) is unavailable, ABR will be used.
653
654Platforms: Android ExoPlayer
655
656#### source
657Sets the media source. You can pass an asset loaded via require or an object with a uri.
658
659The docs for this prop are incomplete and will be updated as each option is investigated and tested.
660
661
662##### Asset loaded via require
663
664Example:
665```
666const sintel = require('./sintel.mp4');
667
668source={sintel}
669```
670
671##### URI string
672
673A number of URI schemes are supported by passing an object with a `uri` attribute.
674
675###### Web address (http://, https://)
676
677Example:
678```
679source={{uri: 'https://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_10mb.mp4' }}
680```
681
682Platforms: all
683
684###### File path (file://)
685
686Example:
687```
688source={{ uri: 'file:///sdcard/Movies/sintel.mp4' }}
689```
690
691Note: Your app will need to request permission to read external storage if you're accessing a file outside your app.
692
693Platforms: Android ExoPlayer, Android MediaPlayer, possibly others
694
695###### iPod Library (ipod-library://)
696
697Path to a sound file in your iTunes library. Typically shared from iTunes to your app.
698
699Example:
700```
701source={{ uri: 'ipod-library:///path/to/music.mp3' }}
702```
703
704Note: Using this feature adding an entry for NSAppleMusicUsageDescription to your Info.plist file as described [here](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html)
705
706Platforms: iOS
707
708###### Other protocols
709
710The following other types are supported on some platforms, but aren't fully documented yet:
711`content://, ms-appx://, ms-appdata://, assets-library://`
712
713
714#### stereoPan
715Adjust the balance of the left and right audio channels. Any value between –1.0 and 1.0 is accepted.
716* **-1.0** - Full left
717* **0.0 (default)** - Center
718* **1.0** - Full right
719
720Platforms: Android MediaPlayer
721
722#### textTracks
723Load one or more "sidecar" text tracks. This takes an array of objects representing each track. Each object should have the format:
724
725Property | Description
726--- | ---
727title | Descriptive name for the track
728language | 2 letter [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) representing the language
729type | Mime type of the track<br> * TextTrackType.SRT - SubRip (.srt)<br> * TextTrackType.TTML - TTML (.ttml)<br> * TextTrackType.VTT - WebVTT (.vtt)<br>iOS only supports VTT, Android ExoPlayer supports all 3
730uri | URL for the text track. Currently, only tracks hosted on a webserver are supported
731
732On iOS, sidecar text tracks are only supported for individual files, not HLS playlists. For HLS, you should include the text tracks as part of the playlist.
733
734Note: Due to iOS limitations, sidecar text tracks are not compatible with Airplay. If textTracks are specified, AirPlay support will be automatically disabled.
735
736Example:
737```
738import { TextTrackType }, Video from 'react-native-video';
739
740textTracks={[
741 {
742 title: "English CC",
743 language: "en",
744 type: TextTrackType.VTT, // "text/vtt"
745 uri: "https://bitdash-a.akamaihd.net/content/sintel/subtitles/subtitles_en.vtt"
746 },
747 {
748 title: "Spanish Subtitles",
749 language: "es",
750 type: TextTrackType.SRT, // "application/x-subrip"
751 uri: "https://durian.blender.org/wp-content/content/subtitles/sintel_es.srt"
752 }
753]}
754```
755
756
757Platforms: Android ExoPlayer, iOS
758
759#### useTextureView
760Controls whether to output to a TextureView or SurfaceView.
761
762SurfaceView is more efficient and provides better performance but has two limitations:
763* It can't be animated, transformed or scaled
764* You can't overlay multiple SurfaceViews
765
766useTextureView can only be set at same time you're setting the source.
767
768* **true (default)** - Use a TextureView
769* **false** - Use a SurfaceView
770
771Platforms: Android ExoPlayer
772
773#### volume
774Adjust the volume.
775* **1.0 (default)** - Play at full volume
776* **0.0** - Mute the audio
777* **Other values** - Reduce volume
778
779Platforms: all
780
781
782### Event props
783
784#### onAudioBecomingNoisy
785Callback function that is called when the audio is about to become 'noisy' due to a change in audio outputs. Typically this is called when audio output is being switched from an external source like headphones back to the internal speaker. It's a good idea to pause the media when this happens so the speaker doesn't start blasting sound.
786
787Payload: none
788
789Platforms: Android ExoPlayer, iOS
790
791#### onBandwidthUpdate
792Callback function that is called when the available bandwidth changes.
793
794Payload:
795
796Property | Type | Description
797--- | --- | ---
798bitrate | number | The estimated bitrate in bits/sec
799
800Example:
801```
802{
803 bitrate: 1000000
804}
805```
806
807Note: On Android ExoPlayer, you must set the [reportBandwidth](#reportbandwidth) prop to enable this event. This is due to the high volume of events generated.
808
809Platforms: Android ExoPlayer
810
811#### onEnd
812Callback function that is called when the player reaches the end of the media.
813
814Payload: none
815
816Platforms: all
817
818#### onExternalPlaybackChange
819Callback function that is called when external playback mode for current playing video has changed. Mostly useful when connecting/disconnecting to Apple TV – it's called on connection/disconnection.
820
821Payload:
822
823Property | Type | Description
824--- | --- | ---
825isExternalPlaybackActive | boolean | Boolean indicating whether external playback mode is active
826
827Example:
828```
829{
830 isExternalPlaybackActive: true
831}
832```
833
834Platforms: iOS
835
836#### onFullscreenPlayerWillPresent
837Callback function that is called when the player is about to enter fullscreen mode.
838
839Payload: none
840
841Platforms: Android ExoPlayer, Android MediaPlayer, iOS
842
843#### onFullscreenPlayerDidPresent
844Callback function that is called when the player has entered fullscreen mode.
845
846Payload: none
847
848Platforms: Android ExoPlayer, Android MediaPlayer, iOS
849
850#### onFullscreenPlayerWillDismiss
851Callback function that is called when the player is about to exit fullscreen mode.
852
853Payload: none
854
855Platforms: Android ExoPlayer, Android MediaPlayer, iOS
856
857#### onFullscreenPlayerDidDismiss
858Callback function that is called when the player has exited fullscreen mode.
859
860Payload: none
861
862Platforms: Android ExoPlayer, Android MediaPlayer, iOS
863
864#### onLoad
865Callback function that is called when the media is loaded and ready to play.
866
867Payload:
868
869Property | Type | Description
870--- | --- | ---
871currentPosition | number | Time in seconds where the media will start
872duration | number | Length of the media in seconds
873naturalSize | object | Properties:<br> * width - Width in pixels that the video was encoded at<br> * height - Height in pixels that the video was encoded at<br> * orientation - "portrait" or "landscape"
874audioTracks | array | An array of audio track info objects with the following properties:<br> * index - Index number<br> * title - Description of the track<br> * language - 2 letter [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) or 3 letter [ISO639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) language code<br> * type - Mime type of track
875textTracks | array | An array of text track info objects with the following properties:<br> * index - Index number<br> * title - Description of the track<br> * language - 2 letter [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) or 3 letter [ISO 639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) language code<br> * type - Mime type of track
876
877Example:
878```
879{
880 canPlaySlowForward: true,
881 canPlayReverse: false,
882 canPlaySlowReverse: false,
883 canPlayFastForward: false,
884 canStepForward: false,
885 canStepBackward: false,
886 currentTime: 0,
887 duration: 5910.208984375,
888 naturalSize: {
889 height: 1080
890 orientation: 'landscape'
891 width: '1920'
892 },
893 audioTracks: [
894 { language: 'es', title: 'Spanish', type: 'audio/mpeg', index: 0 },
895 { language: 'en', title: 'English', type: 'audio/mpeg', index: 1 }
896 ],
897 textTracks: [
898 { title: '#1 French', language: 'fr', index: 0, type: 'text/vtt' },
899 { title: '#2 English CC', language: 'en', index: 1, type: 'text/vtt' },
900 { title: '#3 English Director Commentary', language: 'en', index: 2, type: 'text/vtt' }
901 ]
902}
903```
904
905Platforms: all
906
907#### onLoadStart
908Callback function that is called when the media starts loading.
909
910Payload:
911
912Property | Description
913--- | ---
914isNetwork | boolean | Boolean indicating if the media is being loaded from the network
915type | string | Type of the media. Not available on Windows
916uri | string | URI for the media source. Not available on Windows
917
918Example:
919```
920{
921 isNetwork: true,
922 type: '',
923 uri: 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8'
924}
925```
926
927Platforms: all
928
929#### onProgress
930Callback function that is called every progressUpdateInterval seconds with info about which position the media is currently playing.
931
932Property | Type | Description
933--- | --- | ---
934currentTime | number | Current position in seconds
935playableDuration | number | Position to where the media can be played to using just the buffer in seconds
936seekableDuration | number | Position to where the media can be seeked to in seconds. Typically, the total length of the media
937
938Example:
939```
940{
941 currentTime: 5.2,
942 playableDuration: 34.6,
943 seekableDuration: 888
944}
945```
946
947Platforms: all
948
949#### onSeek
950Callback function that is called when a seek completes.
951
952Payload:
953
954Property | Type | Description
955--- | --- | ---
956currentTime | number | The current time after the seek
957seekTime | number | The requested time
958
959Example:
960```
961{
962 currentTime: 100.5
963 seekTime: 100
964}
965```
966
967Both the currentTime & seekTime are reported because the video player may not seek to the exact requested position in order to improve seek performance.
968
969
970Platforms: Android ExoPlayer, Android MediaPlayer, iOS, Windows UWP
971
972#### onTimedMetadata
973Callback function that is called when timed metadata becomes available
974
975Payload:
976
977Property | Type | Description
978--- | --- | ---
979metadata | array | Array of metadata objects
980
981Example:
982```
983{
984 metadata: [
985 { value: 'Streaming Encoder', identifier: 'TRSN' },
986 { value: 'Internet Stream', identifier: 'TRSO' },
987 { value: 'Any Time You Like', identifier: 'TIT2' }
988 ]
989}
990```
991
992Support for timed metadata on Android MediaPlayer is limited at best and only compatible with some videos. It requires a target SDK of 23 or higher.
993
994Platforms: Android ExoPlayer, Android MediaPlayer, iOS
995
996### Methods
997Methods operate on a ref to the Video element. You can create a ref using code like:
998```
999return (
1000 <Video source={...}
1001 ref => (this.player = ref) />
1002);
1003```
1004
1005#### dismissFullscreenPlayer
1006`dismissFullscreenPlayer()`
1007
1008Take the player out of fullscreen mode.
1009
1010Example:
1011```
1012this.player.dismissFullscreenPlayer();
1013```
1014
1015Platforms: Android ExoPlayer, Android MediaPlayer, iOS
1016
1017#### presentFullscreenPlayer
1018`presentFullscreenPlayer()`
1019
1020Put the player in fullscreen mode.
1021
1022On iOS, this displays the video in a fullscreen view controller with controls.
1023
1024On Android ExoPlayer & MediaPlayer, this puts the navigation controls in fullscreen mode. It is not a complete fullscreen implementation, so you will still need to apply a style that makes the width and height match your screen dimensions to get a fullscreen video.
1025
1026Example:
1027```
1028this.player.presentFullscreenPlayer();
1029```
1030
1031Platforms: Android ExoPlayer, Android MediaPlayer, iOS
1032
1033#### save
1034`save(): Promise`
1035
1036Save video to your Photos with current filter prop. Returns promise.
1037
1038Example:
1039```
1040let response = await this.save();
1041let path = response.uri;
1042```
1043
1044Notes:
1045 - Currently only supports highest quality export
1046 - Currently only supports MP4 export
1047 - Currently only supports exporting to user's cache directory with a generated UUID filename.
1048 - User will need to remove the saved video through their Photos app
1049 - Works with cached videos as well. (Checkout video-caching example)
1050 - If the video is has not began buffering (e.g. there is no internet connection) then the save function will throw an error.
1051 - If the video is buffering then the save function promise will return after the video has finished buffering and processing.
1052
1053Future:
1054 - Will support multiple qualities through options
1055 - Will support more formats in the future through options
1056 - Will support custom directory and file name through options
1057
1058Platforms: iOS
1059
1060#### seek()
1061`seek(seconds)`
1062
1063Seek to the specified position represented by seconds. seconds is a float value.
1064
1065`seek()` can only be called after the `onLoad` event has fired. Once completed, the [onSeek](#onseek) event will be called.
1066
1067Example:
1068```
1069this.player.seek(200); // Seek to 3 minutes, 20 seconds
1070```
1071
1072Platforms: all
1073
1074##### Exact seek
1075
1076By default iOS seeks within 100 milliseconds of the target position. If you need more accuracy, you can use the seek with tolerance method:
1077
1078`seek(seconds, tolerance)`
1079
1080tolerance is the max distance in milliseconds from the seconds position that's allowed. Using a more exact tolerance can cause seeks to take longer. If you want to seek exactly, set tolerance to 0.
1081
1082Example:
1083```
1084this.player.seek(120, 50); // Seek to 2 minutes with +/- 50 milliseconds accuracy
1085```
1086
1087Platforms: iOS
1088
1089
1090
1091
1092### iOS App Transport Security
1093
1094- By default, iOS will only load encrypted (https) urls. If you want to load content from an unencrypted (http) source, you will need to modify your Info.plist file and add the following entry:
1095
1096<img src="./docs/AppTransportSecuritySetting.png" width="50%">
1097
1098For more detailed info check this [article](https://cocoacasts.com/how-to-add-app-transport-security-exception-domains)
1099</details>
1100
1101### Audio Mixing
1102
1103At some point in the future, react-native-video will include an Audio Manager for configuring how videos mix with other apps playing sounds on the device.
1104
1105On iOS, if you would like to allow other apps to play music over your video component, make the following change:
1106
1107**AppDelegate.m**
1108
1109```objective-c
1110#import <AVFoundation/AVFoundation.h> // import
1111
1112- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
1113{
1114 ...
1115 [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil]; // allow
1116 ...
1117}
1118```
1119
1120You can also use the [ignoreSilentSwitch](ignoresilentswitch) prop.
1121</details>
1122
1123### Android Expansion File Usage
1124Expansions files allow you to ship assets that exceed the 100MB apk size limit and don't need to be updated each time you push an app update.
1125
1126This only supports mp4 files and they must not be compressed. Example command line for preventing compression:
1127```bash
1128zip -r -n .mp4 *.mp4 player.video.example.com
1129```
1130
1131```javascript
1132// Within your render function, assuming you have a file called
1133// "background.mp4" in your expansion file. Just add your main and (if applicable) patch version
1134<Video source={{uri: "background", mainVer: 1, patchVer: 0}} // Looks for .mp4 file (background.mp4) in the given expansion version.
1135 resizeMode="cover" // Fill the whole screen at aspect ratio.
1136 style={styles.backgroundVideo} />
1137
1138### Load files with the RN Asset System
1139
1140The asset system [introduced in RN `0.14`](http://www.reactnative.com/react-native-v0-14-0-released/) allows loading image resources shared across iOS and Android without touching native code. As of RN `0.31` [the same is true](https://github.com/facebook/react-native/commit/91ff6868a554c4930fd5fda6ba8044dbd56c8374) of mp4 video assets for Android. As of [RN `0.33`](https://github.com/facebook/react-native/releases/tag/v0.33.0) iOS is also supported. Requires `react-native-video@0.9.0`.
1141
1142```
1143<Video
1144 source={require('../assets/video/turntable.mp4')}
1145/>
1146```
1147
1148### Play in background on iOS
1149
1150To enable audio to play in background on iOS the audio session needs to be set to `AVAudioSessionCategoryPlayback`. See [Apple documentation][3] for additional details. (NOTE: there is now a ticket to [expose this as a prop]( https://github.com/react-native-community/react-native-video/issues/310) )
1151
1152## Examples
1153
1154- See an [Example integration][1] in `react-native-login` *note that this example uses an older version of this library, before we used `export default` -- if you use `require` you will need to do `require('react-native-video').default` as per instructions above.*
1155- Try the included [VideoPlayer example][2] yourself:
1156
1157 ```sh
1158 git clone git@github.com:react-native-community/react-native-video.git
1159 cd react-native-video/example
1160 npm install
1161 open ios/VideoPlayer.xcodeproj
1162
1163 ```
1164
1165 Then `Cmd+R` to start the React Packager, build and run the project in the simulator.
1166
1167- [Lumpen Radio](https://github.com/jhabdas/lumpen-radio) contains another example integration using local files and full screen background video.
1168
1169## Updating
1170
1171### Version 4.0.0
1172
1173#### Gradle 3 and SDK 26 requirement
1174In order to support ExoPlayer 2.9.0, you must use version 3 or higher of the Gradle plugin. This is included by default in React Native 0.57. ExoPlayer
1175
1176#### ExoPlayer 2.9.0 Java 1.8 requirement
1177ExoPlayer 2.9.0 uses some Java 1.8 features, so you may need to enable support for Java 1.8 in your app/build.gradle file. If you get an error, compiling with ExoPlayer like:
1178`Default interface methods are only supported starting with Android N (--min-api 24)`
1179
1180Add the following to your app/build.gradle file:
1181```
1182android {
1183 ... // Various other settings go here
1184 compileOptions {
1185 targetCompatibility JavaVersion.VERSION_1_8
1186 }
1187}
1188```
1189
1190#### ExoPlayer no longer detaches
1191When using a router like the react-navigation TabNavigator, switching between tab routes would previously cause ExoPlayer to detach causing the video player to pause. We now don't detach the view, allowing the video to continue playing in a background tab. This matches the behavior for iOS. Android MediaPlayer will crash if it detaches when switching routes, so its behavior has not been changed.
1192
1193#### useTextureView now defaults to true
1194The SurfaceView, which ExoPlayer has been using by default has a number of quirks that people are unaware of and often cause issues. This includes not supporting animations or scaling. It also causes strange behavior if you overlay two videos on top of each other, because the SurfaceView will [punch a hole](https://developer.android.com/reference/android/view/SurfaceView) through other views. Since TextureView doesn't have these issues and behaves in the way most developers expect, it makes sense to make it the default.
1195
1196TextureView is not as fast as SurfaceView, so you may still want to enable SurfaceView support. To do this, you can set `useTextureView={false}`.
1197
1198
1199### Version 3.0.0
1200
1201#### All platforms now auto-play
1202Previously, on Android ExoPlayer if the paused prop was not set, the media would not automatically start playing. The only way it would work was if you set `paused={false}`. This has been changed to automatically play if paused is not set so that the behavior is consistent across platforms.
1203
1204#### All platforms now keep their paused state when returning from the background
1205Previously, on Android MediaPlayer if you setup an AppState event when the app went into the background and set a paused prop so that when you returned to the app the video would be paused it would be ignored.
1206
1207Note, Windows does not have a concept of an app going into the background, so this doesn't apply there.
1208
1209#### Use Android SDK 27 by default
1210Version 3.0 updates the Android build tools and SDK to version 27. React Native is in the process of [switchting over](https://github.com/facebook/react-native/issues/18095#issuecomment-395596130) to SDK 27 in preparation for Google's requirement that new Android apps [use SDK 26](https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html) by August 2018.
1211
1212You will either need to install the version 27 SDK and version 27.0.3 buildtools or modify your build.gradle file to configure react-native-video to use the same build settings as the rest of your app as described below.
1213
1214##### Using app build settings
1215You will need to create a `project.ext` section in the top-level build.gradle file (not app/build.gradle). Fill in the values from the example below using the values found in your app/build.gradle file.
1216```
1217// Top-level build file where you can add configuration options common to all sub-projects/modules.
1218
1219buildscript {
1220 ... // Various other settings go here
1221}
1222
1223allprojects {
1224 ... // Various other settings go here
1225
1226 project.ext {
1227 compileSdkVersion = 23
1228 buildToolsVersion = "23.0.1"
1229
1230 minSdkVersion = 16
1231 targetSdkVersion = 22
1232 }
1233}
1234```
1235
1236If you encounter an error `Could not find com.android.support:support-annotations:27.0.0.` reinstall your Android Support Repository.
1237
1238## TODOS
1239
1240- [ ] Add support for playing multiple videos in a sequence (will interfere with current `repeat` implementation)
1241- [x] Callback to get buffering progress for remote videos
1242- [ ] Bring API closer to HTML5 `<Video>` [reference](http://devdocs.io/html/element/video)
1243
1244[1]: https://github.com/brentvatne/react-native-login/blob/56c47a5d1e23781e86e19b27e10427fd6391f666/App/Screens/UserInfoScreen.js#L32-L35
1245[2]: https://github.com/react-native-community/react-native-video/tree/master/example
1246[3]: https://developer.apple.com/library/ios/qa/qa1668/_index.html
1247
1248---
1249
1250**MIT Licensed**
1251
\No newline at end of file