fbpixel
Étiquettes : ,

Nous allons voir dans ce tutoriel comment récupérer un flux vidéo Motion sur une application React Native.

Configuration du projet

Nous avons mis en place un stream vidéo avec Motion sur une machine Linux dont l’adresse est 192.168.1.92:8554 sur le réseau Wifi.

Le programme Motion sert les streams vidéo sous forme de page HTML avec le protocol HTTP. Pour récupérer cette page nous utilisons la librairie react-native-webview qui permet d’afficher des pages web complètes dans une application.

Pour installer la librairie, entrez la commande suivante

npm install --save react-native-webview

Utilisation de WebView

Pour utiliser le composant WebView, il nous suffit d’importer le composant

import {WebView} from 'react-native-webview'

et d’appeler le composant dans le rendu du composant fonctionnel App et de préciser la source de la vidéo

      <View style={{flex: 1 }}>

            <WebView
              source={{uri: "http://192.168.1.92:8554/"}}
              style={styles.webVideo} />

      </View>

Avec le style sheet suivant

var styles = StyleSheet.create({
  webVideo: {
    position: 'absolute',
    top: 0,
    left: 0,
    bottom: 0,
    right: 0,
  },
});

Pour aller plus loin, nous avons créé une encart textInput qui nous permet de mettre à jour l’url du stream (ou de la page web) avec les états ipAddress et ipServer. Vous pouvez retrouver les détails dans le code complet.

react-native-webview-motion-video-stream Afficher un Stream Vidéo Motion sur React Native

La vidéo s’affiche avec un délai inférieur à 3secondes et une qualité qui n’est pas très fluide.

Code complet de l’application React Native pour lire un flux vidéo Motion

Dans le code suivant nous définissons textInput qui va nous permettre de mettre à jour la valeur de ipAddress (valeur d’ip stockée) et lorsqu’on appuit sur le bouton, mettre à jour l’url lu par le composant WebView (ipServer)

Nous avons aussi rajouter l’affichage de la date et de l’heure (currentDate) en temps réel pour évaluer le délai de réception du flux vidéo. Nous avons commenté cette fonction car elle rafraichit l’application toute les secondes.

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

Sources