Neste tutorial, veremos como recuperar um fluxo de vídeo Motion de um aplicativo React Native.
Configuração do projeto
Configurámos um fluxo de vídeo com o Motion numa máquina Linux cujo endereço é 192.168.1.92:8554 na rede Wifi.
O programa Motion serve os fluxos de vídeo sob a forma de uma página HTML utilizando o protocolo HTTP. Para recuperar esta página, utilizamos a biblioteca react-native-webview , que pode apresentar páginas Web completas numa aplicação.
Para instalar a biblioteca, introduza o seguinte comando
npm install --save react-native-webview
Utilizar o WebView
Para usar o componente WebView, tudo o que precisamos de fazer é importar o componente
import {WebView} from 'react-native-webview'
e chamar o componente na renderização do componente funcional da aplicação e especificar a fonte do vídeo
<View style={{flex: 1 }}> <WebView source={{uri: "http://192.168.1.92:8554/"}} style={styles.webVideo} /> </View>
Com o seguinte estilo de folha
var styles = StyleSheet.create({ webVideo: { position: 'absolute', top: 0, left: 0, bottom: 0, right: 0, }, });
Para ir mais longe, criámos um textInput insert que nos permite atualizar o url do fluxo (ou página Web) com os estados ipAddress e ipServer. Pode encontrar os pormenores no código completo.
O vídeo é apresentado com um atraso de menos de 3 segundos e com uma qualidade pouco fluida.
Código completo da aplicação React Native para reproduzir um fluxo de vídeo Motion
No código seguinte, definimos textInput que nos permitirá atualizar o valor de ipAddress (valor ip armazenado) e, quando o botão é premido, atualizar o url lido pelo componente WebView (ipServer)
Adicionámos também a visualização da data e da hora (currentDate) em tempo real para avaliar o atraso na receção do fluxo de vídeo. Comentámos esta função porque actualiza a aplicação a 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, }, });