Fix 3GP-Datei nach dem Streaming von Android Media Recorder

Ich versuche, Video von Android-Kamera über lokale Unix-Socket Stream und schreiben Datei aus Stream zu SDD. Alles funktioniert gut, außer Datei ist bei jedem Spieler nicht abspielbar. Es ist, weil Android nicht füllen einige Lücken in der Datei, weil Sockel ist nicht suchbar. Wie ich verstehe, muss ich einige Änderungen vornehmen, nachdem der Videostream vorbei ist. Ich habe hier mehrere Artikel gelesen, aber keiner von ihnen hat mir geholfen Ich spiele mit Hex-Editor, um zu lernen, wie man es manuell macht, also danach wird es trivial, dasselbe im Android-Code zu tun.

Hier ist eine Beispieldatei, die aus dem Stream gespeichert wurde: https://dl.dropbox.com/u/17510473/sample_not_playable.3gp

Kann jemand reparieren, um es spielbar zu machen und zu erzählen, wie er es getan hat?

EDIT: Ich lösche den Header der 3GP-Datei und schreibe neue wie folgt:

00 00 00 18 66 74 79 70 33 67 70 34 00 00 03 00 33 67 70 34 33 67 70 36 00 00 00 00 

Dann finde ich Startort von mdat und moov Atomen mit folgendem Befehl:

 grep -aobE "ftyp|mdat|moov" sample_not_playable.3gp 

Und es gibt mir folgende Ausgabe:

 4:ftyp 28:mdat 1414676:moov 

Dann machen 1414676 - 28 = 1,414,648 = 0x1595F8

Dann schreibe ich 0x1595F8 als 25-28 Bytes, gerade vorher mdat Atom. So sieht mein header jetzt so aus:

 00 00 00 18 66 74 79 70 33 67 70 34 00 00 03 00 33 67 70 34 33 67 70 36 00 15 95 F8 

