Arduino und Video? Einfach


Es ist bekannt, dass ein schwacher Arduino-Mikrocontroller keinen Videostream durch sich selbst leiten kann.
Und wenn Sie sich dieser Aufgabe von einer anderen Seite nähern?

... und verlängern Sie den Aufnahmevorgang rechtzeitig.

Heh, viele haben bereits selbst erraten, dass diese Technik als Zeitraffer (Zeitlupen-Einzelbildaufnahme) bezeichnet wird. Das heißt, dies ist keine Videoaufnahme, sondern eine Aufnahme, aus der ein Video erstellt wird.

Ich gebe zu, anfangs hatte ich nicht vor, eine Zeitlupe zu machen. Ich wollte nur eine Registrierung von Ereignissen für meine Arduins vornehmen, auch mit Fotos. Na dann ab und an. Wenn mein Leser nicht an der Entwicklung beteiligt ist, kann er nur das Ergebnis sehen ( siehe unter Chrome).

Woraus mein System besteht:
  • Arduino Mega Board
  • JPEG-Modul der Kamera;
  • Dienstprogramm und MongoDB-Datenbank;
  • WEB-Server zum Hosten von HTML-Dateien;


Wenn die Arduina ihre Daten an den Server sendet, wird jedem Parameter ein eigener Zeitstempel hinzugefügt.
Der Parameter wurde gesendet - ein Datensatz wurde zum Repository hinzugefügt, zwei weitere Male wurden gesendet - zwei weitere Datensätze wurden gespeichert.

Alle Arbeiten mit dem Repository werden über ein Hilfsprogramm (im Folgenden als Vermittler bezeichnet) ausgeführt, das auf einem stationären Computer gestartet wird. Gleichzeitig liefert der WEB-Server selbst nur statischen Inhalt. Das heißt, alle Clients führen einen Informationsaustausch über das Hilfsprogramm des Vermittlers durch, ähnlich dem beliebten MQTT-Protokoll. Der Hauptunterschied zu MQTT besteht darin, dass dieser Vermittler direkt mit dem Data Warehouse zusammenarbeitet und die Arbeit mit historischen Daten bereitstellt. Diese Tatsache vereinfacht das Interaktionsschema und erfordert keinen zusätzlichen Netzwerkverkehr zum Speichern von Daten.

Um die Entwicklung meiner Webanwendungen zu vereinfachen, habe ich eine Javascript-Bibliothek mit der folgenden API erstellt:

Dadurch wird ein Client für die Arbeit mit Netzwerkspeicher erstellt:
var client = new MgtClient("localhost", "login", "password", onDebugLog);

Funktionsargumente:
  1. Als Netzwerkadresse, auf der das Zwischenprogramm ausgeführt wird, können Sie einfach die IP-Adresse angeben, z. B. "127.0.0.1".
  2. Benutzer Login;
  3. Benutzerpasswort
  4. Rückruffunktion zum Debuggen von String-Nachrichten;


Die Rückruffunktion zum Debuggen von Nachrichten könnte folgendermaßen aussehen:
function onDebugLog(aStr) {
  //          
  console.log((new Date()).getTimeString() + ' ' + aStr + '\n'); 
}


Noch nicht schwer? Weiter wird es schwierig sein.

Speicheranforderungsstruktur:
var request = {
  name: " 1", //   
  placeId: 1, //                         
  beginTime: 1458108472000, //      1  1970 
  endTime: 1458194872000, //      1  1970  ( )
  limit: 10000 //   ,    (   )
};


Noch nicht verwirrt?

Dann ist hier die Struktur der Antwort auf die Anfrage:
var result = {
  times: [], //      (    1  1970 )
  values: [], //    
  position: 20, //         (   )
  status: "progress", //    ("progress", "abort", "done", "fail")
  progress: 91 //   ( )   
};


Ja, ist es komplizierter?

Status des Feldes "Status":
  • "Fertig" - erhielt alles, was angefordert wurde (entweder wurden Daten für den gesamten Zeitraum empfangen oder die Anzahl der bearbeiteten Datensätze wurde begrenzt);
  • "Fortschritt" - zeigt an, dass dies nicht das letzte Datenelement ist. Der Downloadvorgang ist noch nicht abgeschlossen.
  • "Abbruch" - Das Herunterladen von Daten wurde unterbrochen (die Beschränkung der Gesamtmenge der gepumpten Daten hat funktioniert). Sie können sofort eine neue Anforderung zum Empfangen der fehlenden Daten generieren.
  • "Fail" - etwas ist schief gelaufen (möglicherweise ist kein Strom in der Steckdose?)


Glaubst du, das ist alles? Leider gibt es keine.

Die angeforderten Parameter können unterschiedlicher Art sein.
  • Wenn der Parameter numerisch ist, werden die Zahlen im Wertearray angezeigt.
  • Wenn die Zeichenfolge, dann werden im Array von Werten Zeichenfolgen sein.
  • Wenn boolesch, ist das Array von Werten "wahr" oder "falsch".
  • Wenn es binär ist (z. B. ein JPEG-Bild), befinden sich Byte-Arrays im Array von Werten.
  • Wenn dies ein Ereignis ist, geben Sie Arrays zurück, die auf spezielle Weise gebildet wurden.

Ein Beispiel für einen einzelnen Ereignisdatensatz:
var event = [
  "  ", //   
  "", //   1
  27.5, //   1
  "", //   2
  true, //   2
  ...
  "", //   
  1458108472000 // !!!       ,
                //        .
];

Das heißt, jeder Ereignisdatensatz kann einen beliebigen Satz von Parametern enthalten. Eine solche Gruppierung ist sehr praktisch für die Analyse des Gesamtbildes.

Uff, der schwierigste Teil ist vorbei.

Und so sieht die Anfrage aus, die sich selbst sendet:
// aRequest -  
// onReadArchive -     /
client.readArchive(aRequest, onReadArchive);                                                           


Umgekehrte Funktion, um Antworten zu erhalten:
// aResult -  
onReadArchive(aResult) {
  // TODO       

  //   "false",     (    )
  //   "true",      (    ) 
  return false; 
}


Schließlich kamen wir zur Videobearbeitung selbst.

Um das Video zu erstellen, habe ich die Whammy-Javascript-Bibliothek verwendet, weitere Details hier.

Funktion, die das Video erstellt:

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


Leider können Sie nicht in allen Browsern Videos erstellen. Zum Beispiel weiß mein Lieblings-Firefox nicht, wie man Bilder in das WebP-Format konvertiert, auf dessen Grundlage die Konvertierung in Video erfolgt. Und obwohl ich eine Javascript-Bibliothek für eine solche Konvertierung gefunden habe, wurde sie so langsam konvertiert (und es gab so viele Frames), dass ich mich weigerte, sie zu verwenden. In allen Browsern mit der Chrome-Engine funktioniert dies jedoch.

Hier können Sie sehen, was ich getan habe.

Ohne vollständige Dokumentation kann ich meine vorherigen Artikel anbieten.
Artikel 1
Artikel 2

Nun, das ist alles und ich habe nichts mehr zu sagen.

Source: https://habr.com/ru/post/de391773/


All Articles