En este tutorial veremos cómo recuperar un flujo de vídeo Motion desde una aplicación React Native.
Configuración del proyecto
Hemos configurado un flujo de vídeo con Motion en una máquina Linux cuya dirección es 192.168.1.92:8554 en la red Wifi.
El programa Motion sirve las secuencias de vídeo en forma de página HTML mediante el protocolo HTTP. Para recuperar esta página utilizamos la biblioteca react-native-webview, que puede mostrar páginas web completas en una aplicación.
Para instalar la biblioteca, introduzca el siguiente comando
npm install --save react-native-webview
Uso de WebView
Para utilizar el componente WebView, todo lo que tenemos que hacer es importar el archivo
import {WebView} from 'react-native-webview'
y llame al componente en el renderizado del componente funcional App y especifique la fuente del vídeo
<View style={{flex: 1 }}>
<WebView
source={{uri: "http://192.168.1.92:8554/"}}
style={styles.webVideo} />
</View>
Con el siguiente estilo de hoja
var styles = StyleSheet.create({
webVideo: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
});
Para ir un paso más allá, hemos creado una inserción textInput que nos permite actualizar la url del stream (o página web) con los estados ipAddress e ipServer. Puedes encontrar los detalles en el código completo.

El vídeo se muestra con un retardo de menos de 3 segundos y una calidad poco fluida.
Código completo de la aplicación React Native para reproducir un flujo de vídeo Motion.
En el siguiente código definimos textInput que nos permitirá actualizar el valor de ipAddress (valor de ip almacenado) y al pulsar el botón, actualizar la url leída por el componente WebView (ipServer)
También hemos añadido la visualización de la fecha y la hora (currentDate) en tiempo real para evaluar el retraso en la recepción del flujo de vídeo. Comentamos esta función porque refresca la aplicación cada segundo.
/**
* https://github.com/react-native-webview/react-native-webview
*/
import React, { useEffect, useState } from 'react'
import { Text, View, StyleSheet, TextInput, TouchableOpacity } from 'react-native'
import {WebView} from 'react-native-webview'
const App = () => {
const videoRef = React.createRef();
const [ipAddress, setIpAddress] = useState("http://192.168.1.92:8554/");
const [ipServer, setIpServer] = useState("http://192.168.1.92:8554/");
//const [currentDate, setCurrentDate] = useState('');
useEffect(() => {
/*setInterval(() => {
var date = new Date().getDate(); //Current Date
var month = new Date().getMonth() + 1; //Current Month
var year = new Date().getFullYear(); //Current Year
var hours = new Date().getHours(); //Current Hours
var min = new Date().getMinutes(); //Current Minutes
var sec = new Date().getSeconds(); //Current Seconds
setCurrentDate(
date + '/' + month + '/' + year + ' ' + hours + ':' + min + ':' + sec
);
}, 1000)*/
}, []);
console.log("rendering...");
return (
<View style={{ flexGrow: 1, flex: 1 }}>
<Text style={styles.mainTitle}>AC Video Player</Text>
<View
style={styles.inputBar}>
<TextInput
style={styles.textInput}
placeholder="Enter a message"
value={ipAddress}
onChangeText={(text) => setIpAddress(text)
}
/>
<TouchableOpacity
onPress={() => {
setIpServer(""); //force state change thus rendering
setIpServer(ipAddress);}
}
style={[styles.sendButton]}>
<Text
style={styles.buttonText}>
SEND
</Text>
</TouchableOpacity>
</View>
<View style={{flex: 1 }}>
<WebView
source={{uri: ipServer}}
style={styles.webVideo} />
</View>
{/*<Text style={{textAlign: 'right'}}>{currentDate}</Text>*/}
</View>
)
}
export default App;
let BACKGROUND_COLOR = "#161616"; //191A19
let BUTTON_COLOR = "#346751"; //1E5128
let ERROR_COLOR = "#C84B31"; //4E9F3D
let TEXT_COLOR = "#ECDBBA"; //D8E9A8
var styles = StyleSheet.create({
mainTitle:{
color: TEXT_COLOR,
fontSize: 30,
textAlign: 'center',
borderBottomWidth: 2,
borderBottomColor: ERROR_COLOR,
},
webVideo: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
buttonText: {
color: TEXT_COLOR,
fontWeight: 'bold',
fontSize: 12,
textAlign: 'center',
textAlignVertical: 'center',
},
sendButton: {
backgroundColor: BUTTON_COLOR,
padding: 15,
borderRadius: 15,
margin: 2,
paddingHorizontal: 20,
},
inputBar:{
flexDirection: 'row',
justifyContent: 'space-between',
margin: 5,
},
textInput:{
backgroundColor: '#888888',
margin: 2,
borderRadius: 15,
flex:3,
},
});