Als ich von der indischen „Microsoft“-Abteilung angerufen wurde, ließ ich sie auf meiner virtuellen VirtualBox-Maschine mitmachen und startete eine Videoaufnahme, um alle Details über sie festzuhalten. Dabei erstellt VirtualBox .webm-Videodateien.
Wenn ich diese Webm-Datei jetzt abspiele, sehe ich jedoch, dass sie genau dort verstümmelt wurde, wo ich die Auflösung der VM geändert habe. Die Sitzung dauerte eine Stunde (puh ...), und am Ende gelang es mir, ihre vergeblichen Hackversuche zu vereiteln, ein Systemkennwort auf meinem Computer festzulegen, und loggte mich stattdessen wieder in die Verbindung ein, die sie dann trennten. Ich glaube, ich habe dann eine Dashboard-Umgebung im Vollbildmodus gesehen - vielleicht ihre? Könnte einige sehr nützliche Informationen haben, wenn dies wahr ist!
Das Verstümmeln scheint nur ein Problem mit der Scanline-Länge im Videostream zu sein. Das Schwierige dabei ist, dass das Video selbst korrekt in einer Auflösung von 1024 x 768 vorliegt, die Nutzlast jedoch nur ein 800 x 600-Bereich in der Mitte ist (mit schwarzen Rändern drumherum). Dieser innere Bereich wurde im Video weiter durcheinander gebracht. Die schwarzen Ränder bleiben in Ordnung, also ist nur der Quelldatenstrom von VirtualBox für den mittleren Teil falsch ausgerichtet.
Kennt jemand ein Verfahren oder eine Software, mit der ich versuchen könnte, dieses Video zu entzerren? Ich habe bereits gesehen, dass Webm-Videodateien einen Matroska-basierten Standard verwenden und eine EBML-Codierung verwenden; Ich habe bereits versucht, einige Header-Werte in der EBML-Struktur zu ändern, um die Anzeigeauflösung zu verfälschen (wobei die schwarzen Ränder falsch ausgerichtet sind, aber die mittlere Nutzlast in Ordnung ist), aber das hat schnell nirgendwohin geführt (jede 5 Sekunden Video oder so hat einen eigenen Header-Block wie Gut).
Zusatz:
Um genau zu sein: Das Video wurde mit 1024x786 Pixel gerendert, während die virtuelle Maschine mit 800x600 lief. Dies führt zu einem dicken schwarzen Rand, der den inneren erfassten Inhalt während des gesamten Videos umgibt. Nachdem ich die Fenstergröße der virtuellen Maschine erhöht hatte (z. B. auf 1200 x 650 – ich konnte es wirklich nicht genau sagen), blieb der schwarze Rand in seiner Größe gleich, nur der innere Inhalt darin wurde verstümmelt. Mit verstümmelt meine ich, dass es so aussieht, als würde es die jetzt längeren Scanzeilen von 1200 Pixeln anzeigen und sie in die 800-Scanzeilenlänge einwickeln, sodass jede nächste echte Scanzeile um den horizontalen Größenunterschied versetzt wird, da die vorherige Zeile darin eingewickelt ist. Zumindest dachte ich das anfangs, aber wenn ich es mir noch einmal ansehe, habe ich auch meine Zweifel an dieser Theorie.
Nun - das ist überhaupt nicht klar :) Ich habe hier einen Frame hochgeladen: und hier ein kurzes Videofragment: kurzes Fragment eines Betrugsvideos (das Problem tritt in der Mitte des Fragments auf)
Aber um ehrlich zu sein, denke ich, dass ich besser aufgeben sollte. Ich fange an zu vermuten, dass die einzig mögliche Lösung darin besteht, Pixelgrabbing in den alten Frames durchzuführen und daraus ein neues Video zu erstellen, wenn das überhaupt eine Lösung ist - dh zu viel Aufwand. Schade aber, da ich den Inhalt am Ende wirklich gerne noch einmal Revue passieren lassen würde...
Lösung:
Dank bukkojot habe ich die folgende (auf Windows ausgerichtete) App entwickelt, die in die Mitte der von ihm angegebenen ffmpeg-cmdline passt; vielleicht kann es jemand nützlich finden? Beachten Sie, dass das "RGB24" in der cmdline "rgb24" sein muss, wenn Sie die neueste ffmpeg-Version unter Windows verwenden, was die cmdline bringt, die ich verwendet habe:
ffmpeg.exe -i scamvideo_problem.webm -f rawvideo -pix_fmt rgb24 pipe: | restorer.exe | ffmpeg -f rawvideo -pix_fmt rgb24 -s 1103x436 -i pipe: -vcodec libx264 resolvedvideo.avi
Das Video war lesbar (abgesehen von Farbverschiebungen), und alle hineingezogenen Parteien wurden benachrichtigt (iTunes, Gmail, TeamViewer und VICIdial).
Wie auch immer, das ist der C++-Code, den ich letztendlich verwendet habe:
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <Windows.h>
using namespace std;
int main() {
const size_t inLineSize = 1024 * 3;
const size_t inFrameSize = 1024 * 768 * 3;
const size_t outFrameSize = 1103 * 436 * 3;
const size_t inPayloadLineSize = 800 * 3;
const size_t inPayloadNumLines = 600;
const size_t inPayloadFrameSize = inPayloadLineSize * inPayloadNumLines;
const size_t inTopBorderNumLines = 84;
const size_t inLeftBorderNumPixels = 112;
const size_t inPayloadOffset = inLineSize * inTopBorderNumLines + inLeftBorderNumPixels * 3;
const size_t outPadSize = outFrameSize - inPayloadFrameSize;
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
char* inFrame = new char[inFrameSize];
char* outPadding = new char[outPadSize];
memset(outPadding, 0, outPadSize);
while (!feof(stdin)) {
size_t sizeLeft = inFrameSize;
char* nextReadPos = inFrame;
while (!feof(stdin) && sizeLeft > 0) {
size_t bytesRead = fread(nextReadPos, 1, sizeLeft, stdin);
sizeLeft -= bytesRead;
nextReadPos += bytesRead;
if (sizeLeft > 0) {
Sleep(100);
}
}
if (!feof(stdin)) {
char* inPayloadPos = inFrame;
inPayloadPos += inPayloadOffset;
for (size_t inLineNr = 0; inLineNr < inPayloadNumLines; ++inLineNr, inPayloadPos += inLineSize) {
fwrite(inPayloadPos, 1, inPayloadLineSize, stdout);
}
fwrite(outPadding, 1, outPadSize, stdout);
}
}
return 0;
}
Nach ein bisschen Manipulation... Siehst du...
Der einfachste Weg für Sie:
Schreiben Sie eine sehr einfache App in C, die 1024 * 768 * 3 Bytes liest und mit Nullen auf 1327 * 768 * 3 Bytes auffüllt. Es ist einfach für Sie.
Geben Sie Rohpixel mit ffmpeg aus, leiten Sie Daten an Ihre App weiter, leiten Sie Daten an ffmpeg zurück
So etwas wie:
ffmpeg -i scamvideo.avi -f rawvideo -pix_fmt RGB24 - | ./a.out | ffmpeg -f rawvideo -pix_fmt RGB24 -s 1327x768 -i - -vcodec libx264 newvideo.avi
Alle anderen Optionen nach Ihrem Geschmack. Ich denke, Sie haben eine Idee.
Gyan
Karl Colijn