Merge branch 'master' into deprecated-prop-types

This commit is contained in:
Eran Hammer 2022-05-04 12:34:28 -07:00 committed by GitHub
commit ec8e7eba11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 1633 additions and 679 deletions

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
examples/

60
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,60 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 60
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 3
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
onlyLabels: []
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- pinned
- security
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: true
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: true
# Set to true to ignore issues with an assignee (defaults to false)
exemptAssignees: true
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions. If you are having a similar problem, please open a
new issue and reference this one instead of commenting on a stale or closed
issue.
# Comment to post when removing the stale label.
unmarkComment: false
# Comment to post when closing a stale Issue or Pull Request.
closeComment: false
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 50
# Limit to only `issues` or `pulls`
only: issues
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
# pulls:
# daysUntilStale: 30
# markComment: >
# This pull request has been automatically marked as stale because it has not had
# recent activity. It will be closed if no further activity occurs. Thank you
# for your contributions.
# issues:
# exemptLabels:
# - confirmed

10
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,10 @@
name: ci
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- run: yarn --no-lockfile
- run: yarn lint

View File

@ -1,8 +1,19 @@
## Changelog
### Version 5.2.1
### Version 6.0.0-alpha1
- Add Google's maven repository to avoid build error [#2552] (https://github.com/react-native-video/react-native-video/pull/2552)
- Add Google's maven repository to avoid build error [#2552](https://github.com/react-native-video/react-native-video/pull/2552)
- Fix iOS 15.4 HLS playback race condition [#2633](https://github.com/react-native-video/react-native-video/pull/2633)
- Add fullscreen support on Android [#2073](https://github.com/react-native-video/react-native-video/pull/2073)
- Fix app crash from NPE in Exoplayer error handler [#2575](https://github.com/react-native-video/react-native-video/pull/2575)
- Fix default closed captioning behavior for Android ExoPlayer [#2181](https://github.com/react-native-video/react-native-video/pull/2181)
- Disable pipController init if pictureInPicture is false [#2645](https://github.com/react-native-video/react-native-video/pull/2645)
- Make sure modifiers are applied before playing [#2395](https://github.com/react-native-video/react-native-video/pull/2395)
- Better support newer versions of RNW (64 and newer) [#2535](https://github.com/react-native-video/react-native-video/pull/2535)
- Fix nil string uri parameter error [#695](https://github.com/react-native-video/react-native-video/pull/695)
- (Breaking) Bump shaka-player to 3.3.2 [#2587](https://github.com/react-native-video/react-native-video/pull/2587)
- Improve basic player example on android [#2662](https://github.com/react-native-video/react-native-video/pull/2662)
- Ensure we always use `hideShutterView` before showing the `shutterView` on Android [#2609](https://github.com/react-native-video/react-native-video/pull/2609)
### Version 5.2.0

View File

@ -2,5 +2,5 @@ export default {
WIDEVINE: 'widevine',
PLAYREADY: 'playready',
CLEARKEY: 'clearkey',
FAIRPLAY: 'fairplay'
FAIRPLAY: 'fairplay',
};

170
README.md
View File

@ -1,5 +1,7 @@
## react-native-video
[![ci][4]][5]
A `<Video>` component for react-native, as seen in
[react-native-login](https://github.com/brentvatne/react-native-login)!
@ -101,11 +103,11 @@ First select your project in Xcode.
<img src="./docs/tvOS-step-1.jpg" width="40%">
After that, select the tvOS target of your application and select « General » tab
After that, select the tvOS target of your application and select « General » tab
<img src="./docs/tvOS-step-2.jpg" width="40%">
Scroll to « Linked Frameworks and Libraries » and tap on the + button
Scroll to « Linked Frameworks and Libraries » and tap on the + button
<img src="./docs/tvOS-step-3.jpg" width="40%">
@ -287,74 +289,84 @@ var styles = StyleSheet.create({
```
### Configurable props
* [allowsExternalPlayback](#allowsexternalplayback)
* [audioOnly](#audioonly)
* [automaticallyWaitsToMinimizeStalling](#automaticallyWaitsToMinimizeStalling)
* [bufferConfig](#bufferconfig)
* [controls](#controls)
* [currentPlaybackTime](#currentPlaybackTime)
* [disableFocus](#disableFocus)
* [filter](#filter)
* [filterEnabled](#filterEnabled)
* [fullscreen](#fullscreen)
* [fullscreenAutorotate](#fullscreenautorotate)
* [fullscreenOrientation](#fullscreenorientation)
* [headers](#headers)
* [hideShutterView](#hideshutterview)
* [id](#id)
* [ignoreSilentSwitch](#ignoresilentswitch)
* [maxBitRate](#maxbitrate)
* [minLoadRetryCount](#minLoadRetryCount)
* [mixWithOthers](#mixWithOthers)
* [muted](#muted)
* [paused](#paused)
* [pictureInPicture](#pictureinpicture)
* [playInBackground](#playinbackground)
* [playWhenInactive](#playwheninactive)
* [poster](#poster)
* [posterResizeMode](#posterresizemode)
* [preferredForwardBufferDuration](#preferredForwardBufferDuration)
* [preventsDisplaySleepDuringVideoPlayback](#preventsDisplaySleepDuringVideoPlayback)
* [progressUpdateInterval](#progressupdateinterval)
* [rate](#rate)
* [repeat](#repeat)
* [reportBandwidth](#reportbandwidth)
* [resizeMode](#resizemode)
* [selectedAudioTrack](#selectedaudiotrack)
* [selectedTextTrack](#selectedtexttrack)
* [selectedVideoTrack](#selectedvideotrack)
* [source](#source)
* [stereoPan](#stereopan)
* [textTracks](#texttracks)
* [trackId](#trackId)
* [useTextureView](#usetextureview)
* [volume](#volume)
| Name |Plateforms Support |
|--|--|
|[allowsExternalPlayback](#allowsexternalplayback) |iOS |
|[audioOnly](#audioonly)|All |
|[automaticallyWaitsToMinimizeStalling](#automaticallyWaitsToMinimizeStalling) | iOS|
|[bufferConfig](#bufferconfig)|Android ExoPlayer|
|[controls](#controls)|Android ExoPlayer, iOS, react-native-dom|
|[currentPlaybackTime](#currentPlaybackTime)|Android Exoplayer|
|[disableFocus](#disableFocus)|Android Exoplayer, iOS|
|[filter](#filter)|iOS|
|[filterEnabled](#filterEnabled)|iOS|
|[fullscreen](#fullscreen)|iOS|
|[fullscreenAutorotate](#fullscreenautorotate)|iOS|
|[fullscreenOrientation](#fullscreenorientation)|iOS|
|[headers](#headers)|Android ExoPlayer|
|[hideShutterView](#hideshutterview)|Android ExoPlayer|
|[id](#id)|react-native-dom|
|[ignoreSilentSwitch](#ignoresilentswitch)|iOS|
|[maxBitRate](#maxbitrate)|Android ExoPlayer, iOS|
|[minLoadRetryCount](#minLoadRetryCount)|Android ExoPlayer|
|[mixWithOthers](#mixWithOthers)|iOS|
|[muted](#muted)|All|
|[paused](#paused)|All|
|[pictureInPicture](#pictureinpicture)|iOS|
|[playInBackground](#playinbackground)|Android ExoPlayer, Android MediaPlayer, iOS|
|[playWhenInactive](#playwheninactive)|iOS|
|[poster](#poster)|All|
|[posterResizeMode](#posterresizemode)|All|
|[preferredForwardBufferDuration](#preferredForwardBufferDuration)|iOS|
| [preventsDisplaySleepDuringVideoPlayback](#preventsDisplaySleepDuringVideoPlayback)|iOS, Android|
|[progressUpdateInterval](#progressupdateinterval)|All|
|[rate](#rate)|All|
|[repeat](#repeat)|All|
|[reportBandwidth](#reportbandwidth)|Android ExoPlayer|
|[resizeMode](#resizemode)|Android ExoPlayer, Android MediaPlayer, iOS, Windows UWP|
|[selectedAudioTrack](#selectedaudiotrack)|Android ExoPlayer, iOS|
|[selectedTextTrack](#selectedtexttrack)|Android ExoPlayer, iOS|
|[selectedVideoTrack](#selectedvideotrack)|Android ExoPlayer|
|[source](#source)|All|
|[stereoPan](#stereopan)|Android MediaPlayer|
|[textTracks](#texttracks)|Android ExoPlayer, iOS|
|[trackId](#trackId)|Android ExoPlayer|
|[useTextureView](#usetextureview)|Android ExoPlayer|
|[volume](#volume)|All|
### Event props
* [onAudioBecomingNoisy](#onaudiobecomingnoisy)
* [onBandwidthUpdate](#onbandwidthupdate)
* [onEnd](#onend)
* [onExternalPlaybackChange](#onexternalplaybackchange)
* [onFullscreenPlayerWillPresent](#onfullscreenplayerwillpresent)
* [onFullscreenPlayerDidPresent](#onfullscreenplayerdidpresent)
* [onFullscreenPlayerWillDismiss](#onfullscreenplayerwilldismiss)
* [onFullscreenPlayerDidDismiss](#onfullscreenplayerdiddismiss)
* [onLoad](#onload)
* [onLoadStart](#onloadstart)
* [onReadyForDisplay](#onreadyfordisplay)
* [onPictureInPictureStatusChanged](#onpictureinpicturestatuschanged)
* [onPlaybackRateChange](#onplaybackratechange)
* [onProgress](#onprogress)
* [onSeek](#onseek)
* [onRestoreUserInterfaceForPictureInPictureStop](#onrestoreuserinterfaceforpictureinpicturestop)
* [onTimedMetadata](#ontimedmetadata)
| Name |Plateforms Support |
|--|--|
|[onAudioBecomingNoisy](#onaudiobecomingnoisy)|Android ExoPlayer, iOS|
|[onBandwidthUpdate](#onbandwidthupdate)|Android ExoPlayer|
|[onBuffer](#onbuffer)|Android ExoPlayer, iOS|
|[onEnd](#onend)|All|
|[onExternalPlaybackChange](#onexternalplaybackchange)|iOS|
|[onFullscreenPlayerWillPresent](#onfullscreenplayerwillpresent)|Android ExoPlayer, Android MediaPlayer, iOS|
|[onFullscreenPlayerDidPresent](#onfullscreenplayerdidpresent)|Android ExoPlayer, Android MediaPlayer, iOS|
|[onFullscreenPlayerWillDismiss](#onfullscreenplayerwilldismiss)|Android ExoPlayer, Android MediaPlayer, iOS|
|[onFullscreenPlayerDidDismiss](#onfullscreenplayerdiddismiss)|Android ExoPlayer, Android MediaPlayer, iOS|
|[onLoad](#onload)|All|
|[onLoadStart](#onloadstart)|All|
|[onReadyForDisplay](#onreadyfordisplay)|Android ExoPlayer, Android MediaPlayer, iOS, Web|
|[onPictureInPictureStatusChanged](#onpictureinpicturestatuschanged)|iOS|
|[onPlaybackRateChange](#onplaybackratechange)|All|
|[onProgress](#onprogress)|All|
|[onSeek](#onseek)|Android ExoPlayer, Android MediaPlayer, iOS, Windows UWP|
|[onRestoreUserInterfaceForPictureInPictureStop](#onrestoreuserinterfaceforpictureinpicturestop)|iOS|
|[onTimedMetadata](#ontimedmetadata)|Android ExoPlayer, Android MediaPlayer, iOS|
### Methods
* [dismissFullscreenPlayer](#dismissfullscreenplayer)
* [presentFullscreenPlayer](#presentfullscreenplayer)
* [save](#save)
* [restoreUserInterfaceForPictureInPictureStop](#restoreuserinterfaceforpictureinpicturestop)
* [seek](#seek)
| Name |Plateforms Support |
|--|--|
|[dismissFullscreenPlayer](#dismissfullscreenplayer)|Android ExoPlayer, Android MediaPlayer, iOS|
|[presentFullscreenPlayer](#presentfullscreenplayer)|Android ExoPlayer, Android MediaPlayer, iOS|
|[save](#save)|iOS|
|[restoreUserInterfaceForPictureInPictureStop](#restoreuserinterfaceforpictureinpicturestop)|iOS|
|[seek](#seek)|All|
### Configurable props
@ -489,7 +501,7 @@ Platforms: iOS
* **landscape**
* **portrait**
Platforms: iOS
Platforms: Android ExoPlayer, iOS
#### headers
Pass headers to the HTTP client. Can be used for authorization. Headers must be a part of the source object.
@ -944,6 +956,24 @@ Note: On Android ExoPlayer, you must set the [reportBandwidth](#reportbandwidth)
Platforms: Android ExoPlayer
#### onBuffer
Callback function that is called when the player buffers.
Payload:
Property | Type | Description
--- | --- | ---
isBuffering | boolean | Boolean indicating whether buffering is active
Example:
```
{
isBuffering: true
}
```
Platforms: Android ExoPlayer, iOS
#### onEnd
Callback function that is called when the player reaches the end of the media.
@ -1113,7 +1143,7 @@ Platforms: all
#### onProgress
Callback function that is called every progressUpdateInterval seconds with info about which position the media is currently playing.
Callback function that is called every progressUpdateInterval milliseconds with info about which position the media is currently playing.
Property | Type | Description
--- | --- | ---
@ -1480,8 +1510,10 @@ If you encounter an error `Could not find com.android.support:support-annotation
- [ ] Bring API closer to HTML5 `<Video>` [reference](http://devdocs.io/html/element/video)
[1]: https://github.com/brentvatne/react-native-login/blob/56c47a5d1e23781e86e19b27e10427fd6391f666/App/Screens/UserInfoScreen.js#L32-L35
[2]: https://github.com/react-native-community/react-native-video/tree/master/example
[2]: https://github.com/react-native-video/react-native-video/tree/master/examples
[3]: https://developer.apple.com/library/ios/qa/qa1668/_index.html
[4]: https://github.com/react-native-video/react-native-video/workflows/ci/badge.svg
[5]: https://github.com/react-native-video/react-native-video/actions
---

View File

@ -1,6 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { StyleSheet, requireNativeComponent, NativeModules, View, Image, Platform, findNodeHandle } from 'react-native';
import { StyleSheet, requireNativeComponent, NativeModules, UIManager, View, Image, Platform, findNodeHandle } from 'react-native';
import { ViewPropTypes } from "deprecated-react-native-prop-types";
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
import TextTrackType from './TextTrackType';
@ -250,15 +250,15 @@ export default class Video extends Component {
NativeModules.VideoManager.setLicenseError && NativeModules.VideoManager.setLicenseError(error, findNodeHandle(this._root));
});
} else {
NativeModules.VideoManager.setLicenseError && NativeModules.VideoManager.setLicenseError("No spc received", findNodeHandle(this._root));
NativeModules.VideoManager.setLicenseError && NativeModules.VideoManager.setLicenseError('No spc received', findNodeHandle(this._root));
}
}
}
getViewManagerConfig = viewManagerName => {
if (!NativeModules.UIManager.getViewManagerConfig) {
return NativeModules.UIManager[viewManagerName];
if (!UIManager.getViewManagerConfig) {
return UIManager[viewManagerName];
}
return NativeModules.UIManager.getViewManagerConfig(viewManagerName);
return UIManager.getViewManagerConfig(viewManagerName);
};
render() {
@ -269,6 +269,8 @@ export default class Video extends Component {
let uri = source.uri || '';
if (uri && uri.match(/^\//)) {
uri = `file://${uri}`;
} else if (uri === '') {
return null;
}
if (!uri) {
@ -404,7 +406,7 @@ Video.propTypes = {
]),
drm: PropTypes.shape({
type: PropTypes.oneOf([
DRMType.CLEARKEY, DRMType.FAIRPLAY, DRMType.WIDEVINE, DRMType.PLAYREADY
DRMType.CLEARKEY, DRMType.FAIRPLAY, DRMType.WIDEVINE, DRMType.PLAYREADY,
]),
licenseServer: PropTypes.string,
headers: PropTypes.shape({}),

View File

@ -1,3 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.brentvatne.react">
<application>
<activity
android:name="com.brentvatne.exoplayer.ExoPlayerFullscreenVideoActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTop" />
</application>
</manifest>

View File

@ -0,0 +1,155 @@
package com.brentvatne.exoplayer;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import com.brentvatne.react.R;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.ui.PlayerControlView;
public class ExoPlayerFullscreenVideoActivity extends AppCompatActivity implements ReactExoplayerView.FullScreenDelegate {
public static final String EXTRA_EXO_PLAYER_VIEW_ID = "extra_id";
public static final String EXTRA_ORIENTATION = "extra_orientation";
private ReactExoplayerView exoplayerView;
private PlayerControlView playerControlView;
private SimpleExoPlayer player;
@Override
public void onCreate(Bundle savedInstanceState) {
int exoplayerViewId = getIntent().getIntExtra(EXTRA_EXO_PLAYER_VIEW_ID, -1);
exoplayerView = ReactExoplayerView.getViewInstance(exoplayerViewId);
if (exoplayerView == null) {
finish();
return;
}
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
String orientation = getIntent().getStringExtra(EXTRA_ORIENTATION);
if ("landscape".equals(orientation)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
} else if ("portrait".equals(orientation)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
setContentView(R.layout.exo_player_fullscreen_video);
player = exoplayerView.getPlayer();
ExoPlayerView playerView = findViewById(R.id.player_view);
playerView.setPlayer(player);
playerView.setOnClickListener(v -> togglePlayerControlVisibility());
playerControlView = findViewById(R.id.player_controls);
playerControlView.setPlayer(player);
// Set the fullscreen button to "close fullscreen" icon
ImageView fullscreenIcon = playerControlView.findViewById(R.id.exo_fullscreen_icon);
fullscreenIcon.setImageResource(R.drawable.exo_controls_fullscreen_exit);
playerControlView.findViewById(R.id.exo_fullscreen_button)
.setOnClickListener(v -> {
if (exoplayerView != null) {
exoplayerView.setFullscreen(false);
}
});
//Handling the playButton click event
playerControlView.findViewById(R.id.exo_play).setOnClickListener(v -> {
if (player != null && player.getPlaybackState() == Player.STATE_ENDED) {
player.seekTo(0);
}
if (exoplayerView != null) {
exoplayerView.setPausedModifier(false);
}
});
//Handling the pauseButton click event
playerControlView.findViewById(R.id.exo_pause).setOnClickListener(v -> {
if (exoplayerView != null) {
exoplayerView.setPausedModifier(true);
}
});
}
@Override
public void onResume() {
super.onResume();
if (exoplayerView != null) {
exoplayerView.syncPlayerState();
exoplayerView.registerFullScreenDelegate(this);
}
}
@Override
public void onPause() {
super.onPause();
player.setPlayWhenReady(false);
if (exoplayerView != null) {
exoplayerView.registerFullScreenDelegate(null);
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
playerControlView.postDelayed(this::hideSystemUI, 200);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
if (exoplayerView != null) {
exoplayerView.setFullscreen(false);
return false;
}
return true;
}
return super.onKeyDown(keyCode, event);
}
private void togglePlayerControlVisibility() {
if (playerControlView.isVisible()) {
playerControlView.hide();
} else {
playerControlView.show();
}
}
/**
* Enables regular immersive mode.
*/
private void hideSystemUI() {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Hide the nav bar and status bar
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
}
/**
* Shows the system bars by removing all the flags
* except for the ones that make the content appear under the system bars.
*/
private void showSystemUI() {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
@Override
public void closeFullScreen() {
finish();
}
}

View File

@ -129,9 +129,6 @@ public final class ExoPlayerView extends FrameLayout {
* @param player The {@link SimpleExoPlayer} to use.
*/
public void setPlayer(SimpleExoPlayer player) {
if (this.player == player) {
return;
}
if (this.player != null) {
this.player.removeTextOutput(componentListener);
this.player.removeVideoListener(componentListener);
@ -139,7 +136,7 @@ public final class ExoPlayerView extends FrameLayout {
clearVideoView();
}
this.player = player;
shutterView.setVisibility(VISIBLE);
shutterView.setVisibility(this.hideShutterView ? View.INVISIBLE : View.VISIBLE);
if (player != null) {
setVideoView();
player.addVideoListener(componentListener);
@ -206,7 +203,7 @@ public final class ExoPlayerView extends FrameLayout {
}
}
// Video disabled so the shutter must be closed.
shutterView.setVisibility(VISIBLE);
shutterView.setVisibility(this.hideShutterView ? View.INVISIBLE : View.VISIBLE);
}
public void invalidateAspectRatio() {

View File

@ -1,8 +1,8 @@
package com.brentvatne.exoplayer;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Handler;
@ -10,7 +10,6 @@ import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.accessibility.CaptioningManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;
@ -30,7 +29,6 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
@ -39,7 +37,6 @@ import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
import com.google.android.exoplayer2.drm.FrameworkMediaDrm;
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
import com.google.android.exoplayer2.drm.UnsupportedDrmException;
@ -61,8 +58,8 @@ import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.PlayerControlView;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
@ -76,9 +73,10 @@ import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.UUID;
import java.util.Map;
import java.util.UUID;
@SuppressLint("ViewConstructor")
class ReactExoplayerView extends FrameLayout implements
@ -100,6 +98,9 @@ class ReactExoplayerView extends FrameLayout implements
DEFAULT_COOKIE_MANAGER.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
}
private static Map<Integer, ReactExoplayerView> instances = new HashMap<>();
private FullScreenDelegate fullScreenDelegate;
private final VideoEventEmitter eventEmitter;
private final ReactExoplayerConfig config;
private final DefaultBandwidthMeter bandwidthMeter;
@ -118,7 +119,9 @@ class ReactExoplayerView extends FrameLayout implements
private long resumePosition;
private boolean loadVideoStarted;
private boolean isFullscreen;
private String fullScreenOrientation;
private boolean isInBackground;
private boolean isInFullscreen;
private boolean isPaused;
private boolean isBuffering;
private boolean muted = false;
@ -134,8 +137,6 @@ class ReactExoplayerView extends FrameLayout implements
private int bufferForPlaybackMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS;
private int bufferForPlaybackAfterRebufferMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS;
private Handler mainHandler;
// Props from React
private Uri srcUri;
private String extension;
@ -202,7 +203,6 @@ class ReactExoplayerView extends FrameLayout implements
createViews();
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
themedReactContext.addLifecycleEventListener(this);
audioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver(themedReactContext);
}
@ -227,8 +227,6 @@ class ReactExoplayerView extends FrameLayout implements
exoPlayerView.setLayoutParams(layoutParams);
addView(exoPlayerView, 0, layoutParams);
mainHandler = new Handler();
}
@Override
@ -251,7 +249,15 @@ class ReactExoplayerView extends FrameLayout implements
@Override
public void onHostResume() {
if (!playInBackground || !isInBackground) {
setPlayWhenReady(!isPaused);
if (isInFullscreen) {
if (player != null) {
exoPlayerView.setPlayer(player);
syncPlayerState();
}
isInFullscreen = false;
} else {
setPlayWhenReady(!isPaused);
}
}
isInBackground = false;
}
@ -272,6 +278,7 @@ class ReactExoplayerView extends FrameLayout implements
public void cleanUpResources() {
stopPlayback();
instances.remove(this.getId());
}
//BandwidthMeter.EventListener implementation
@ -290,6 +297,29 @@ class ReactExoplayerView extends FrameLayout implements
}
}
public static ReactExoplayerView getViewInstance(Integer uid) {
return instances.get(uid);
}
public SimpleExoPlayer getPlayer() {
return player;
}
public void syncPlayerState() {
if (player == null) return;
if (player.getPlaybackState() == Player.STATE_ENDED) {
// Try to get last frame displayed
player.seekTo(player.getDuration() - 200);
player.setPlayWhenReady(true);
} else {
player.setPlayWhenReady(!isPaused);
}
}
public void registerFullScreenDelegate(FullScreenDelegate delegate) {
this.fullScreenDelegate = delegate;
}
// Internal methods
/**
@ -305,6 +335,15 @@ class ReactExoplayerView extends FrameLayout implements
}
}
private void showFullscreen() {
instances.put(this.getId(), this);
Intent intent = new Intent(getContext(), ExoPlayerFullscreenVideoActivity.class);
intent.putExtra(ExoPlayerFullscreenVideoActivity.EXTRA_EXO_PLAYER_VIEW_ID, this.getId());
intent.putExtra(ExoPlayerFullscreenVideoActivity.EXTRA_ORIENTATION, this.fullScreenOrientation);
getContext().startActivity(intent);
isInFullscreen = true;
}
/**
* Initializing Player control
*/
@ -317,6 +356,7 @@ class ReactExoplayerView extends FrameLayout implements
playerControlView.setPlayer(player);
playerControlView.show();
playPauseControlContainer = playerControlView.findViewById(R.id.exo_play_pause_container);
playerControlView.findViewById(R.id.exo_fullscreen_button).setOnClickListener(v -> setFullscreen(true));
// Invoking onClick event for exoplayerView
exoPlayerView.setOnClickListener(new OnClickListener() {
@ -389,6 +429,7 @@ class ReactExoplayerView extends FrameLayout implements
}
private void initializePlayer() {
themedReactContext.addLifecycleEventListener(this);
ReactExoplayerView self = this;
// This ensures all props have been settled, to avoid async racing conditions.
new Handler().postDelayed(new Runnable() {
@ -411,7 +452,7 @@ class ReactExoplayerView extends FrameLayout implements
new DefaultRenderersFactory(getContext())
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF);
player = new SimpleExoPlayer.Builder(getContext(), renderersFactory)
.setTrackSelector(trackSelector)
.setTrackSelector(trackSelector)
.setBandwidthMeter(bandwidthMeter)
.setLoadControl(defaultLoadControl)
.build();
@ -641,9 +682,6 @@ class ReactExoplayerView extends FrameLayout implements
}
private void onStopPlayback() {
if (isFullscreen) {
setFullscreen(false);
}
audioManager.abandonAudioFocus(this);
}
@ -947,7 +985,8 @@ class ReactExoplayerView extends FrameLayout implements
// Special case for decoder initialization failures.
MediaCodecRenderer.DecoderInitializationException decoderInitializationException =
(MediaCodecRenderer.DecoderInitializationException) cause;
if (decoderInitializationException.codecInfo.name == null) {
if (decoderInitializationException.codecInfo == null
|| decoderInitializationException.codecInfo.name == null) {
if (decoderInitializationException.getCause() instanceof MediaCodecUtil.DecoderQueryException) {
errorString = getResources().getString(R.string.error_querying_decoders);
} else if (decoderInitializationException.secureDecoderRequired) {
@ -1155,7 +1194,7 @@ class ReactExoplayerView extends FrameLayout implements
}
}
}
} else if (rendererIndex == C.TRACK_TYPE_TEXT && Util.SDK_INT > 18) { // Text default
} else if (trackType == C.TRACK_TYPE_TEXT && Util.SDK_INT > 18) { // Text default
// Use system settings if possible
CaptioningManager captioningManager
= (CaptioningManager)themedReactContext.getSystemService(Context.CAPTIONING_SERVICE);
@ -1297,34 +1336,23 @@ class ReactExoplayerView extends FrameLayout implements
return; // Avoid generating events when nothing is changing
}
isFullscreen = fullscreen;
Activity activity = themedReactContext.getCurrentActivity();
if (activity == null) {
return;
}
Window window = activity.getWindow();
View decorView = window.getDecorView();
int uiOptions;
if (isFullscreen) {
if (Util.SDK_INT >= 19) { // 4.4+
uiOptions = SYSTEM_UI_FLAG_HIDE_NAVIGATION
| SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| SYSTEM_UI_FLAG_FULLSCREEN;
} else {
uiOptions = SYSTEM_UI_FLAG_HIDE_NAVIGATION
| SYSTEM_UI_FLAG_FULLSCREEN;
}
eventEmitter.fullscreenWillPresent();
decorView.setSystemUiVisibility(uiOptions);
showFullscreen();
eventEmitter.fullscreenDidPresent();
} else {
uiOptions = View.SYSTEM_UI_FLAG_VISIBLE;
eventEmitter.fullscreenWillDismiss();
decorView.setSystemUiVisibility(uiOptions);
if (fullScreenDelegate != null) {
fullScreenDelegate.closeFullScreen();
}
eventEmitter.fullscreenDidDismiss();
}
}
public void setFullscreenOrientation(String orientation) {
this.fullScreenOrientation = orientation;
}
public void setUseTextureView(boolean useTextureView) {
boolean finallyUseTextureView = useTextureView && this.drmUUID == null;
exoPlayerView.setUseTextureView(finallyUseTextureView);
@ -1394,4 +1422,8 @@ class ReactExoplayerView extends FrameLayout implements
}
}
}
public interface FullScreenDelegate {
void closeFullScreen();
}
}

View File

@ -64,6 +64,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_PLAY_IN_BACKGROUND = "playInBackground";
private static final String PROP_DISABLE_FOCUS = "disableFocus";
private static final String PROP_FULLSCREEN = "fullscreen";
private static final String PROP_FULLSCREEN_ORIENTATION = "fullscreenOrientation";
private static final String PROP_USE_TEXTURE_VIEW = "useTextureView";
private static final String PROP_SELECTED_VIDEO_TRACK = "selectedVideoTrack";
private static final String PROP_SELECTED_VIDEO_TRACK_TYPE = "type";
@ -299,6 +300,11 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
videoView.setFullscreen(fullscreen);
}
@ReactProp(name = PROP_FULLSCREEN_ORIENTATION)
public void setFullscreenOrientation(final ReactExoplayerView videoView, final String fullscreenOrientation) {
videoView.setFullscreenOrientation(fullscreenOrientation);
}
@ReactProp(name = PROP_USE_TEXTURE_VIEW, defaultBoolean = true)
public void setUseTextureView(final ReactExoplayerView videoView, final boolean useTextureView) {
videoView.setUseTextureView(useTextureView);

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
@ -71,6 +72,22 @@
android:paddingRight="4dp"
android:includeFontPadding="false"
android:textColor="#FFBEBEBE"/>
</LinearLayout>
<FrameLayout
android:id="@+id/exo_fullscreen_button"
android:layout_width="32dp"
android:layout_height="wrap_content"
android:layout_gravity="right">
<ImageView
android:id="@+id/exo_fullscreen_icon"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
app:srcCompat="@drawable/exo_controls_fullscreen_enter" />
</FrameLayout>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/enclosing_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black">
<com.brentvatne.exoplayer.ExoPlayerView
android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.exoplayer2.ui.PlayerControlView
android:id="@+id/player_controls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
</FrameLayout>

View File

@ -1,3 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.brentvatne.react">
package="com.brentvatne.react">
</manifest>

View File

@ -1,9 +0,0 @@
MIT License
Copyright (c) 2018 Vincent Riemer
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,11 +1,13 @@
// @flow
import { RCTEvent, RCTView, type RCTBridge } from "react-native-dom";
import shaka from "shaka-player";
/* eslint-env browser */
import resizeModes from "./resizeModes";
import type { VideoSource } from "./types";
import RCTVideoEvent from "./RCTVideoEvent";
import { RCTView, type RCTBridge } from 'react-native-dom';
import shaka from 'shaka-player';
import resizeModes from './resizeModes';
import type { VideoSource } from './types';
import RCTVideoEvent from './RCTVideoEvent';
class RCTVideo extends RCTView {
playPromise: Promise<void> = Promise.resolve();
@ -24,7 +26,7 @@ class RCTVideo extends RCTView {
constructor(bridge: RCTBridge) {
super(bridge);
this.eventDispatcher = bridge.getModuleByName("EventDispatcher");
this.eventDispatcher = bridge.getModuleByName('EventDispatcher');
shaka.polyfill.installAll();
@ -35,12 +37,12 @@ class RCTVideo extends RCTView {
this.onProgress = this.onProgress.bind(this);
this.videoElement = this.initializeVideoElement();
this.videoElement.addEventListener("ended", this.onEnd);
this.videoElement.addEventListener("loadeddata", this.onLoad);
this.videoElement.addEventListener("canplay", this.onReadyForDisplay);
this.videoElement.addEventListener("loadstart", this.onLoadStart);
this.videoElement.addEventListener("pause", this.onPause);
this.videoElement.addEventListener("play", this.onPlay);
this.videoElement.addEventListener('ended', this.onEnd);
this.videoElement.addEventListener('loadeddata', this.onLoad);
this.videoElement.addEventListener('canplay', this.onReadyForDisplay);
this.videoElement.addEventListener('loadstart', this.onLoadStart);
this.videoElement.addEventListener('pause', this.onPause);
this.videoElement.addEventListener('play', this.onPlay);
this.player = new shaka.Player(this.videoElement);
this.muted = false;
@ -50,26 +52,26 @@ class RCTVideo extends RCTView {
}
detachFromView(view: UIView) {
this.videoElement.removeEventListener("ended", this.onEnd);
this.videoElement.removeEventListener("loadeddata", this.onLoad);
this.videoElement.removeEventListener("canplay", this.onReadyForDisplay);
this.videoElement.removeEventListener("loadstart", this.onLoadStart);
this.videoElement.removeEventListener("pause", this.onPause);
this.videoElement.removeEventListener("play", this.onPlay);
this.videoElement.removeEventListener('ended', this.onEnd);
this.videoElement.removeEventListener('loadeddata', this.onLoad);
this.videoElement.removeEventListener('canplay', this.onReadyForDisplay);
this.videoElement.removeEventListener('loadstart', this.onLoadStart);
this.videoElement.removeEventListener('pause', this.onPause);
this.videoElement.removeEventListener('play', this.onPlay);
this.stopProgressTimer();
}
initializeVideoElement() {
const elem = document.createElement("video");
const elem = document.createElement('video');
Object.assign(elem.style, {
display: "block",
position: "absolute",
top: "0",
left: "0",
width: "100%",
height: "100%"
display: 'block',
position: 'absolute',
top: '0',
left: '0',
width: '100%',
height: '100%',
});
return elem;
@ -81,7 +83,7 @@ class RCTVideo extends RCTView {
set controls(value: boolean) {
this.videoElement.controls = value;
this.videoElement.style.pointerEvents = value ? "auto" : "";
this.videoElement.style.pointerEvents = value ? 'auto' : '';
}
set id(value: string) {
@ -121,19 +123,19 @@ class RCTVideo extends RCTView {
set resizeMode(value: number) {
switch (value) {
case resizeModes.ScaleNone: {
this.videoElement.style.objectFit = "none";
this.videoElement.style.objectFit = 'none';
break;
}
case resizeModes.ScaleToFill: {
this.videoElement.style.objectFit = "fill";
this.videoElement.style.objectFit = 'fill';
break;
}
case resizeModes.ScaleAspectFit: {
this.videoElement.style.objectFit = "contain";
this.videoElement.style.objectFit = 'contain';
break;
}
case resizeModes.ScaleAspectFill: {
this.videoElement.style.objectFit = "cover";
this.videoElement.style.objectFit = 'cover';
break;
}
}
@ -146,16 +148,16 @@ class RCTVideo extends RCTView {
set source(value: VideoSource) {
let uri = value.uri;
if (uri.startsWith("blob:")) {
if (uri.startsWith('blob:')) {
let blob = this.bridge.blobManager.resolveURL(uri);
if (blob.type === "text/xml") {
blob = new Blob([blob], { type: "video/mp4" });
if (blob.type === 'text/xml') {
blob = new Blob([blob], { type: 'video/mp4' });
}
uri = URL.createObjectURL(blob);
}
if (!shaka.Player.isBrowserSupported()) { // primarily iOS WebKit
this.videoElement.setAttribute("src", uri);
this.videoElement.setAttribute('src', uri);
if (!this._paused) {
this.requestPlay();
}
@ -181,12 +183,12 @@ class RCTVideo extends RCTView {
onEnd = () => {
this.onProgress();
this.sendEvent("topVideoEnd", null);
this.stopProgressTimer();
this.sendEvent('topVideoEnd', null);
this.stopProgressTimer();
}
onError = error => {
console.warn("topVideoError", error);
console.warn('topVideoError', error);
}
onLoad = () => {
@ -199,23 +201,23 @@ class RCTVideo extends RCTView {
naturalSize: {
width,
height,
orientation: width >= height ? "landscape" : "portrait"
}
orientation: width >= height ? 'landscape' : 'portrait',
},
};
this.sendEvent("topVideoLoad", payload);
this.sendEvent('topVideoLoad', payload);
}
onReadyForDisplay = () => {
this.sendEvent("onReadyForDisplay");
this.sendEvent('onReadyForDisplay');
}
onLoadStart = () => {
const src = this.videoElement.currentSrc;
const payload = {
isNetwork: !src.match(/^https?:\/\/localhost/), // require is served from localhost
uri: this.videoElement.currentSrc
uri: this.videoElement.currentSrc,
};
this.sendEvent("topVideoLoadStart", payload);
this.sendEvent('topVideoLoadStart', payload);
}
onPause = () => {
@ -229,13 +231,13 @@ class RCTVideo extends RCTView {
onProgress = () => {
const payload = {
currentTime: this.videoElement.currentTime,
seekableDuration: this.videoElement.duration
seekableDuration: this.videoElement.duration,
};
this.sendEvent("topVideoProgress", payload);
this.sendEvent('topVideoProgress', payload);
}
onRejectedAutoplay = () => {
this.sendEvent("topVideoRejectedAutoplay", null);
this.sendEvent('topVideoRejectedAutoplay', null);
}
requestPlay() {
@ -273,6 +275,6 @@ class RCTVideo extends RCTView {
}
}
customElements.define("rct-video", RCTVideo);
customElements.define('rct-video', RCTVideo);
export default RCTVideo;

View File

@ -4,10 +4,10 @@ interface RCTEvent {
viewTag: number;
eventName: string;
coalescingKey: number;
canCoalesce(): boolean;
coalesceWithEvent(event: RCTEvent): RCTEvent;
moduleDotMethod(): string;
arguments(): Array<any>;
}
@ -38,14 +38,14 @@ export default class RCTVideoEvent implements RCTEvent {
}
moduleDotMethod(): string {
return "RCTEventEmitter.receiveEvent";
return 'RCTEventEmitter.receiveEvent';
}
arguments(): Array<any> {
const args = [
this.viewTag,
this.eventName,
this.data
this.data,
];
return args;
}

View File

@ -1,14 +1,14 @@
// @flow
import { RCTViewManager } from "react-native-dom";
import { RCTViewManager } from 'react-native-dom';
import RCTVideo from "./RCTVideo";
import resizeModes from "./resizeModes";
import RCTVideo from './RCTVideo';
import resizeModes from './resizeModes';
import type { VideoSource } from "./types";
import type { VideoSource } from './types';
class RCTVideoManager extends RCTViewManager {
static moduleName = "RCTVideoManager";
static moduleName = 'RCTVideoManager';
view() {
return new RCTVideo(this.bridge);
@ -17,22 +17,22 @@ class RCTVideoManager extends RCTViewManager {
describeProps() {
return super
.describeProps()
.addBooleanProp("controls", this.setControls)
.addStringProp("id", this.setId)
.addBooleanProp("muted", this.setMuted)
.addBooleanProp("paused", this.setPaused)
.addNumberProp("progressUpdateInterval", this.setProgressUpdateInterval)
.addBooleanProp("rate", this.setRate)
.addBooleanProp("repeat", this.setRepeat)
.addNumberProp("resizeMode", this.setResizeMode)
.addNumberProp("seek", this.setSeek)
.addObjectProp("src", this.setSource)
.addNumberProp("volume", this.setVolume)
.addDirectEvent("onVideoEnd")
.addDirectEvent("onVideoError")
.addDirectEvent("onVideoLoad")
.addDirectEvent("onVideoLoadStart")
.addDirectEvent("onVideoProgress");
.addBooleanProp('controls', this.setControls)
.addStringProp('id', this.setId)
.addBooleanProp('muted', this.setMuted)
.addBooleanProp('paused', this.setPaused)
.addNumberProp('progressUpdateInterval', this.setProgressUpdateInterval)
.addBooleanProp('rate', this.setRate)
.addBooleanProp('repeat', this.setRepeat)
.addNumberProp('resizeMode', this.setResizeMode)
.addNumberProp('seek', this.setSeek)
.addObjectProp('src', this.setSource)
.addNumberProp('volume', this.setVolume)
.addDirectEvent('onVideoEnd')
.addDirectEvent('onVideoError')
.addDirectEvent('onVideoLoad')
.addDirectEvent('onVideoLoadStart')
.addDirectEvent('onVideoProgress');
}
dismissFullscreenPlayer() {

View File

@ -1,3 +1,3 @@
// @flow
module.exports = require("./RCTVideoManager");
module.exports = require('./RCTVideoManager');

View File

@ -66,7 +66,7 @@ import com.android.build.OutputFile
*/
project.ext.react = [
entryFile: "index.android.js",
entryFile: "index.js",
enableHermes: false,
]
apply from: "../../node_modules/react-native/react.gradle"
@ -97,6 +97,7 @@ android {
applicationId "com.videoplayer"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled true
versionCode 1
versionName "1.0"
ndk {
@ -136,6 +137,7 @@ android {
dependencies {
implementation project(':react-native-video')
implementation 'com.android.support:multidex:1.0.3'
implementation "com.facebook.react:react-native:+" // From node_modules
implementation 'org.webkit:android-jsc:+'
}
@ -146,3 +148,5 @@ task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
into 'libs'
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

View File

@ -11,6 +11,7 @@
android:allowBackup="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"

View File

@ -2,6 +2,7 @@ package com.videoplayer;
import android.app.Application;
import androidx.multidex.MultiDexApplication;
import com.facebook.react.ReactApplication;
import com.brentvatne.react.ReactVideoPackage;
import com.facebook.react.ReactNativeHost;
@ -9,10 +10,12 @@ import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.reactnativecommunity.picker.RNCPickerPackage;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
public class MainApplication extends MultiDexApplication implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
@ -24,9 +27,15 @@ public class MainApplication extends Application implements ReactApplication {
protected List<ReactPackage> getPackages() {
return Arrays.asList(
new MainReactPackage(),
new ReactVideoPackage()
new ReactVideoPackage(),
new RNCPickerPackage()
);
}
@Override
protected String getJSMainModuleName() {
return "src/index";
}
};
@Override

View File

@ -2,11 +2,11 @@
buildscript {
ext {
buildToolsVersion = "28.0.3"
minSdkVersion = 16
compileSdkVersion = 28
targetSdkVersion = 28
supportLibVersion = "28.0.0"
buildToolsVersion = "29.0.2"
minSdkVersion = 16
compileSdkVersion = 31
targetSdkVersion = 29
supportLibVersion = "28.0.0"
}
repositories {
@ -14,7 +14,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
classpath 'com.android.tools.build:gradle:4.0.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

View File

@ -1,6 +1,12 @@
rootProject.name = 'VideoPlayer'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':react-native-video'
project(':react-native-video').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android-exoplayer')
include ':@react-native-picker_picker'
project(':@react-native-picker_picker').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-picker/picker/android')
include ':app'

View File

@ -1,3 +1,16 @@
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'module-resolver',
{
extensions: ['.js', '.tsx', '.ts'],
root: ['./src'],
alias: {
src: './src',
},
},
],
],
};

View File

@ -1,230 +0,0 @@
'use strict';
import React, {
Component
} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import Video from 'react-native-video';
class VideoPlayer extends Component {
state = {
rate: 1,
volume: 1,
muted: false,
resizeMode: 'contain',
duration: 0.0,
currentTime: 0.0,
paused: true,
};
video: Video;
onLoad = (data) => {
this.setState({ duration: data.duration });
};
onProgress = (data) => {
this.setState({ currentTime: data.currentTime });
};
onEnd = () => {
this.setState({ paused: true })
this.video.seek(0)
};
onAudioBecomingNoisy = () => {
this.setState({ paused: true })
};
onAudioFocusChanged = (event: { hasAudioFocus: boolean }) => {
this.setState({ paused: !event.hasAudioFocus })
};
getCurrentTimePercentage() {
if (this.state.currentTime > 0) {
return parseFloat(this.state.currentTime) / parseFloat(this.state.duration);
}
return 0;
};
renderRateControl(rate) {
const isSelected = (this.state.rate === rate);
return (
<TouchableOpacity onPress={() => { this.setState({ rate }) }}>
<Text style={[styles.controlOption, { fontWeight: isSelected ? 'bold' : 'normal' }]}>
{rate}x
</Text>
</TouchableOpacity>
);
}
renderResizeModeControl(resizeMode) {
const isSelected = (this.state.resizeMode === resizeMode);
return (
<TouchableOpacity onPress={() => { this.setState({ resizeMode }) }}>
<Text style={[styles.controlOption, { fontWeight: isSelected ? 'bold' : 'normal' }]}>
{resizeMode}
</Text>
</TouchableOpacity>
)
}
renderVolumeControl(volume) {
const isSelected = (this.state.volume === volume);
return (
<TouchableOpacity onPress={() => { this.setState({ volume }) }}>
<Text style={[styles.controlOption, { fontWeight: isSelected ? 'bold' : 'normal' }]}>
{volume * 100}%
</Text>
</TouchableOpacity>
)
}
render() {
const flexCompleted = this.getCurrentTimePercentage() * 100;
const flexRemaining = (1 - this.getCurrentTimePercentage()) * 100;
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.fullScreen}
onPress={() => this.setState({ paused: !this.state.paused })}
>
<Video
ref={(ref: Video) => { this.video = ref }}
/* For ExoPlayer */
/* source={{ uri: 'http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=51AF5F39AB0CEC3E5497CD9C900EBFEAECCCB5C7.8506521BFC350652163895D4C26DEE124209AA9E&key=ik0', type: 'mpd' }} */
source={require('./broadchurch.mp4')}
style={styles.fullScreen}
rate={this.state.rate}
paused={this.state.paused}
volume={this.state.volume}
muted={this.state.muted}
resizeMode={this.state.resizeMode}
onLoad={this.onLoad}
onProgress={this.onProgress}
onEnd={this.onEnd}
onAudioBecomingNoisy={this.onAudioBecomingNoisy}
onAudioFocusChanged={this.onAudioFocusChanged}
repeat={false}
/>
</TouchableOpacity>
<View style={styles.controls}>
<View style={styles.generalControls}>
<View style={styles.rateControl}>
{this.renderRateControl(0.25)}
{this.renderRateControl(0.5)}
{this.renderRateControl(1.0)}
{this.renderRateControl(1.5)}
{this.renderRateControl(2.0)}
</View>
<View style={styles.volumeControl}>
{this.renderVolumeControl(0.5)}
{this.renderVolumeControl(1)}
{this.renderVolumeControl(1.5)}
</View>
<View style={styles.resizeModeControl}>
{this.renderResizeModeControl('cover')}
{this.renderResizeModeControl('contain')}
{this.renderResizeModeControl('stretch')}
</View>
</View>
<View style={styles.trackingControls}>
<View style={styles.progress}>
<View style={[styles.innerProgressCompleted, { flex: flexCompleted }]} />
<View style={[styles.innerProgressRemaining, { flex: flexRemaining }]} />
</View>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black',
},
fullScreen: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
controls: {
backgroundColor: 'transparent',
borderRadius: 5,
position: 'absolute',
bottom: 20,
left: 20,
right: 20,
},
progress: {
flex: 1,
flexDirection: 'row',
borderRadius: 3,
overflow: 'hidden',
},
innerProgressCompleted: {
height: 20,
backgroundColor: '#cccccc',
},
innerProgressRemaining: {
height: 20,
backgroundColor: '#2C2C2C',
},
generalControls: {
flex: 1,
flexDirection: 'row',
borderRadius: 4,
overflow: 'hidden',
paddingBottom: 10,
},
rateControl: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
},
volumeControl: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
},
resizeModeControl: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
controlOption: {
alignSelf: 'center',
fontSize: 11,
color: 'white',
paddingLeft: 2,
paddingRight: 2,
lineHeight: 12,
},
});
AppRegistry.registerComponent('VideoPlayer', () => VideoPlayer);

View File

@ -26,12 +26,12 @@
//
// To run on device, change `localhost` to the IP address of your computer, and make sure your computer and
// iOS device are on the same Wi-Fi network.
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios&dev=true"];
// OPTION 2
// Load from pre-bundled file on disk. To re-generate the static bundle, run
//
// $ curl 'http://localhost:8081/index.ios.bundle?dev=false&minify=true' -o iOS/main.jsbundle
// $ curl 'http://localhost:8081/index.bundle?dev=false&minify=true' -o iOS/main.jsbundle
//
// and uncomment the next following line
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];

View File

@ -18,7 +18,7 @@
{
NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"VideoPlayer"

View File

@ -1,5 +1,5 @@
// Offline JS
// To re-generate the offline bundle, run this from root of your project
// $ curl 'http://localhost:8081/index.ios.bundle?dev=false&minify=true' -o iOS/main.jsbundle
// $ curl 'http://localhost:8081/index.bundle?dev=false&minify=true' -o iOS/main.jsbundle
throw new Error('Offline JS file is empty. See iOS/main.jsbundle for instructions');

View File

@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"baseUrl": "./src",
"paths": {
"*": [
"./src/*"
]
}
},
"exclude": [
"node_modules",
"**/node_modules/*"
]
}

View File

@ -4,24 +4,29 @@
"private": true,
"scripts": {
"start": "react-native start",
"android": "react-native run-android",
"postinstall": "rm -rf node_modules/react-native-video/{examples,node_modules}",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"@react-native-picker/picker": "^1.9.11",
"babel-plugin-module-resolver": "^4.1.0",
"react": "^16.12.0",
"react-native": "0.61.5",
"react-native-windows": "^0.61.0-0",
"react-native-video": "file:../.."
"react-native-video": "../../",
"react-native-windows": "^0.61.0-0"
},
"devDependencies": {
"@babel/core": "^7.6.0",
"@babel/runtime": "^7.6.0",
"@react-native-community/eslint-config": "^0.0.5",
"@types/react": "^18.0.6",
"@types/react-native": "^0.67.6",
"babel-jest": "^24.9.0",
"eslint": "^6.4.0",
"jest": "^24.9.0",
"metro-react-native-babel-preset": "^0.56.0",
"react-test-renderer": "16.8.6"
}
}
}

View File

@ -0,0 +1,817 @@
'use strict';
import React, {
Component
} from 'react';
import {
StyleSheet,
Text,
TouchableOpacity,
View,
ActivityIndicator,
PanResponder,
ToastAndroid,
} from 'react-native';
import { Picker } from '@react-native-picker/picker'
import Video, { TextTrackType } from 'react-native-video';
class VideoPlayer extends Component {
state = {
rate: 1,
volume: 1,
muted: false,
resizeMode: 'contain',
duration: 0.0,
currentTime: 0.0,
videoWidth: 0,
videoHeight: 0,
paused: false,
fullscreen: true,
decoration: true,
isLoading: false,
seekerFillWidth: 0,
seekerPosition: 0,
seekerOffset: 0,
seeking: false,
audioTracks: [],
textTracks: [],
selectedAudioTrack: undefined,
selectedTextTrack: undefined,
srcListId: 0,
loop: false,
};
seekerWidth = 0
srcList = [
{
description: 'demo with sintel Subtitles',
uri:
'http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=51AF5F39AB0CEC3E5497CD9C900EBFEAECCCB5C7.8506521BFC350652163895D4C26DEE124209AA9E&key=ik0',
type: 'mpd',
},
{
description: 'subtitles',
uri: 'https://bitmovin-a.akamaihd.net/content/sintel/sintel.mpd',
},
{ description: 'Stopped playback', uri: undefined },
{
description: 'no View',
noView: true,
},
]
video: Video;
seekPanResponder: PanResponder | undefined;
onLoad = (data: any) => {
this.setState({ duration: data.duration, loading: false, });
this.onAudioTracks(data.audioTracks)
this.onTextTracks(data.textTracks)
};
onProgress = (data: any) => {
if (!this.state.seeking) {
const position = this.calculateSeekerPosition()
this.setSeekerPosition(position)
}
this.setState({ currentTime: data.currentTime })
};
onVideoLoadStart = () => {
console.log('onVideoLoadStart')
this.setState({ isLoading: true })
}
onAudioTracks = (data: any) => {
const selectedTrack = data.audioTracks?.find((x: any) => {
return x.selected
})
this.setState({
audioTracks: data,
})
if (selectedTrack?.language) {
this.setState({
selectedAudioTrack: {
type: 'language',
value: selectedTrack?.language,
},
})
}
}
onTextTracks = (data: any) => {
const selectedTrack = data.textTracks?.find((x: any) => {
return x.selected
})
this.setState({
textTracks: data,
})
if (selectedTrack?.language) {
this.setState({
textTracks: data,
selectedTextTrack: {
type: 'language',
value: selectedTrack?.language,
},
})
}
}
onAspectRatio = (data: any) => {
console.log('onAspectRadio called ' + JSON.stringify(data))
this.setState({
videoWidth: data.width,
videoHeight: data.height,
})
}
onVideoBuffer = (param: any) => {
console.log('onVideoBuffer')
this.setState({ isLoading: param.isBuffering })
}
onReadyForDisplay = () => {
console.log('onReadyForDisplay')
this.setState({ isLoading: false })
}
onAudioBecomingNoisy = () => {
this.setState({ paused: true })
};
onAudioFocusChanged = (event: { hasAudioFocus: boolean }) => {
this.setState({ paused: !event.hasAudioFocus })
};
getCurrentTimePercentage = () => {
if (this.state.currentTime > 0 && this.state.duration !== 0) {
return this.state.currentTime / this.state.duration;
}
return 0;
};
renderRateControl(rate: number) {
const isSelected = (this.state.rate === rate);
return (
<TouchableOpacity onPress={() => { this.setState({ rate }) }}>
<Text style={[styles.controlOption, { fontWeight: isSelected ? 'bold' : 'normal' }]}>
{rate}
</Text>
</TouchableOpacity>
);
}
renderResizeModeControl(resizeMode: string) {
const isSelected = (this.state.resizeMode === resizeMode);
return (
<TouchableOpacity onPress={() => { this.setState({ resizeMode }) }}>
<Text style={[styles.controlOption, { fontWeight: isSelected ? 'bold' : 'normal' }]}>
{resizeMode}
</Text>
</TouchableOpacity>
)
}
renderVolumeControl(volume: number) {
const isSelected = (this.state.volume === volume);
return (
<TouchableOpacity onPress={() => { this.setState({ volume }) }}>
<Text style={[styles.controlOption, { fontWeight: isSelected ? 'bold' : 'normal' }]}>
{volume * 100}%
</Text>
</TouchableOpacity>
)
}
toast = (visible: boolean, message: string) => {
if (visible) {
ToastAndroid.showWithGravityAndOffset(
message,
ToastAndroid.LONG,
ToastAndroid.BOTTOM,
25,
50,
)
return null
}
return null
}
onError = (err: any) => {
console.log(JSON.stringify(err))
this.toast(true, 'error: ' + err?.error?.code)
}
onEnd = () => {
this.channelUp()
};
toggleFullscreen() {
this.setState({ fullscreen: !this.state.fullscreen })
}
toggleDecoration() {
this.setState({ decoration: !this.state.decoration })
if (this.state.decoration) {
this.video.dismissFullscreenPlayer()
} else {
this.video.presentFullscreenPlayer()
}
}
goToChannel(channel: any) {
this.setState({
srcListId: channel,
duration: 0.0,
currentTime: 0.0,
videoWidth: 0,
videoHeight: 0,
isLoading: false,
audioTracks: [],
textTracks: [],
selectedAudioTrack: undefined,
selectedTextTrack: undefined,
})
}
channelUp() {
console.log('channel up')
this.goToChannel((this.state.srcListId + 1) % this.srcList.length)
}
channelDown() {
console.log('channel down')
this.goToChannel((this.state.srcListId + this.srcList.length - 1) % this.srcList.length)
}
componentDidMount() {
this.initSeekPanResponder()
}
renderDecorationsControl() {
return (
<TouchableOpacity
onPress={() => {
this.toggleDecoration()
}}
>
<Text style={[styles.controlOption]}>{'decoration'}</Text>
</TouchableOpacity>
)
}
renderFullScreenControl() {
return (
<TouchableOpacity
onPress={() => {
this.toggleFullscreen()
}}
>
<Text style={[styles.controlOption]}>{'fullscreen'}</Text>
</TouchableOpacity>
)
}
renderPause() {
return (
<TouchableOpacity
onPress={() => {
this.setState({ paused: !this.state.paused })
}}
>
<Text style={[styles.controlOption]}>
{this.state.paused ? 'pause' : 'playing'}
</Text>
</TouchableOpacity>
)
}
renderRepeatModeControl() {
return (
<TouchableOpacity
onPress={() => {
this.setState({ loop: !this.state.loop })
}}
>
<Text style={[styles.controlOption]}>
{this.state.loop ? 'loop enable' : 'loop disable'}
</Text>
</TouchableOpacity>
)
}
renderLeftControl() {
return (
<View>
<TouchableOpacity
onPress={() => {
this.channelDown()
}}
>
<Text style={[styles.leftRightControlOption]}>{'ChDown'}</Text>
</TouchableOpacity>
</View>
// onTimelineUpdated
)
}
renderRightControl() {
return (
<View>
<TouchableOpacity
onPress={() => {
this.channelUp()
}}
>
<Text style={[styles.leftRightControlOption]}>{'ChUp'}</Text>
</TouchableOpacity>
</View>
)
}
/**
* Render the seekbar and attach its handlers
*/
/**
* Constrain the location of the seeker to the
* min/max value based on how big the
* seeker is.
*
* @param {float} val position of seeker handle in px
* @return {float} constrained position of seeker handle in px
*/
constrainToSeekerMinMax(val = 0) {
if (val <= 0) {
return 0
} else if (val >= this.seekerWidth) {
return this.seekerWidth
}
return val
}
/**
* Set the position of the seekbar's components
* (both fill and handle) according to the
* position supplied.
*
* @param {float} position position in px of seeker handle}
*/
setSeekerPosition(position = 0) {
const state = this.state
position = this.constrainToSeekerMinMax(position)
state.seekerFillWidth = position
state.seekerPosition = position
if (!state.seeking) {
state.seekerOffset = position
}
this.setState(state)
}
/**
* Calculate the position that the seeker should be
* at along its track.
*
* @return {float} position of seeker handle in px based on currentTime
*/
calculateSeekerPosition() {
const percent = this.state.currentTime / this.state.duration
return this.seekerWidth * percent
}
/**
* Return the time that the video should be at
* based on where the seeker handle is.
*
* @return {float} time in ms based on seekerPosition.
*/
calculateTimeFromSeekerPosition() {
const percent = this.state.seekerPosition / this.seekerWidth
return this.state.duration * percent
}
/**
* Get our seekbar responder going
*/
initSeekPanResponder() {
this.seekPanResponder = PanResponder.create({
// Ask to be the responder.
onStartShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
/**
* When we start the pan tell the machine that we're
* seeking. This stops it from updating the seekbar
* position in the onProgress listener.
*/
onPanResponderGrant: (evt, gestureState) => {
const state = this.state
// this.clearControlTimeout()
const position = evt.nativeEvent.locationX
this.setSeekerPosition(position)
state.seeking = true
this.setState(state)
},
/**
* When panning, update the seekbar position, duh.
*/
onPanResponderMove: (evt, gestureState) => {
const position = this.state.seekerOffset + gestureState.dx
this.setSeekerPosition(position)
},
/**
* On release we update the time and seek to it in the video.
* If you seek to the end of the video we fire the
* onEnd callback
*/
onPanResponderRelease: (evt, gestureState) => {
const time = this.calculateTimeFromSeekerPosition()
const state = this.state
if (time >= state.duration && !state.isLoading) {
state.paused = true
this.onEnd()
} else {
this.video?.seek(time)
state.seeking = false
}
this.setState(state)
},
})
}
renderSeekBar() {
if (!this.seekPanResponder) {
return null
}
return (
<View
style={styles.seekbarContainer}
{...this.seekPanResponder.panHandlers}
{...styles.generalControls}
>
<View
style={styles.seekbarTrack}
onLayout={(event) => (this.seekerWidth = event.nativeEvent.layout.width)}
pointerEvents={'none'}
>
<View
style={[
styles.seekbarFill,
{
width:
this.state.seekerFillWidth > 0 ? this.state.seekerFillWidth : 0,
backgroundColor: '#FFF',
},
]}
pointerEvents={'none'}
/>
</View>
<View
style={[
styles.seekbarHandle,
{ left: this.state.seekerPosition > 0 ? this.state.seekerPosition : 0 },
]}
pointerEvents={'none'}
>
<View
style={[
styles.seekbarCircle,
{ backgroundColor: '#FFF' },
]}
pointerEvents={'none'}
/>
</View>
</View>
)
}
IndicatorLoadingView() {
if (this.state.isLoading)
return <ActivityIndicator color="#3235fd" size="large" style={styles.IndicatorStyle} />
else return <View />
}
renderOverlay() {
return (
<>
{this.IndicatorLoadingView()}
<View style={styles.topControls}>
<Text style={[styles.controlOption]}>
{this.srcList[this.state.srcListId]?.description}
</Text>
</View>
<View style={styles.leftControls}>
<View style={styles.resizeModeControl}>{this.renderLeftControl()}</View>
</View>
<View style={styles.rightControls}>
<View style={styles.resizeModeControl}>{this.renderRightControl()}</View>
</View>
<View style={styles.bottomControls}>
<View style={styles.generalControls}>
<View style={styles.resizeModeControl}>{this.renderPause()}</View>
<View style={styles.resizeModeControl}>
{this.renderRepeatModeControl()}
</View>
<View style={styles.resizeModeControl}>
{this.renderFullScreenControl()}
</View>
<View style={styles.resizeModeControl}>
{this.renderDecorationsControl()}
</View>
</View>
<View style={styles.generalControls}>
<View style={styles.rateControl}>
{this.renderRateControl(0.25)}
{this.renderRateControl(0.5)}
{this.renderRateControl(1.0)}
{this.renderRateControl(1.5)}
{this.renderRateControl(2.0)}
</View>
<View style={styles.volumeControl}>
{this.renderVolumeControl(0.5)}
{this.renderVolumeControl(1)}
{this.renderVolumeControl(1.5)}
</View>
<View style={styles.resizeModeControl}>
{this.renderResizeModeControl('cover')}
{this.renderResizeModeControl('contain')}
{this.renderResizeModeControl('stretch')}
</View>
</View>
{this.renderSeekBar()}
<View style={styles.generalControls}>
<Text style={styles.controlOption}>AudioTrack</Text>
{this.state.audioTracks?.length <= 0 ? (
<Text style={styles.controlOption}>empty</Text>
) : (
<Picker
style={styles.picker}
selectedValue={this.state.selectedAudioTrack?.value}
onValueChange={(itemValue, itemIndex) => {
console.log('on audio value change ' + itemValue)
this.setState({
selectedAudioTrack: {
type: 'language',
value: itemValue,
},
})
}}
>
{this.state.audioTracks.map((track) => {
return (
<Picker.Item
label={track.language}
value={track.language}
key={track.language}
/>
)
})}
</Picker>
)}
<Text style={styles.controlOption}>TextTrack</Text>
{this.state.textTracks?.length <= 0 ? (
<Text style={styles.controlOption}>empty</Text>
) : (
<Picker
style={styles.picker}
selectedValue={this.state.selectedTextTrack?.value}
onValueChange={(itemValue, itemIndex) => {
console.log('on value change ' + itemValue)
this.setState({
selectedTextTrack: {
type: 'language',
value: itemValue,
},
})
}}
>
<Picker.Item label={'none'} value={'none'} key={'none'} />
{this.state.textTracks.map((track) => (
<Picker.Item
label={track.language}
value={track.language}
key={track.language}
/>
))}
</Picker>
)}
</View>
</View>
</>
)
}
renderVideoView() {
const viewStyle = this.state.fullscreen ? styles.fullScreen : styles.halfScreen
return (
<TouchableOpacity style={viewStyle}>
<Video
ref={(ref: Video) => {
this.video = ref
}}
source={this.srcList[this.state.srcListId]}
style={viewStyle}
rate={this.state.rate}
paused={this.state.paused}
volume={this.state.volume}
muted={this.state.muted}
resizeMode={this.state.resizeMode}
onLoad={this.onLoad}
onProgress={this.onProgress}
onEnd={this.onEnd}
progressUpdateInterval={1000}
onError={this.onError}
onAudioBecomingNoisy={this.onAudioBecomingNoisy}
onAudioFocusChanged={this.onAudioFocusChanged}
onLoadStart={this.onVideoLoadStart}
onVideoAspectRatio={this.onAspectRatio}
onReadyForDisplay={this.onReadyForDisplay}
onBuffer={this.onVideoBuffer}
repeat={this.state.loop}
selectedTextTrack={this.state.selectedTextTrack}
selectedAudioTrack={this.state.selectedAudioTrack}
/>
</TouchableOpacity>
)
}
render() {
return (
<View style={styles.container}>
{this.srcList[this.state.srcListId]?.noView ? null : this.renderVideoView()}
{this.renderOverlay()}
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black',
},
halfScreen: {
position: 'absolute',
top: 50,
left: 50,
bottom: 100,
right: 100,
},
fullScreen: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
bottomControls: {
backgroundColor: 'transparent',
borderRadius: 5,
position: 'absolute',
bottom: 20,
left: 20,
right: 20,
},
leftControls: {
backgroundColor: 'transparent',
borderRadius: 5,
position: 'absolute',
top: 20,
bottom: 20,
left: 20,
},
rightControls: {
backgroundColor: 'transparent',
borderRadius: 5,
position: 'absolute',
top: 20,
bottom: 20,
right: 20,
},
topControls: {
backgroundColor: 'transparent',
borderRadius: 4,
position: 'absolute',
top: 20,
left: 20,
right: 20,
flex: 1,
flexDirection: 'row',
overflow: 'hidden',
paddingBottom: 10,
},
generalControls: {
flex: 1,
flexDirection: 'row',
borderRadius: 4,
overflow: 'hidden',
paddingBottom: 10,
},
rateControl: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
},
volumeControl: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
},
resizeModeControl: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
leftRightControlOption: {
alignSelf: 'center',
fontSize: 11,
color: 'white',
padding: 10,
lineHeight: 12,
},
controlOption: {
alignSelf: 'center',
fontSize: 11,
color: 'white',
paddingLeft: 2,
paddingRight: 2,
lineHeight: 12,
},
IndicatorStyle: {
flex: 1,
justifyContent: 'center',
},
seekbarContainer: {
flex: 1,
flexDirection: 'row',
borderRadius: 4,
height: 30,
},
seekbarTrack: {
backgroundColor: '#333',
height: 1,
position: 'relative',
top: 14,
width: '100%',
},
seekbarFill: {
backgroundColor: '#FFF',
height: 1,
width: '100%',
},
seekbarHandle: {
position: 'absolute',
marginLeft: -7,
height: 28,
width: 28,
},
seekbarCircle: {
borderRadius: 12,
position: 'relative',
top: 8,
left: 8,
height: 12,
width: 12,
},
picker: {
color: 'white',
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
},
});
export default VideoPlayer

View File

@ -5,7 +5,6 @@ import React, {
import {
AlertIOS,
AppRegistry,
Platform,
StyleSheet,
Text,
@ -35,7 +34,7 @@ const filterTypes = [
];
class VideoPlayer extends Component {
constructor(props) {
constructor(props: any) {
super(props);
this.onLoad = this.onLoad.bind(this);
this.onProgress = this.onProgress.bind(this);
@ -58,12 +57,12 @@ class VideoPlayer extends Component {
filterEnabled: true
};
onLoad(data) {
onLoad(data: any) {
console.log('On load fired!');
this.setState({duration: data.duration});
}
onProgress(data) {
onProgress(data: any) {
this.setState({currentTime: data.currentTime});
}
@ -72,14 +71,14 @@ class VideoPlayer extends Component {
}
getCurrentTimePercentage() {
if (this.state.currentTime > 0) {
return parseFloat(this.state.currentTime) / parseFloat(this.state.duration);
if (this.state.currentTime > 0 && this.state.duration !== 0) {
return this.state.currentTime / this.state.duration;
} else {
return 0;
}
}
setFilter(step) {
setFilter(step: number) {
let index = filterTypes.indexOf(this.state.filter) + step;
if (index === filterTypes.length) {
@ -108,7 +107,7 @@ class VideoPlayer extends Component {
);
}
renderRateControl(rate) {
renderRateControl(rate: number) {
const isSelected = (this.state.rate == rate);
return (
@ -120,7 +119,7 @@ class VideoPlayer extends Component {
)
}
renderResizeModeControl(resizeMode) {
renderResizeModeControl(resizeMode: string) {
const isSelected = (this.state.resizeMode == resizeMode);
return (
@ -132,7 +131,7 @@ class VideoPlayer extends Component {
)
}
renderVolumeControl(volume) {
renderVolumeControl(volume: number) {
const isSelected = (this.state.volume == volume);
return (
@ -144,7 +143,7 @@ class VideoPlayer extends Component {
)
}
renderIgnoreSilentSwitchControl(ignoreSilentSwitch) {
renderIgnoreSilentSwitchControl(ignoreSilentSwitch: string) {
const isSelected = (this.state.ignoreSilentSwitch == ignoreSilentSwitch);
return (
@ -156,7 +155,7 @@ class VideoPlayer extends Component {
)
}
renderMixWithOthersControl(mixWithOthers) {
renderMixWithOthersControl(mixWithOthers: string) {
const isSelected = (this.state.mixWithOthers == mixWithOthers);
return (
@ -442,8 +441,13 @@ const styles = StyleSheet.create({
},
nativeVideoControls: {
top: 184,
height: 300
}
height: 300,
},
trackingControls: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
});
AppRegistry.registerComponent('VideoPlayer', () => VideoPlayer);
export default VideoPlayer

View File

@ -5,7 +5,6 @@ import React, {
} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
TouchableOpacity,
@ -15,7 +14,7 @@ import {
import Video from 'react-native-video';
class VideoPlayer extends Component {
constructor(props) {
constructor(props: any) {
super(props);
this.onLoad = this.onLoad.bind(this);
this.onProgress = this.onProgress.bind(this);
@ -28,25 +27,26 @@ class VideoPlayer extends Component {
resizeMode: 'contain',
duration: 0.0,
currentTime: 0.0,
paused: 0,
};
onLoad(data) {
onLoad(data: any) {
this.setState({duration: data.duration});
}
onProgress(data) {
onProgress(data: any) {
this.setState({currentTime: data.currentTime});
}
getCurrentTimePercentage() {
if (this.state.currentTime > 0) {
return parseFloat(this.state.currentTime) / parseFloat(this.state.duration);
if (this.state.currentTime > 0 && this.state.duration !== 0) {
return this.state.currentTime / this.state.duration;
} else {
return 0;
}
}
renderRateControl(rate) {
renderRateControl(rate: number) {
const isSelected = (this.state.rate == rate);
return (
@ -58,7 +58,7 @@ class VideoPlayer extends Component {
)
}
renderResizeModeControl(resizeMode) {
renderResizeModeControl(resizeMode: string) {
const isSelected = (this.state.resizeMode == resizeMode);
return (
@ -70,7 +70,7 @@ class VideoPlayer extends Component {
)
}
renderVolumeControl(volume) {
renderVolumeControl(volume: number) {
const isSelected = (this.state.volume == volume);
return (
@ -205,6 +205,11 @@ const styles = StyleSheet.create({
paddingRight: 2,
lineHeight: 12,
},
trackingControls: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
});
AppRegistry.registerComponent('VideoPlayer', () => VideoPlayer);
export default VideoPlayer

View File

@ -0,0 +1,5 @@
import VideoPlayer from './VideoPlayer';
import { AppRegistry } from 'react-native';
AppRegistry.registerComponent('VideoPlayer', () => VideoPlayer);

View File

@ -0,0 +1,20 @@
{
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"isolatedModules": true,
"jsx": "react-native",
"lib": ["es2017"],
"moduleResolution": "node",
"noEmit": true,
"strict": true,
"target": "esnext"
},
"exclude": [
"node_modules",
"babel.config.js",
"metro.config.js",
"jest.config.js"
]
}

View File

@ -59,19 +59,14 @@ Global
..\node_modules\react-native-windows\Shared\Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Debug|ARM.ActiveCfg = Debug|ARM
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Debug|ARM.Build.0 = Debug|ARM
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Debug|ARM.Deploy.0 = Debug|ARM
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Debug|ARM64.ActiveCfg = Debug|ARM64
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Debug|ARM64.Build.0 = Debug|ARM64
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Debug|ARM64.Deploy.0 = Debug|ARM64
@ -81,9 +76,6 @@ Global
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Debug|x86.ActiveCfg = Debug|Win32
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Debug|x86.Build.0 = Debug|Win32
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Debug|x86.Deploy.0 = Debug|Win32
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Release|ARM.ActiveCfg = Release|ARM
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Release|ARM.Build.0 = Release|ARM
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Release|ARM.Deploy.0 = Release|ARM
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Release|ARM64.ActiveCfg = Release|ARM64
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Release|ARM64.Build.0 = Release|ARM64
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Release|ARM64.Deploy.0 = Release|ARM64
@ -93,112 +85,84 @@ Global
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Release|x86.ActiveCfg = Release|Win32
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Release|x86.Build.0 = Release|Win32
{ADF1CF02-8224-4167-A737-8CBE1A0D5208}.Release|x86.Deploy.0 = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.ActiveCfg = Debug|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.Build.0 = Debug|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.Build.0 = Debug|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.ActiveCfg = Debug|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.Build.0 = Debug|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.ActiveCfg = Debug|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.Build.0 = Debug|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.ActiveCfg = Release|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.Build.0 = Release|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.ActiveCfg = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.Build.0 = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.ActiveCfg = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.Build.0 = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.ActiveCfg = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.Build.0 = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.ActiveCfg = Debug|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.Build.0 = Debug|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.Build.0 = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.ActiveCfg = Debug|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.Build.0 = Debug|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.ActiveCfg = Debug|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.Build.0 = Debug|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.ActiveCfg = Release|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.Build.0 = Release|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.ActiveCfg = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.Build.0 = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.ActiveCfg = Release|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.Build.0 = Release|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.ActiveCfg = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.Build.0 = Release|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.ActiveCfg = Debug|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.Build.0 = Debug|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.ActiveCfg = Debug|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.Build.0 = Debug|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.ActiveCfg = Debug|x64
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.Build.0 = Debug|x64
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.ActiveCfg = Debug|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.Build.0 = Debug|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.ActiveCfg = Release|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.Build.0 = Release|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.ActiveCfg = Release|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.Build.0 = Release|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.ActiveCfg = Release|x64
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.Build.0 = Release|x64
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.ActiveCfg = Release|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.Build.0 = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.ActiveCfg = Debug|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.Build.0 = Debug|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.ActiveCfg = Debug|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.Build.0 = Debug|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.ActiveCfg = Debug|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.Build.0 = Debug|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.ActiveCfg = Debug|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.Build.0 = Debug|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.ActiveCfg = Release|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.Build.0 = Release|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.ActiveCfg = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.Build.0 = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.ActiveCfg = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.Build.0 = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.ActiveCfg = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.Build.0 = Release|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.ActiveCfg = Debug|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.Build.0 = Debug|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.Build.0 = Debug|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.ActiveCfg = Debug|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.Build.0 = Debug|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.ActiveCfg = Debug|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.Build.0 = Debug|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.ActiveCfg = Release|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.Build.0 = Release|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.ActiveCfg = Release|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.Build.0 = Release|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.ActiveCfg = Release|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.Build.0 = Release|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.ActiveCfg = Release|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.Build.0 = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.ActiveCfg = Debug|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.Build.0 = Debug|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.Build.0 = Debug|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.ActiveCfg = Debug|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.Build.0 = Debug|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.ActiveCfg = Debug|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.Build.0 = Debug|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.ActiveCfg = Release|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.Build.0 = Release|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.ActiveCfg = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.Build.0 = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.ActiveCfg = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.Build.0 = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.ActiveCfg = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.Build.0 = Release|Win32
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|ARM.ActiveCfg = Debug|ARM
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|ARM.Build.0 = Debug|ARM
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|ARM64.ActiveCfg = Debug|ARM64
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|ARM64.Build.0 = Debug|ARM64
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|x64.ActiveCfg = Debug|x64
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|x64.Build.0 = Debug|x64
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|x86.ActiveCfg = Debug|Win32
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|x86.Build.0 = Debug|Win32
{765365E4-9553-4900-9F69-E26D4309C8DA}.Release|ARM.ActiveCfg = Release|ARM
{765365E4-9553-4900-9F69-E26D4309C8DA}.Release|ARM.Build.0 = Release|ARM
{765365E4-9553-4900-9F69-E26D4309C8DA}.Release|ARM64.ActiveCfg = Release|ARM64
{765365E4-9553-4900-9F69-E26D4309C8DA}.Release|ARM64.Build.0 = Release|ARM64
{765365E4-9553-4900-9F69-E26D4309C8DA}.Release|x64.ActiveCfg = Release|x64

View File

@ -18,7 +18,7 @@ App::App() noexcept
MainComponentName(L"VideoPlayer");
#if BUNDLE
JavaScriptBundleFile(L"index.windows");
JavaScriptBundleFile(L"index");
InstanceSettings().UseWebDebugger(false);
InstanceSettings().UseFastRefresh(false);
#else

View File

@ -20,10 +20,6 @@
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
@ -36,10 +32,6 @@
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
@ -160,7 +152,7 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<PropertyGroup>
<BundleCommand>
npx --no-install react-native bundle --platform windows --entry-file index.js --bundle-output $(MSBuildThisFileDirectory)/Bundle/index.windows.bundle --assets-dest $(MSBuildThisFileDirectory)/Bundle
npx --no-install react-native bundle --platform windows --entry-file index.js --bundle-output $(MSBuildThisFileDirectory)/Bundle/index.bundle --assets-dest $(MSBuildThisFileDirectory)/Bundle
</BundleCommand>
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
</PropertyGroup>

View File

@ -961,6 +961,11 @@
eslint-plugin-react-native "3.6.0"
prettier "1.16.4"
"@react-native-picker/picker@^1.9.11":
version "1.16.8"
resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-1.16.8.tgz#2126ca54d4a5a3e9ea5e3f39ad1e6643f8e4b3d4"
integrity sha512-pacdQDX6V6EmjF+HoiIh6u++qx4mTK0WnhgUHRc01B+Qt5eoeUwseBqmqfTSXTx/aHDEd6PiIw7UGvKgFoqgFQ==
"@types/babel__core@^7.1.0":
version "7.1.3"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30"
@ -1024,6 +1029,32 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636"
integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==
"@types/prop-types@*":
version "15.7.5"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
"@types/react-native@^0.67.6":
version "0.67.6"
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.67.6.tgz#9a7de5feba6065aec9f44f9a1e8f6e55ee5d015c"
integrity sha512-NM6atxrefIXMLE/PyQ1bIQjQ/lWLdls3uVxItzKvNUUVZlGqgn/uGN4MarM9quSf90uSqJYPIAeAgTtBTUjhgg==
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^18.0.6":
version "18.0.6"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.6.tgz#30206c3830af6ce8639b91ace5868bc2d3d1d96c"
integrity sha512-bPqwzJRzKtfI0mVYr5R+1o9BOE8UEXefwc1LwcBtfnaAn6OoqMhLa/91VA8aeWfDPJt1kHvYKI8RHcQybZLHHA==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/scheduler@*":
version "0.16.2"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
"@types/stack-utils@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
@ -1447,6 +1478,17 @@ babel-plugin-jest-hoist@^24.9.0:
dependencies:
"@types/babel__traverse" "^7.0.6"
babel-plugin-module-resolver@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz#22a4f32f7441727ec1fbf4967b863e1e3e9f33e2"
integrity sha512-MlX10UDheRr3lb3P0WcaIdtCSRlxdQsB1sBqL7W0raF070bGl1HQQq5K3T2vf2XAYie+ww+5AKC/WrkjRO2knA==
dependencies:
find-babel-config "^1.2.0"
glob "^7.1.6"
pkg-up "^3.1.0"
reselect "^4.0.0"
resolve "^1.13.1"
babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0:
version "7.0.0-beta.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf"
@ -2002,6 +2044,11 @@ cssstyle@^1.0.0:
dependencies:
cssom "0.3.x"
csstype@^3.0.2:
version "3.0.11"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33"
integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@ -2180,10 +2227,10 @@ ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
eme-encryption-scheme-polyfill@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/eme-encryption-scheme-polyfill/-/eme-encryption-scheme-polyfill-2.0.1.tgz#b080b01bffd74c75c9cf8044c1cabedf3b83954f"
integrity sha512-Wz+Ro1c0/2Wsx2RLFvTOO0m4LvYn+7cSnq3XOvRvLLBq8jbvUACH/zpU9s0/5+mQa5oaelkU69x+q0z/iWYrFA==
eme-encryption-scheme-polyfill@^2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/eme-encryption-scheme-polyfill/-/eme-encryption-scheme-polyfill-2.0.4.tgz#7d818302af3f3b19d5974255dcc92dc087413845"
integrity sha512-MHYJX1v145Pjj2YJTrVVuJOYyXrxGVy8LWf6kV5M4jrV/GyoeuJKyTuD+GaD+VAiE8Ip+MptiH4dXk6ZVmMNow==
emoji-regex@^7.0.1:
version "7.0.3"
@ -2739,6 +2786,14 @@ finalhandler@1.1.2:
statuses "~1.5.0"
unpipe "~1.0.0"
find-babel-config@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.2.0.tgz#a9b7b317eb5b9860cda9d54740a8c8337a2283a2"
integrity sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==
dependencies:
json5 "^0.5.1"
path-exists "^3.0.0"
find-cache-dir@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7"
@ -2948,6 +3003,18 @@ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.1.6:
version "7.2.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
globals@^11.1.0, globals@^11.7.0:
version "11.12.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
@ -3277,6 +3344,13 @@ is-core-module@^2.1.0:
dependencies:
has "^1.0.3"
is-core-module@^2.8.1:
version "2.9.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69"
integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==
dependencies:
has "^1.0.3"
is-data-descriptor@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
@ -3954,6 +4028,11 @@ json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
json5@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
json5@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850"
@ -5161,6 +5240,11 @@ path-parse@^1.0.6:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-type@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
@ -5208,6 +5292,13 @@ pkg-dir@^3.0.0:
dependencies:
find-up "^3.0.0"
pkg-up@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5"
integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==
dependencies:
find-up "^3.0.0"
plist@^3.0.0, plist@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c"
@ -5377,12 +5468,12 @@ react-is@^16.8.4, react-is@^16.8.6:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb"
integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==
"react-native-video@file:../..":
version "5.1.0-alpha8"
react-native-video@../../:
version "5.2.0"
dependencies:
keymirror "^0.1.1"
prop-types "^15.7.2"
shaka-player "^2.5.9"
shaka-player "^3.3.2"
react-native-windows@^0.61.0-0:
version "0.61.15"
@ -5669,6 +5760,11 @@ require-main-filename@^2.0.0:
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
reselect@^4.0.0:
version "4.1.5"
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.5.tgz#852c361247198da6756d07d9296c2b51eddb79f6"
integrity sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ==
resolve-cwd@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
@ -5704,6 +5800,15 @@ resolve@^1.1.6:
is-core-module "^2.1.0"
path-parse "^1.0.6"
resolve@^1.13.1:
version "1.22.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
dependencies:
is-core-module "^2.8.1"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
resolve@^1.3.2, resolve@^1.5.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232"
@ -5940,12 +6045,12 @@ setprototypeof@1.1.1:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
shaka-player@^2.5.9:
version "2.5.18"
resolved "https://registry.yarnpkg.com/shaka-player/-/shaka-player-2.5.18.tgz#5382d0b879ade01dc7cea5115d311d2168b7428a"
integrity sha512-kW6sNMl36E4ookOcAo7//D/+sNkKNw7kBCR58AAC0eYw+fpVXwUbFoN/aqsj5nhACZ00QGQQajTZXZyK1s8Dow==
shaka-player@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/shaka-player/-/shaka-player-3.3.2.tgz#6c903413d64d0205d2c9672440f041233075e748"
integrity sha512-6N9J/Dy7xprT8xKcs9+YYiEJsXfKn3xtVzLndLRFP2hR13tn3YzVhP83hZmbnLzOEFBpuYlRq4kNrBNlOA+4/g==
dependencies:
eme-encryption-scheme-polyfill "^2.0.1"
eme-encryption-scheme-polyfill "^2.0.3"
shebang-command@^1.2.0:
version "1.2.0"
@ -6284,6 +6389,11 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
symbol-observable@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4"

View File

@ -383,6 +383,7 @@ static int const RCTVideoUnset = -1;
}
self->_player = [AVPlayer playerWithPlayerItem:self->_playerItem];
[self applyModifiers];
self->_player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[self->_player addObserver:self forKeyPath:playbackRate options:0 context:nil];
@ -907,7 +908,7 @@ static int const RCTVideoUnset = -1;
}
- (void)setupPipController {
if (!_pipController && _playerLayer && [AVPictureInPictureController isPictureInPictureSupported]) {
if (!_pipController && _playerLayer && [AVPictureInPictureController isPictureInPictureSupported] && _pictureInPicture) {
// Create new controller passing reference to the AVPlayerLayer
_pipController = [[AVPictureInPictureController alloc] initWithPlayerLayer:_playerLayer];
_pipController.delegate = self;
@ -1064,8 +1065,8 @@ static int const RCTVideoUnset = -1;
[self setSelectedTextTrack:_selectedTextTrack];
[self setResizeMode:_resizeMode];
[self setRepeat:_repeat];
[self setPaused:_paused];
[self setControls:_controls];
[self setPaused:_paused];
[self setAllowsExternalPlayback:_allowsExternalPlayback];
}

View File

@ -25,26 +25,26 @@
],
"repository": {
"type": "git",
"url": "git@github.com:react-native-community/react-native-video.git"
"url": "git@github.com:react-native-video/react-native-video.git"
},
"devDependencies": {
"@react-native-community/eslint-config": "0.0.7",
"babel-eslint": "10.0.3",
"eslint": "6.8.0",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"@react-native-community/eslint-config": "^0.0.5",
"eslint": "^6.5.1",
"react": "16.9.0",
"react-dom": "16.9.0",
"react-hot-loader": "^4.12.19",
"react-native": "^0.61.5",
"react-native": "0.61.5",
"react-native-dom": "^0.5.0",
"react-native-windows": "^0.61.0-0"
},
"dependencies": {
"deprecated-react-native-prop-types": "^2.2.0",
"keymirror": "^0.1.1",
"prop-types": "^15.7.2",
"shaka-player": "^2.5.9"
"shaka-player": "^3.3.2"
},
"scripts": {
"lint": "yarn eslint *.js"
"lint": "eslint ."
},
"files": [
"android-exoplayer",

View File

@ -9,8 +9,8 @@ Pod::Spec.new do |s|
s.description = package['description']
s.license = package['license']
s.author = package['author']
s.homepage = 'https://github.com/react-native-community/react-native-video'
s.source = { :git => "https://github.com/react-native-community/react-native-video.git", :tag => "#{s.version}" }
s.homepage = 'https://github.com/react-native-video/react-native-video'
s.source = { :git => "https://github.com/react-native-video/react-native-video.git", :tag => "v#{s.version}" }
s.ios.deployment_target = "8.0"
s.tvos.deployment_target = "9.0"

View File

@ -45,158 +45,119 @@ Global
..\node_modules\react-native-windows\Shared\Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
WinUI3|ARM = WinUI3|ARM
WinUI3|ARM64 = WinUI3|ARM64
WinUI3|x64 = WinUI3|x64
WinUI3|x86 = WinUI3|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|ARM.ActiveCfg = Debug|ARM
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|ARM.Build.0 = Debug|ARM
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|ARM64.ActiveCfg = Debug|ARM64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|ARM64.Build.0 = Debug|ARM64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|x64.ActiveCfg = Debug|x64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|x64.Build.0 = Debug|x64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|x86.ActiveCfg = Debug|Win32
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|x86.Build.0 = Debug|Win32
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|ARM.ActiveCfg = Release|ARM
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|ARM.Build.0 = Release|ARM
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|ARM64.ActiveCfg = Release|ARM64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|ARM64.Build.0 = Release|ARM64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|x64.ActiveCfg = Release|x64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|x64.Build.0 = Release|x64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|x86.ActiveCfg = Release|Win32
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|x86.Build.0 = Release|Win32
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|ARM.ActiveCfg = Release|ARM
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|ARM.Build.0 = Release|ARM
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|ARM64.ActiveCfg = Release|ARM64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|ARM64.Build.0 = Release|ARM64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|x64.ActiveCfg = Release|x64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|x64.Build.0 = Release|x64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|x86.ActiveCfg = Release|Win32
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|x86.Build.0 = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.ActiveCfg = Debug|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.Build.0 = Debug|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.Build.0 = Debug|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.ActiveCfg = Debug|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.Build.0 = Debug|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.ActiveCfg = Debug|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.Build.0 = Debug|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.ActiveCfg = Release|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.Build.0 = Release|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.ActiveCfg = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.Build.0 = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.ActiveCfg = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.Build.0 = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.ActiveCfg = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.Build.0 = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|ARM.ActiveCfg = Release|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|ARM.Build.0 = Release|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|ARM64.ActiveCfg = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|ARM64.Build.0 = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|x64.ActiveCfg = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|x64.Build.0 = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|x86.ActiveCfg = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|x86.Build.0 = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.ActiveCfg = Debug|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.Build.0 = Debug|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.Build.0 = Debug|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.ActiveCfg = Debug|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.Build.0 = Debug|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.ActiveCfg = Debug|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.Build.0 = Debug|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.ActiveCfg = Release|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.Build.0 = Release|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.ActiveCfg = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.Build.0 = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.ActiveCfg = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.Build.0 = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.ActiveCfg = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.Build.0 = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|ARM.ActiveCfg = Release|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|ARM.Build.0 = Release|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|ARM64.ActiveCfg = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|ARM64.Build.0 = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|x64.ActiveCfg = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|x64.Build.0 = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|x86.ActiveCfg = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|x86.Build.0 = Release|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.ActiveCfg = Debug|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.Build.0 = Debug|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.Build.0 = Debug|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.ActiveCfg = Debug|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.Build.0 = Debug|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.ActiveCfg = Debug|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.Build.0 = Debug|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.ActiveCfg = Release|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.Build.0 = Release|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.ActiveCfg = Release|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.Build.0 = Release|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.ActiveCfg = Release|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.Build.0 = Release|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.ActiveCfg = Release|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.Build.0 = Release|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|ARM.ActiveCfg = Release|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|ARM.Build.0 = Release|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|ARM64.ActiveCfg = Release|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|ARM64.Build.0 = Release|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|x64.ActiveCfg = Release|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|x64.Build.0 = Release|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|x86.ActiveCfg = Release|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|x86.Build.0 = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.ActiveCfg = Debug|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.Build.0 = Debug|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.ActiveCfg = Debug|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.Build.0 = Debug|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.ActiveCfg = Debug|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.Build.0 = Debug|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.ActiveCfg = Debug|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.Build.0 = Debug|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.ActiveCfg = Release|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.Build.0 = Release|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.ActiveCfg = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.Build.0 = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.ActiveCfg = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.Build.0 = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.ActiveCfg = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.Build.0 = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|ARM.ActiveCfg = Release|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|ARM.Build.0 = Release|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|ARM64.ActiveCfg = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|ARM64.Build.0 = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|x64.ActiveCfg = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|x64.Build.0 = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|x86.ActiveCfg = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|x86.Build.0 = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.ActiveCfg = Debug|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.Build.0 = Debug|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.Build.0 = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.ActiveCfg = Debug|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.Build.0 = Debug|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.ActiveCfg = Debug|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.Build.0 = Debug|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.ActiveCfg = Release|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.Build.0 = Release|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.ActiveCfg = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.Build.0 = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.ActiveCfg = Release|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.Build.0 = Release|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.ActiveCfg = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.Build.0 = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|ARM.ActiveCfg = Release|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|ARM.Build.0 = Release|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|ARM64.ActiveCfg = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|ARM64.Build.0 = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|x64.ActiveCfg = Release|x64

View File

@ -21,10 +21,6 @@
<ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(SolutionDir), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
@ -37,10 +33,6 @@
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>

View File

@ -53,121 +53,91 @@ Global
..\node_modules\react-native-windows\Shared\Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.ActiveCfg = Debug|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.Build.0 = Debug|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.Build.0 = Debug|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.ActiveCfg = Debug|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.Build.0 = Debug|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.ActiveCfg = Debug|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.Build.0 = Debug|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.ActiveCfg = Release|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.Build.0 = Release|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.ActiveCfg = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.Build.0 = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.ActiveCfg = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.Build.0 = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.ActiveCfg = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.Build.0 = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.ActiveCfg = Debug|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.Build.0 = Debug|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.Build.0 = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.ActiveCfg = Debug|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.Build.0 = Debug|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.ActiveCfg = Debug|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.Build.0 = Debug|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.ActiveCfg = Release|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.Build.0 = Release|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.ActiveCfg = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.Build.0 = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.ActiveCfg = Release|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.Build.0 = Release|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.ActiveCfg = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.Build.0 = Release|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.ActiveCfg = Debug|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.Build.0 = Debug|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.ActiveCfg = Debug|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.Build.0 = Debug|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.ActiveCfg = Debug|x64
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.Build.0 = Debug|x64
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.ActiveCfg = Debug|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.Build.0 = Debug|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.ActiveCfg = Release|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.Build.0 = Release|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.ActiveCfg = Release|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.Build.0 = Release|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.ActiveCfg = Release|x64
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.Build.0 = Release|x64
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.ActiveCfg = Release|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.Build.0 = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.ActiveCfg = Debug|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.Build.0 = Debug|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.ActiveCfg = Debug|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.Build.0 = Debug|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.ActiveCfg = Debug|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.Build.0 = Debug|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.ActiveCfg = Debug|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.Build.0 = Debug|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.ActiveCfg = Release|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.Build.0 = Release|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.ActiveCfg = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.Build.0 = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.ActiveCfg = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.Build.0 = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.ActiveCfg = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.Build.0 = Release|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.ActiveCfg = Debug|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.Build.0 = Debug|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.Build.0 = Debug|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.ActiveCfg = Debug|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.Build.0 = Debug|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.ActiveCfg = Debug|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.Build.0 = Debug|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.ActiveCfg = Release|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.Build.0 = Release|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.ActiveCfg = Release|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.Build.0 = Release|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.ActiveCfg = Release|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.Build.0 = Release|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.ActiveCfg = Release|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.Build.0 = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.ActiveCfg = Debug|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.Build.0 = Debug|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.Build.0 = Debug|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.ActiveCfg = Debug|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.Build.0 = Debug|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.ActiveCfg = Debug|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.Build.0 = Debug|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.ActiveCfg = Release|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.Build.0 = Release|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.ActiveCfg = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.Build.0 = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.ActiveCfg = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.Build.0 = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.ActiveCfg = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.Build.0 = Release|Win32
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|ARM.ActiveCfg = Debug|ARM
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|ARM.Build.0 = Debug|ARM
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|ARM64.ActiveCfg = Debug|Win32
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|x64.ActiveCfg = Debug|x64
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|x64.Build.0 = Debug|x64
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|x86.ActiveCfg = Debug|Win32
{765365E4-9553-4900-9F69-E26D4309C8DA}.Debug|x86.Build.0 = Debug|Win32
{765365E4-9553-4900-9F69-E26D4309C8DA}.Release|ARM.ActiveCfg = Release|ARM
{765365E4-9553-4900-9F69-E26D4309C8DA}.Release|ARM.Build.0 = Release|ARM
{765365E4-9553-4900-9F69-E26D4309C8DA}.Release|ARM64.ActiveCfg = Release|Win32
{765365E4-9553-4900-9F69-E26D4309C8DA}.Release|x64.ActiveCfg = Release|x64
{765365E4-9553-4900-9F69-E26D4309C8DA}.Release|x64.Build.0 = Release|x64

View File

@ -21,10 +21,6 @@
<ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(SolutionDir), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
@ -37,10 +33,6 @@
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>

View File

@ -48,182 +48,137 @@ Global
..\node_modules\react-native-windows\Shared\Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
WinUI3|ARM = WinUI3|ARM
WinUI3|ARM64 = WinUI3|ARM64
WinUI3|x64 = WinUI3|x64
WinUI3|x86 = WinUI3|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|ARM.ActiveCfg = Debug|ARM
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|ARM.Build.0 = Debug|ARM
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|ARM64.ActiveCfg = Debug|ARM64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|ARM64.Build.0 = Debug|ARM64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|x64.ActiveCfg = Debug|x64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|x64.Build.0 = Debug|x64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|x86.ActiveCfg = Debug|Win32
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Debug|x86.Build.0 = Debug|Win32
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|ARM.ActiveCfg = Release|ARM
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|ARM.Build.0 = Release|ARM
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|ARM64.ActiveCfg = Release|ARM64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|ARM64.Build.0 = Release|ARM64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|x64.ActiveCfg = Release|x64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|x64.Build.0 = Release|x64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|x86.ActiveCfg = Release|Win32
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.Release|x86.Build.0 = Release|Win32
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|ARM.ActiveCfg = Release|ARM
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|ARM.Build.0 = Release|ARM
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|ARM64.ActiveCfg = Release|ARM64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|ARM64.Build.0 = Release|ARM64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|x64.ActiveCfg = Release|x64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|x64.Build.0 = Release|x64
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|x86.ActiveCfg = Release|Win32
{0D1E54D3-4BE1-4DAF-98BF-124C28C85014}.WinUI3|x86.Build.0 = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.ActiveCfg = Debug|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM.Build.0 = Debug|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.Build.0 = Debug|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.ActiveCfg = Debug|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.Build.0 = Debug|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.ActiveCfg = Debug|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.Build.0 = Debug|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.ActiveCfg = Release|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM.Build.0 = Release|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.ActiveCfg = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.Build.0 = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.ActiveCfg = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.Build.0 = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.ActiveCfg = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.Build.0 = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|ARM.ActiveCfg = Release|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|ARM.Build.0 = Release|ARM
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|ARM64.ActiveCfg = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|ARM64.Build.0 = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|x64.ActiveCfg = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|x64.Build.0 = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|x86.ActiveCfg = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.WinUI3|x86.Build.0 = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.ActiveCfg = Debug|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM.Build.0 = Debug|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.Build.0 = Debug|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.ActiveCfg = Debug|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.Build.0 = Debug|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.ActiveCfg = Debug|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.Build.0 = Debug|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.ActiveCfg = Release|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM.Build.0 = Release|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.ActiveCfg = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.Build.0 = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.ActiveCfg = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.Build.0 = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.ActiveCfg = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.Build.0 = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|ARM.ActiveCfg = Release|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|ARM.Build.0 = Release|ARM
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|ARM64.ActiveCfg = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|ARM64.Build.0 = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|x64.ActiveCfg = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|x64.Build.0 = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|x86.ActiveCfg = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.WinUI3|x86.Build.0 = Release|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.ActiveCfg = Debug|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM.Build.0 = Debug|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|ARM64.Build.0 = Debug|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.ActiveCfg = Debug|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x64.Build.0 = Debug|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.ActiveCfg = Debug|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Debug|x86.Build.0 = Debug|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.ActiveCfg = Release|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM.Build.0 = Release|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.ActiveCfg = Release|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|ARM64.Build.0 = Release|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.ActiveCfg = Release|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x64.Build.0 = Release|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.ActiveCfg = Release|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.Release|x86.Build.0 = Release|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|ARM.ActiveCfg = Release|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|ARM.Build.0 = Release|ARM
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|ARM64.ActiveCfg = Release|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|ARM64.Build.0 = Release|ARM64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|x64.ActiveCfg = Release|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|x64.Build.0 = Release|x64
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|x86.ActiveCfg = Release|Win32
{A62D504A-16B8-41D2-9F19-E2E86019E5E4}.WinUI3|x86.Build.0 = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.ActiveCfg = Debug|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM.Build.0 = Debug|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.ActiveCfg = Debug|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.Build.0 = Debug|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.ActiveCfg = Debug|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.Build.0 = Debug|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.ActiveCfg = Debug|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.Build.0 = Debug|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.ActiveCfg = Release|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM.Build.0 = Release|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.ActiveCfg = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.Build.0 = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.ActiveCfg = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.Build.0 = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.ActiveCfg = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.Build.0 = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|ARM.ActiveCfg = Release|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|ARM.Build.0 = Release|ARM
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|ARM64.ActiveCfg = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|ARM64.Build.0 = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|x64.ActiveCfg = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|x64.Build.0 = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|x86.ActiveCfg = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.WinUI3|x86.Build.0 = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.ActiveCfg = Debug|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM.Build.0 = Debug|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.Build.0 = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.ActiveCfg = Debug|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.Build.0 = Debug|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.ActiveCfg = Debug|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.Build.0 = Debug|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.ActiveCfg = Release|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM.Build.0 = Release|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.ActiveCfg = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.Build.0 = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.ActiveCfg = Release|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.Build.0 = Release|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.ActiveCfg = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.Build.0 = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|ARM.ActiveCfg = Release|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|ARM.Build.0 = Release|ARM
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|ARM64.ActiveCfg = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|ARM64.Build.0 = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|x64.ActiveCfg = Release|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|x64.Build.0 = Release|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|x86.ActiveCfg = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.WinUI3|x86.Build.0 = Release|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.ActiveCfg = Debug|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM.Build.0 = Debug|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.ActiveCfg = Debug|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|ARM64.Build.0 = Debug|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.ActiveCfg = Debug|x64
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x64.Build.0 = Debug|x64
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.ActiveCfg = Debug|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.Debug|x86.Build.0 = Debug|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.ActiveCfg = Release|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM.Build.0 = Release|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.ActiveCfg = Release|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|ARM64.Build.0 = Release|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.ActiveCfg = Release|x64
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x64.Build.0 = Release|x64
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.ActiveCfg = Release|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.Release|x86.Build.0 = Release|Win32
{11C084A3-A57C-4296-A679-CAC17B603144}.WinUI3|ARM.ActiveCfg = WinUI3|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.WinUI3|ARM.Build.0 = WinUI3|ARM
{11C084A3-A57C-4296-A679-CAC17B603144}.WinUI3|ARM64.ActiveCfg = WinUI3|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.WinUI3|ARM64.Build.0 = WinUI3|ARM64
{11C084A3-A57C-4296-A679-CAC17B603144}.WinUI3|x64.ActiveCfg = WinUI3|x64