fbpixel
Etiquetas: ,

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.

react-native-webview-motion-video-stream Visualización de un flujo de vídeo Motion en React Native

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,
  },
});

Fuentes