Und wenn ich versuche, es mit mplayer zu spielen, bekomme ich beschädigte Video- und Audioausgaben. Hier ist ein Teil von mplayer output:

 [amrwb @ 0x7f72ad652380]Frame too small (33 bytes). Truncated file? [amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame [amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame [amrwb @ 0x7f72ad652380]Frame too small (33 bytes). Truncated file? [amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame [amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame [amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame A: 11.0 V: 1.4 AV: 9.650 ct: 0.023 0/ 0 10% 1% 1.6% 0 0 [mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f72adeafc40]stream 1, offset 0x15e62b: partial file [h263 @ 0x7f72ad652380]Bad picture start code [h263 @ 0x7f72ad652380]header damaged Error while decoding frame! [h263 @ 0x7f72ad652380]Bad picture start code [h263 @ 0x7f72ad652380]header damaged Error while decoding frame! [h263 @ 0x7f72ad652380]Bad picture start code [h263 @ 0x7f72ad652380]header damaged Error while decoding frame! A: 11.1 V: 1.5 AV: 9.558 ct: 0.027 0/ 0 9% 1% 1.4% 0 0 [h263 @ 0x7f72ad652380]Bad picture start code [h263 @ 0x7f72ad652380]header damaged Error while decoding frame! 

Was mache ich falsch?

  • Verwenden Sie MediaCodec für das H264-Streaming
  • Android ffmpeg und Hardwarebeschleunigung
  • Streaming von Video-Kamera auf Server
  • Android wie Video-Aufnahme, Upload, Transcode, Download, spielen
  • Android - Stream Kamera als RTMP Stream
  • Getting YouTube Video ID mit Parametern
  • Ausnahme beim Aufruf der setDataSource (FileDescriptor) Methode (fehlgeschlagen .: status = 0x80000000)
  • Android VideoView stoppen Streaming nach bestimmten Zeit
  • 2 Solutions collect form web for “Fix 3GP-Datei nach dem Streaming von Android Media Recorder”

    Was Sie verstehen müssen, ist, dass mp4 kein Live- Stream-Format ist. Daher gibt es keine Möglichkeit, dass du in der Lage bist, irgendwie herum zu hacken, um es live zu machen. Der Header [moov atom] steht am Ende. Android erstellt eine in Arbeitstabelle von Rahmengrößen und anderen Parametern, die sie dann am Anfang der Datei am Ende der Aufzeichnung schreibt, weshalb sie die Suchbarkeit des Dateizugriffs benötigt. [Was eine Steckdose nicht ist]

    Wenn du verschlüsselte Inhalte auf die Festplatte schreibst und du es tun möchtest, damit niemand die Datei abspielen kann, musst du die ganze Datei nicht verschlüsseln. Sie müssen nur den Header verschlüsseln und die gesamte Datei ist nicht abspielbar.

    Wenn du dringend eine vollständige Dateikodierung benötigst, weil du nicht von meinem vorherigen Para überzeugt bist, dann benutze etwas wie ffmpeg, um die Codierung zu machen. Ändern Sie es geben Ihnen verschlüsselte Ausgabe selbst und speichern Sie es auf Festplatte wieder – entfernt den Socket-Teil wieder.

    Es gibt keine Möglichkeit, können Sie Live- Streaming von mp4-Dateien in Android zu tun. Ich habe Tonnen von Leuten gesehen, die es vergeblich ausprobieren und wenn du Video / Formate verstehst, gibt es keine Möglichkeit, dass du es tun kannst. Mp4 ist nicht für Live-Streaming konzipiert. Es sei denn, du kennst deine Baugrößen im Voraus [was du nicht machst] und die genaue Länge der Kodierung [die du am ehesten don t t] kannst du den Header nicht vorschaffen.

    Ps Mp4 und 3gp sind Cousins ​​so dasselbe gilt.

    Viele Menschen verwirren Live-Streaming mit http pd und Pseudo-Streaming. Live-Streaming bedeutet, dass ich nicht die ganze Datei habe, es wird erstellt und auch gestreamt. Http pd und pseudo streaming finden mit Dateien, die vollständig verfügbar sind.

    BEARBEITEN:

    Wenn Ihr Ziel ist, die aufgenommene Datei zu verschlüsseln, bevor Sie in sdcard speichern, benötigen Sie Encoderunterstützung. Das bedeutet, dass du hier deinen eigenen Encoder bekommst. Nehmen Sie ffmpeg, kreuzen Sie es zu android. Schreiben Sie eine kleine JNI-Schnittstelle für Ihre Anwendung. Holen Sie dies zuerst ohne Verschlüsselung. Einmal getan, wo ffmpeg den Stream schreibt, füge dein Verschlüsselungsmodul hinzu. Gleiche Sache beim Decodieren. Y3ng Schaffung. Dies ist der sauberste Weg, es zu tun.

    BEARBEITEN 2: Sei spärlich, um einige der Features für dich zu bekommen. Es gibt ähnliche da draußen.

    EDIT 3: Um die Qualität der Antwort zu verbessern, erkläre ich eine unvollkommene Umgehung, die auch durch andere Antworten gegeben ist:

    Man kann den AV noch durch das Parsen des mp4 streamen, wie es erzeugt wird und sendet die elementaren Ströme separat über eine Steckdose. Das einzige Problem, das Sie sehen werden, ist, dass Sie nicht perfekt AV Sync bekommen, da Sie nicht wissen, die genaue AV Probe Zeitstempel. Nur Android weiß das und es schreibt das im mp4-Header am Ende. Also nicht gut für dich Sie müssen eine Annahme auf eine perfekte Abtastrate von Videorahmen machen und Ihr Audio muss amr sein, um 20ms Pakete anzunehmen. In anderen Audio-Fällen fangen Sie an, Drift in langen Läufen zu sehen [besonders dort, wo Sie beginnen, Szenen der hohen Bewegung zu haben]. Dies liegt daran, dass jedes erzeugte Audiopaket nicht einer festen Zeitdauer entspricht [außer für amr und andere Sprachcodecs]

    Zunächst einmal ist es nicht ganz klar, was du zu tun versuchst.

    Möchtest du nur ein Video programmgesteuert zu einer abspielbaren Datei speichern? Wenn ja, müssen Sie nur Datei-Deskriptor anstelle von Unix-Socket verwenden. Diese API von MediaRecord wurde entworfen, um mit einer Datei (nicht Unix-Socket) zu arbeiten, genau aus dem Grund des zufälligen Zugriffs. Also, mein erster Rat wäre, Dateideskriptor zu verwenden und du bekommst die korrekte Datei am Ende der Aufnahme.

    Sie können hier Beispiele bekommen: Wie kann ich eine Videoaufnahme auf Android aufnehmen?

    In dem Fall, wenn Sie versuchen, eine Anwendung zu schreiben, die Video von Gerät streamt, müssen Sie den Stream in einem Echtzeit zu analysieren, teilen Sie es durch Frames und senden Frames separat. Und der komplizierteste Teil analysiert den Stream (einige Video-Codecs, wie zB H263 analysiert werden kann und andere nicht sein können, besonders wenn die Daten mit dem Audio verschachtelt sind).

    Ich glaube, eines dieser beiden Projekte implementiert solche Funktionalität: http://sipdroid.org/ http://code.google.com/p/imsdroid/

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.