Merge pull request #1441 from nfb-onf/1319-fullscreen-rotation-issues
1319 - fullscreen rotation issues with iOS built-in controls
This commit is contained in:
commit
c36a9cf2ef
3
examples/embed-and-fullscreen/.babelrc
Normal file
3
examples/embed-and-fullscreen/.babelrc
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": ["react-native"]
|
||||
}
|
6
examples/embed-and-fullscreen/.buckconfig
Normal file
6
examples/embed-and-fullscreen/.buckconfig
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
[android]
|
||||
target = Google Inc.:Google APIs:23
|
||||
|
||||
[maven_repositories]
|
||||
central = https://repo1.maven.org/maven2
|
58
examples/embed-and-fullscreen/.flowconfig
Normal file
58
examples/embed-and-fullscreen/.flowconfig
Normal file
@ -0,0 +1,58 @@
|
||||
[ignore]
|
||||
; We fork some components by platform
|
||||
.*/*[.]android.js
|
||||
|
||||
# We fork some components by platform.
|
||||
.*/*[.]android.js
|
||||
|
||||
# Ignore templates with `@flow` in header
|
||||
.*/local-cli/generator.*
|
||||
|
||||
# Ignore malformed json
|
||||
.*/node_modules/y18n/test/.*\.json
|
||||
|
||||
# Ignore the website subdir
|
||||
<PROJECT_ROOT>/website/.*
|
||||
|
||||
# Ignore BUCK generated dirs
|
||||
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; Ignore unexpected extra "@providesModule"
|
||||
.*/node_modules/.*/node_modules/fbjs/.*
|
||||
|
||||
; Ignore duplicate module providers
|
||||
; For RN Apps installed via npm, "Libraries" folder is inside
|
||||
; "node_modules/react-native" but in the source repo it is in the root
|
||||
.*/Libraries/react-native/React.js
|
||||
.*/Libraries/react-native/ReactNative.js
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
node_modules/react-native/Libraries/react-native/react-native-interface.js
|
||||
node_modules/react-native/flow
|
||||
flow/
|
||||
|
||||
[options]
|
||||
module.system=haste
|
||||
|
||||
experimental.strict_type_args=true
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FixMe
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-6]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-6]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
|
||||
unsafe.enable_getters_and_setters=true
|
||||
|
||||
[version]
|
||||
|
||||
^0.36.0
|
1
examples/embed-and-fullscreen/.gitattributes
vendored
Normal file
1
examples/embed-and-fullscreen/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.pbxproj -text
|
53
examples/embed-and-fullscreen/.gitignore
vendored
Normal file
53
examples/embed-and-fullscreen/.gitignore
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
# OSX
|
||||
#
|
||||
.DS_Store
|
||||
|
||||
# Xcode
|
||||
#
|
||||
build/
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata
|
||||
*.xccheckout
|
||||
*.moved-aside
|
||||
DerivedData
|
||||
*.hmap
|
||||
*.ipa
|
||||
*.xcuserstate
|
||||
project.xcworkspace
|
||||
|
||||
# Android/IntelliJ
|
||||
#
|
||||
build/
|
||||
.idea
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
|
||||
# node.js
|
||||
#
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
|
||||
# BUCK
|
||||
buck-out/
|
||||
\.buckd/
|
||||
android/app/libs
|
||||
*.keystore
|
||||
|
||||
# fastlane
|
||||
#
|
||||
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
|
||||
# screenshots whenever they are needed.
|
||||
# For more information about the recommended setup visit:
|
||||
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
|
||||
|
||||
fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots
|
144
examples/embed-and-fullscreen/.vscode/.react/debuggerWorker.js
vendored
Normal file
144
examples/embed-and-fullscreen/.vscode/.react/debuggerWorker.js
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
|
||||
// Initialize some variables before react-native code would access them
|
||||
var onmessage=null, self=global;
|
||||
// Cache Node's original require as __debug__.require
|
||||
global.__debug__={require: require};
|
||||
// avoid Node's GLOBAL deprecation warning
|
||||
Object.defineProperty(global, "GLOBAL", {
|
||||
configurable: true,
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
value: global
|
||||
});
|
||||
// Prevent leaking process.versions from debugger process to
|
||||
// worker because pure React Native doesn't do that and some packages as js-md5 rely on this behavior
|
||||
Object.defineProperty(process, "versions", {
|
||||
value: undefined
|
||||
});
|
||||
var vscodeHandlers = {
|
||||
'vscode_reloadApp': function () {
|
||||
try {
|
||||
global.require('NativeModules').DevMenu.reload();
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
},
|
||||
'vscode_showDevMenu': function () {
|
||||
try {
|
||||
var DevMenu = global.require('NativeModules').DevMenu.show();
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
};
|
||||
process.on("message", function (message) {
|
||||
if (message.data && vscodeHandlers[message.data.method]) {
|
||||
vscodeHandlers[message.data.method]();
|
||||
} else if(onmessage) {
|
||||
onmessage(message);
|
||||
}
|
||||
});
|
||||
var postMessage = function(message){
|
||||
process.send(message);
|
||||
};
|
||||
if (!self.postMessage) {
|
||||
self.postMessage = postMessage;
|
||||
}
|
||||
var importScripts = (function(){
|
||||
var fs=require('fs'), vm=require('vm');
|
||||
return function(scriptUrl){
|
||||
var scriptCode = fs.readFileSync(scriptUrl, "utf8");
|
||||
vm.runInThisContext(scriptCode, {filename: scriptUrl});
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
/* global __fbBatchedBridge, self, importScripts, postMessage, onmessage: true */
|
||||
/* eslint no-unused-vars: 0 */
|
||||
|
||||
'use strict';
|
||||
|
||||
onmessage = (function() {
|
||||
var visibilityState;
|
||||
var showVisibilityWarning = (function() {
|
||||
var hasWarned = false;
|
||||
return function() {
|
||||
// Wait until `YellowBox` gets initialized before displaying the warning.
|
||||
if (hasWarned || console.warn.toString().includes('[native code]')) {
|
||||
return;
|
||||
}
|
||||
hasWarned = true;
|
||||
console.warn(
|
||||
'Remote debugger is in a background tab which may cause apps to ' +
|
||||
'perform slowly. Fix this by foregrounding the tab (or opening it in ' +
|
||||
'a separate window).',
|
||||
);
|
||||
};
|
||||
})();
|
||||
|
||||
var messageHandlers = {
|
||||
executeApplicationScript: function(message, sendReply) {
|
||||
for (var key in message.inject) {
|
||||
self[key] = JSON.parse(message.inject[key]);
|
||||
}
|
||||
var error;
|
||||
try {
|
||||
importScripts(message.url);
|
||||
} catch (err) {
|
||||
error = err.message;
|
||||
}
|
||||
sendReply(null /* result */, error);
|
||||
},
|
||||
setDebuggerVisibility: function(message) {
|
||||
visibilityState = message.visibilityState;
|
||||
},
|
||||
};
|
||||
|
||||
return function(message) {
|
||||
if (visibilityState === 'hidden') {
|
||||
showVisibilityWarning();
|
||||
}
|
||||
|
||||
var object = message.data;
|
||||
|
||||
var sendReply = function(result, error) {
|
||||
postMessage({replyID: object.id, result: result, error: error});
|
||||
};
|
||||
|
||||
var handler = messageHandlers[object.method];
|
||||
if (handler) {
|
||||
// Special cased handlers
|
||||
handler(object, sendReply);
|
||||
} else {
|
||||
// Other methods get called on the bridge
|
||||
var returnValue = [[], [], [], 0];
|
||||
var error;
|
||||
try {
|
||||
if (typeof __fbBatchedBridge === 'object') {
|
||||
returnValue = __fbBatchedBridge[object.method].apply(
|
||||
null,
|
||||
object.arguments,
|
||||
);
|
||||
} else {
|
||||
error = 'Failed to call function, __fbBatchedBridge is undefined';
|
||||
}
|
||||
} catch (err) {
|
||||
error = err.message;
|
||||
} finally {
|
||||
sendReply(JSON.stringify(returnValue), error);
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
// Notify debugger that we're done with loading
|
||||
// and started listening for IPC messages
|
||||
postMessage({workerLoaded:true});
|
80702
examples/embed-and-fullscreen/.vscode/.react/index.ios.bundle
vendored
Normal file
80702
examples/embed-and-fullscreen/.vscode/.react/index.ios.bundle
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
examples/embed-and-fullscreen/.vscode/.react/index.ios.map
vendored
Normal file
1
examples/embed-and-fullscreen/.vscode/.react/index.ios.map
vendored
Normal file
File diff suppressed because one or more lines are too long
79
examples/embed-and-fullscreen/.vscode/launch.json
vendored
Normal file
79
examples/embed-and-fullscreen/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug Android Simulator",
|
||||
"program": "${workspaceRoot}/.vscode/launchReactNative.js",
|
||||
"type": "reactnative",
|
||||
"request": "launch",
|
||||
"platform": "android",
|
||||
"sourceMaps": true,
|
||||
"trace": "log",
|
||||
"outDir": "${workspaceRoot}/.vscode/.react"
|
||||
},
|
||||
{
|
||||
"name": "Debug Android Device",
|
||||
"program": "${workspaceRoot}/.vscode/launchReactNative.js",
|
||||
"type": "reactnative",
|
||||
"request": "launch",
|
||||
"platform": "android",
|
||||
"target": "device",
|
||||
"sourceMaps": true,
|
||||
"outDir": "${workspaceRoot}/.vscode/.react"
|
||||
},
|
||||
{
|
||||
"name": "Debug iPhone 6",
|
||||
"program": "${workspaceRoot}/.vscode/launchReactNative.js",
|
||||
"type": "reactnative",
|
||||
"request": "launch",
|
||||
"platform": "ios",
|
||||
"sourceMaps": true,
|
||||
"trace": "log",
|
||||
"target": "iPhone 6",
|
||||
"outDir": "${workspaceRoot}/.vscode/.react"
|
||||
},
|
||||
{
|
||||
"name": "Debug iPhone X",
|
||||
"program": "${workspaceRoot}/.vscode/launchReactNative.js",
|
||||
"type": "reactnative",
|
||||
"request": "launch",
|
||||
"platform": "ios",
|
||||
"sourceMaps": true,
|
||||
"trace": "log",
|
||||
"target": "iPhone X",
|
||||
"outDir": "${workspaceRoot}/.vscode/.react"
|
||||
},
|
||||
{
|
||||
"name": "Debug iPad Air",
|
||||
"program": "${workspaceRoot}/.vscode/launchReactNative.js",
|
||||
"type": "reactnative",
|
||||
"request": "launch",
|
||||
"platform": "ios",
|
||||
"sourceMaps": true,
|
||||
"trace": "log",
|
||||
"target": "iPad Air",
|
||||
"outDir": "${workspaceRoot}/.vscode/.react"
|
||||
},
|
||||
{
|
||||
"name": "Debug iOS Device",
|
||||
"program": "${workspaceRoot}/.vscode/launchReactNative.js",
|
||||
"type": "reactnative",
|
||||
"request": "launch",
|
||||
"platform": "ios",
|
||||
"target": "device",
|
||||
"sourceMaps": true,
|
||||
"outDir": "${workspaceRoot}/.vscode/.react"
|
||||
},
|
||||
{
|
||||
"name": "Attach to packager",
|
||||
"program": "${workspaceRoot}/.vscode/launchReactNative.js",
|
||||
"type": "reactnative",
|
||||
"request": "attach",
|
||||
"sourceMaps": true,
|
||||
"outDir": "${workspaceRoot}/.vscode/.react"
|
||||
}
|
||||
]
|
||||
}
|
5
examples/embed-and-fullscreen/.vscode/settings.json
vendored
Normal file
5
examples/embed-and-fullscreen/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"editor.insertSpaces": true,
|
||||
"editor.tabSize": 2,
|
||||
"java.configuration.updateBuildConfiguration": "disabled"
|
||||
}
|
1
examples/embed-and-fullscreen/.watchmanconfig
Normal file
1
examples/embed-and-fullscreen/.watchmanconfig
Normal file
@ -0,0 +1 @@
|
||||
{}
|
31
examples/embed-and-fullscreen/Utils.js
Normal file
31
examples/embed-and-fullscreen/Utils.js
Normal file
@ -0,0 +1,31 @@
|
||||
import { Dimensions } from "react-native";
|
||||
|
||||
export default function Util() {}
|
||||
|
||||
Util.isPortrait = () => {
|
||||
const dim = Dimensions.get("screen");
|
||||
return dim.height >= dim.width;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a timer for video from< time in seconds
|
||||
* ~~ is used as faster substitute for Math.floor() function
|
||||
* https://stackoverflow.com/questions/5971645/what-is-the-double-tilde-operator-in-javascript
|
||||
* @param time
|
||||
* @returns {string}
|
||||
*/
|
||||
Util.secondToTime = (time) => {
|
||||
return ~~(time / 60) + ":" + (time % 60 < 10 ? "0" : "") + time % 60;
|
||||
};
|
||||
|
||||
Util.normalizeSeconds = (number) => {
|
||||
let sec_num = parseInt(number, 10); // don't forget the second param
|
||||
let hours = Math.floor(sec_num / 3600);
|
||||
let minutes = Math.floor((sec_num - (hours * 3600)) / 60);
|
||||
let seconds = sec_num - (hours * 3600) - (minutes * 60);
|
||||
|
||||
if (hours < 10) {hours = "0"+hours;}
|
||||
if (minutes < 10) {minutes = "0"+minutes;}
|
||||
if (seconds < 10) {seconds = "0"+seconds;}
|
||||
return hours+':'+minutes+':'+seconds;
|
||||
};
|
BIN
examples/embed-and-fullscreen/broadchurch.mp4
Normal file
BIN
examples/embed-and-fullscreen/broadchurch.mp4
Normal file
Binary file not shown.
81
examples/embed-and-fullscreen/index.ios.js
Normal file
81
examples/embed-and-fullscreen/index.ios.js
Normal file
@ -0,0 +1,81 @@
|
||||
'use strict';
|
||||
import React, {
|
||||
Component
|
||||
} from 'react';
|
||||
|
||||
import {
|
||||
AppRegistry,
|
||||
StyleSheet,
|
||||
View,
|
||||
Dimensions,
|
||||
Text,
|
||||
Button
|
||||
} from 'react-native';
|
||||
|
||||
import Util from './Utils'
|
||||
|
||||
import Video from 'react-native-video';
|
||||
|
||||
export default class VideoPlayer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onLayout = this.onLayout.bind(this);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.resizeVideoPlayer();
|
||||
}
|
||||
|
||||
render() {
|
||||
return <View
|
||||
onLayout={this.onLayout}
|
||||
style={styles.container}>
|
||||
<Text>Here's some pre-Text</Text>
|
||||
<Video
|
||||
ref={p => { this.videoPlayer = p; }}
|
||||
source={require('./broadchurch.mp4')}
|
||||
style={{width: this.state.orientationWidth, height: this.state.orientationHeight }}
|
||||
controls={true}
|
||||
/>
|
||||
<Button title="full screen" onPress={ this.onPress.bind(this) }></Button>
|
||||
</View>
|
||||
}
|
||||
|
||||
onPress() {
|
||||
if (this.videoPlayer!=null)
|
||||
this.videoPlayer.presentFullscreenPlayer();
|
||||
}
|
||||
|
||||
resizeVideoPlayer() {
|
||||
// Always in 16 /9 aspect ratio
|
||||
let {width, height} = Dimensions.get('window');
|
||||
|
||||
if (Util.isPortrait()) {
|
||||
this.setState({
|
||||
orientationWidth: width * 0.8,
|
||||
orientationHeight: width * 0.8 * 0.56,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
orientationHeight: height * 0.8,
|
||||
orientationWidth: height * 0.8 * 1.77
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onLayout(e) {
|
||||
console.log('on layout called');
|
||||
this.resizeVideoPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('VideoPlayer', () => VideoPlayer);
|
210
examples/embed-and-fullscreen/index.windows.js
Normal file
210
examples/embed-and-fullscreen/index.windows.js
Normal file
@ -0,0 +1,210 @@
|
||||
'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 {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onLoad = this.onLoad.bind(this);
|
||||
this.onProgress = this.onProgress.bind(this);
|
||||
}
|
||||
|
||||
state = {
|
||||
rate: 1,
|
||||
volume: 1,
|
||||
muted: false,
|
||||
resizeMode: 'contain',
|
||||
duration: 0.0,
|
||||
currentTime: 0.0,
|
||||
};
|
||||
|
||||
onLoad(data) {
|
||||
this.setState({duration: data.duration});
|
||||
}
|
||||
|
||||
onProgress(data) {
|
||||
this.setState({currentTime: data.currentTime});
|
||||
}
|
||||
|
||||
getCurrentTimePercentage() {
|
||||
if (this.state.currentTime > 0) {
|
||||
return parseFloat(this.state.currentTime) / parseFloat(this.state.duration);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
renderRateControl(rate) {
|
||||
const isSelected = (this.state.rate == rate);
|
||||
|
||||
return (
|
||||
<TouchableOpacity onPress={() => { this.setState({rate: 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: 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: 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 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={() => { console.log('Done!') }}
|
||||
repeat={true} />
|
||||
</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);
|
16
examples/embed-and-fullscreen/ios/AppDelegate.h
Normal file
16
examples/embed-and-fullscreen/ios/AppDelegate.h
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
@end
|
52
examples/embed-and-fullscreen/ios/AppDelegate.m
Normal file
52
examples/embed-and-fullscreen/ios/AppDelegate.m
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "RCTRootView.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSURL *jsCodeLocation;
|
||||
|
||||
// Loading JavaScript code - uncomment the one you want.
|
||||
|
||||
// OPTION 1
|
||||
// Load from development server. Start the server from the repository root:
|
||||
//
|
||||
// $ npm start
|
||||
//
|
||||
// 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"];
|
||||
|
||||
// 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
|
||||
//
|
||||
// and uncomment the next following line
|
||||
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"VideoPlayer"
|
||||
initialProperties: nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [[UIViewController alloc] init];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6751" systemVersion="14C1510" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6736"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="VideoPlayer" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
47
examples/embed-and-fullscreen/ios/Info.plist
Normal file
47
examples/embed-and-fullscreen/ios/Info.plist
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string></string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
53
examples/embed-and-fullscreen/ios/VideoPlayer-tvOS.plist
Normal file
53
examples/embed-and-fullscreen/ios/VideoPlayer-tvOS.plist
Normal file
@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1000"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "2D2A28121D9B038B00D4039D"
|
||||
BuildableName = "libReact.a"
|
||||
BlueprintName = "React-tvOS"
|
||||
ReferencedContainer = "container:../node_modules/react-native/React/React.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FA8681B6216D5C6D0010C92A"
|
||||
BuildableName = "VideoPlayer-tvOS.app"
|
||||
BlueprintName = "VideoPlayer-tvOS"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FA8681B6216D5C6D0010C92A"
|
||||
BuildableName = "VideoPlayer-tvOS.app"
|
||||
BlueprintName = "VideoPlayer-tvOS"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FA8681B6216D5C6D0010C92A"
|
||||
BuildableName = "VideoPlayer-tvOS.app"
|
||||
BlueprintName = "VideoPlayer-tvOS"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FA8681B6216D5C6D0010C92A"
|
||||
BuildableName = "VideoPlayer-tvOS.app"
|
||||
BlueprintName = "VideoPlayer-tvOS"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0620"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "83CBBA2D1A601D0E00E9B192"
|
||||
BuildableName = "libReact.a"
|
||||
BlueprintName = "React"
|
||||
ReferencedContainer = "container:../node_modules/react-native/React/React.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "VideoPlayer.app"
|
||||
BlueprintName = "VideoPlayer"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "VideoPlayer.app"
|
||||
BlueprintName = "VideoPlayer"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "VideoPlayer.app"
|
||||
BlueprintName = "VideoPlayer"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "VideoPlayer.app"
|
||||
BlueprintName = "VideoPlayer"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
16
examples/embed-and-fullscreen/ios/VideoPlayer/AppDelegate.h
Normal file
16
examples/embed-and-fullscreen/ios/VideoPlayer/AppDelegate.h
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
@end
|
37
examples/embed-and-fullscreen/ios/VideoPlayer/AppDelegate.m
Normal file
37
examples/embed-and-fullscreen/ios/VideoPlayer/AppDelegate.m
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSURL *jsCodeLocation;
|
||||
|
||||
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"VideoPlayer"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [UIViewController new];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="VideoPlayer" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
54
examples/embed-and-fullscreen/ios/VideoPlayer/Info.plist
Normal file
54
examples/embed-and-fullscreen/ios/VideoPlayer/Info.plist
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->
|
||||
<dict>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
18
examples/embed-and-fullscreen/ios/VideoPlayer/main.m
Normal file
18
examples/embed-and-fullscreen/ios/VideoPlayer/main.m
Normal file
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
5
examples/embed-and-fullscreen/ios/main.jsbundle
Normal file
5
examples/embed-and-fullscreen/ios/main.jsbundle
Normal file
@ -0,0 +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
|
||||
|
||||
throw new Error('Offline JS file is empty. See iOS/main.jsbundle for instructions');
|
19
examples/embed-and-fullscreen/ios/main.m
Normal file
19
examples/embed-and-fullscreen/ios/main.m
Normal file
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
|
7
examples/embed-and-fullscreen/rn-cli.config.js
Normal file
7
examples/embed-and-fullscreen/rn-cli.config.js
Normal file
@ -0,0 +1,7 @@
|
||||
const blacklist = require('metro').createBlacklist;
|
||||
|
||||
module.exports = {
|
||||
getBlacklistRE: function() {
|
||||
return blacklist([/node_modules\/react-native-video\/examples\/.*/]);
|
||||
}
|
||||
};
|
@ -146,7 +146,6 @@ static int const RCTVideoUnset = -1;
|
||||
|
||||
viewController.view.frame = self.bounds;
|
||||
viewController.player = player;
|
||||
viewController.view.frame = self.bounds;
|
||||
return viewController;
|
||||
}
|
||||
|
||||
@ -579,6 +578,27 @@ static int const RCTVideoUnset = -1;
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||
{
|
||||
// when controls==true, this is a hack to reset the rootview when rotation happens in fullscreen
|
||||
if (object == _playerViewController.contentOverlayView) {
|
||||
if ([keyPath isEqualToString:@"frame"]) {
|
||||
|
||||
CGRect oldRect = [change[NSKeyValueChangeOldKey] CGRectValue];
|
||||
CGRect newRect = [change[NSKeyValueChangeNewKey] CGRectValue];
|
||||
|
||||
if (!CGRectEqualToRect(oldRect, newRect)) {
|
||||
if (CGRectEqualToRect(newRect, [UIScreen mainScreen].bounds)) {
|
||||
NSLog(@"in fullscreen");
|
||||
} else NSLog(@"not fullscreen");
|
||||
|
||||
[self.reactViewController.view setFrame:[UIScreen mainScreen].bounds];
|
||||
[self.reactViewController.view setNeedsLayout];
|
||||
}
|
||||
|
||||
return;
|
||||
} else
|
||||
return [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
|
||||
if (object == _playerItem) {
|
||||
// When timeMetadata is read the event onTimedMetadata is triggered
|
||||
if ([keyPath isEqualToString:timedMetadata]) {
|
||||
@ -1267,8 +1287,15 @@ static int const RCTVideoUnset = -1;
|
||||
// to prevent video from being animated when resizeMode is 'cover'
|
||||
// resize mode must be set before subview is added
|
||||
[self setResizeMode:_resizeMode];
|
||||
|
||||
if (_controls) {
|
||||
UIViewController *viewController = [self reactViewController];
|
||||
[viewController addChildViewController:_playerViewController];
|
||||
[self addSubview:_playerViewController.view];
|
||||
}
|
||||
|
||||
[_playerViewController.contentOverlayView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)usePlayerLayer
|
||||
@ -1460,6 +1487,7 @@ static int const RCTVideoUnset = -1;
|
||||
|
||||
[self removePlayerLayer];
|
||||
|
||||
[_playerViewController.contentOverlayView removeObserver:self forKeyPath:@"frame"];
|
||||
[_playerViewController.view removeFromSuperview];
|
||||
_playerViewController = nil;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user