Se sabe que un microcontrolador Arduino débil no puede pasar una transmisión de video a través de sí mismo.¿Y si abordas esta tarea desde otro lado?... y estirar el proceso de disparo a tiempo.Je, muchos ya han adivinado por sí mismos que esta técnica se llama timelapse (disparo en cámara única de cámara lenta). Es decir, no se trata de una filmación de video, sino de una filmación, como resultado de lo cual se crea un video.Admito que inicialmente no tenía planeado hacer una cámara lenta. Solo quería hacer un registro de eventos para mis arduins, incluso con fotos. Bueno, entonces de vez en cuando. Si mi lector no está involucrado en el desarrollo, entonces solo puede ver el resultado (ir desde debajo de Chrome).En qué consiste mi sistema:- Arduino Mega Board
- Módulo JPEG de la cámara;
- utilidad y base de datos MongoDB;
- Servidor WEB para alojar archivos HTML;
Cuando la arduina envía sus datos al servidor, se adjunta su propia marca de tiempo a cada parámetro.Se envió el parámetro: se agregó un registro al repositorio, se enviaron dos veces más y se guardaron dos registros más.Todo el trabajo con el repositorio se lleva a cabo a través de un programa de utilidad (en adelante denominado el intermediario), que se inicia en una computadora estacionaria. Al mismo tiempo, el servidor WEB en sí solo proporciona contenido estático. Es decir, todos los clientes realizan el intercambio de información a través del programa de utilidad del intermediario, similar al popular protocolo MQTT. La principal diferencia con MQTT será que este intermediario trabaja directamente con el almacén de datos, proporcionando trabajo con datos históricos. Este hecho simplifica el esquema de interacción y no requiere tráfico de red adicional para guardar datos.Para la conveniencia de desarrollar mis aplicaciones web, creé una biblioteca javascript con la siguiente API:Esto crea un cliente para trabajar con almacenamiento en red:var client = new MgtClient("localhost", "login", "password", onDebugLog);
Argumentos de funciones:- la dirección de red en la que se ejecuta el programa intermediario, simplemente puede especificar la IP, por ejemplo, "127.0.0.1";
- inicio de sesión de usuario;
- contraseña de usuario
- función de devolución de llamada, para depurar mensajes de cadena;
La función de devolución de llamada para mensajes de depuración podría verse así:function onDebugLog(aStr) {
console.log((new Date()).getTimeString() + ' ' + aStr + '\n');
}
¿Aún no es difícil? Además será difícil.Estructura de solicitud de almacenamiento:var request = {
name: " 1",
placeId: 1,
beginTime: 1458108472000,
endTime: 1458194872000,
limit: 10000
};
¿Todavía no estás confundido?Entonces aquí está la estructura de la respuesta a la solicitud:var result = {
times: [],
values: [],
position: 20,
status: "progress",
progress: 91
};
Sí, ¿es más complicado?Estado del campo "estado":- “Listo”: recibió todo lo que se solicitó (se recibieron datos para todo el intervalo de tiempo o el límite en el número de registros trabajados);
- "Progreso": indica que este no es el último dato, el proceso de descarga aún no ha finalizado;
- "Abortar": se interrumpió la descarga de datos (funcionó la restricción en la cantidad total de datos que se bombea), puede generar inmediatamente una nueva solicitud para recibir los datos faltantes;
- "Falló": algo salió mal (¿tal vez no hay corriente en el tomacorriente?)
¿Crees que eso es todo? Lamentablemente no.Los parámetros solicitados pueden ser de diferentes tipos.- Si el parámetro es numérico, los números aparecerán en la matriz de valores.
- Si la cadena, entonces en la matriz de valores habrá cadenas.
- Si es booleano, la matriz de valores será "verdadera" o "falsa".
- Si es binario (por ejemplo, una imagen JPEG), las matrices de bytes estarán en la matriz de valores.
- Si se trata de un evento, devuelva las matrices formadas de manera especial.
Un ejemplo de un solo registro de evento:var event = [
" ",
"",
27.5,
"",
true,
...
"",
1458108472000
];
Es decir, cada registro de evento puede contener un conjunto arbitrario de parámetros. Tal agrupación es muy conveniente para analizar la imagen general.Uff, la parte más difícil ha terminado.Y así, la solicitud que se envía se ve:
client.readArchive(aRequest, onReadArchive);
Función inversa para obtener respuestas:
onReadArchive(aResult) {
return false;
}
Finalmente, llegamos a la edición de video en sí.Para crear el video, utilicé la biblioteca javascript Whammy, más detalles aquí.Función que crea el video:
<script src="whammy.js"></script>
<canvas id="canvas" style="display:none"></canvas>
<video id="player" controls autoplay loop></video>
function createVideo() {
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
canvas.width = '640';
canvas.height = '480';
var framerate = 10;
var quality = 0.8;
var video = new Whammy.Video(framerate, quality);
for (var i = 0; i < images.length; i++) {
var image = images[i];
context.globalAlpha = 1;
context.drawImage(image, 0, 0, 640, 480);
video.add(context);
}
var output = video.compile();
var url = URL.createObjectURL(output);
document.getElementById('player').src = url;
}
Lamentablemente, no puede crear videos en todos los navegadores. Por ejemplo, mi Firefox favorito no sabe cómo convertir imágenes al formato WebP, en función de las cuales se realiza la conversión a video. Y aunque encontré una biblioteca de JavaScript para tal conversión, se convirtió tan lentamente (y había tantos marcos) que me negué a usarla. Sin embargo, en todos los navegadores con el motor Chrome, esto funcionará.Aquí puedes ver lo que hice.Sin documentación completa, puedo ofrecer mis artículos anteriores.Artículo 1Artículo 2Bueno, eso es todo, y no tengo nada más que decir.