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

