2015-04-30 6 views
17

Ich verwende die Klasse JavaCV FFmpegFrameRecorder, um die Vorschaubilder von Android in ein Video zu konvertieren.Einstellen von Video-Stream-Metadaten mit Ffmpeg

Das Ziel wäre, das Ergebnis der folgenden Befehlszeile zum Replizieren:

ffmpeg -i input.mp4 -metadata:s:v:0 rotate="90" output.mp4 

I die startUnsafe() Verfahren wie folgt modifiziert, aber es versäumt, die gewünschte Ausgabe zu erzeugen:

if ((video_st = avformat_new_stream(oc, video_codec)) != null) { 
     video_c = video_st.codec(); 
     video_c.codec_id(oformat.video_codec()); 
     video_c.codec_type(AVMEDIA_TYPE_VIDEO); 
     ... 
     AVDictionary avDictionary = new AVDictionary(null); 
     av_dict_set(avDictionary, "rotate", "90", 0); 
     video_st.metadata(avDictionaty); 
     ... 
} 
... 
avformat_write_header(oc, (PointerPointer) null); 

Diese kodiert das Video zwar immer noch korrekt, aber die hinzugefügten Metadaten werden nie in ffprobe angezeigt. Wenn es hilft, ist die Videokodierung h264.

By the way, ist hier die ffprobe Ausgabe:

ffprobe version 2.3.3 Copyright (c) 2007-2014 the FFmpeg developers 
    built on Jan 22 2015 18:22:57 with Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn) 
    configuration: --prefix=/usr/local/Cellar/ffmpeg/2.3.3 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-nonfree --enable-hardcoded-tables --enable-avresample --enable-vda --cc=clang --host-cflags= --host-ldflags= --enable-libx264 --enable-libfaac --enable-libmp3lame --enable-libxvid --enable-libfreetype --enable-libvorbis --enable-libvpx --enable-libass --enable-ffplay --enable-libfdk-aac --enable-libopus --enable-libquvi --enable-libx265 
    libavutil  52. 92.100/52. 92.100 
    libavcodec  55. 69.100/55. 69.100 
    libavformat 55. 48.100/55. 48.100 
    libavdevice 55. 13.102/55. 13.102 
    libavfilter  4. 11.100/4. 11.100 
    libavresample 1. 3. 0/1. 3. 0 
    libswscale  2. 6.100/2. 6.100 
    libswresample 0. 19.100/0. 19.100 
    libpostproc 52. 3.100/52. 3.100 
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'abcd.mp4': 
    Metadata: 
    major_brand  : isom 
    minor_version : 512 
    compatible_brands: isomiso2avc1mp41 
    encoder   : Lavf56.15.102 
    Duration: 00:00:19.48, start: 0.023220, bitrate: 572 kb/s 
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1/0x31637661), yuv420p, 1280x720, 573 kb/s, 5.71 fps, 30 tbr, 15360 tbn, 60 tbc (default) 
    Metadata: 
     handler_name : VideoHandler 
    Stream #0:1(und): Audio: aac (mp4a/0x6134706D), 44100 Hz, mono, fltp, 64 kb/s (default) 
    Metadata: 
     handler_name : SoundHandler 

Irgendwelche Vorschläge auf, warum es versagt? Vielen Dank.

+0

Ähnliche Fragen: http://stackoverflow.com/questions/17024192/how-to-set-header-metadata-to-encoded-video –

Antwort

1

Die FFmpegFrameRecorderclass, die Sie verwenden, verwendet eine AVFormatContextclass. Um die Linie 2579 können Sie aus den Methodensignaturen sehen, dass die AVFormatContext Klasse nativen Code verwendet sowohl

  • public native AVDictionary metadata() Methode
  • public native AVFormatContext metadata(AVDictionary metadata) Verfahren zu implementieren.

Die Antwort auf den Link zur Verfügung gestellt, sagt sie die metadata Eigenschaft der AVFormatContext direkt verwendet - so etwas wie die erste Methode, die ich denke. Aber Zeile 649 von FFmpegFrameRecorder verwendet die zweite Methode - ich vermute. dh:

AVDictionary metadata = new AVDictionary(null); 
... code to fill up dictionary ... 
... 

avformat_write_header(oc.metadata(metadata), options); 

Leider kann ich versuchen, dies nicht im Moment, aber ich frage mich, ob man so etwas tun könnte:

AVDictionary metadata = co.metadata(); 
... code to fill up dictionary ... 

//I would assume at this point that oc has the metadata so 
avformat_write_header(oc, (PointerPointer) null); 
//if not then maybe 
// avformat_write_header(oc.metadata(metadata), options); 

Die Signatur zeigt es öffentlich ist, so dass ich nicht Sehen Sie, warum Sie das Metadatenwörterbuch nicht direkt von AVFormatContext abrufen können. Ich bin mir nicht sicher, wie die avformat_write_header Methode funktioniert, also schlug ich zwei Dinge vor.

Hinweis: Ich habe nicht diese Bibliothek zuvor verwendet. Ich habe vergeblich versucht, Xuggler in der Vergangenheit für einige grundlegende Codierung zu verwenden.

4

Es scheint, dass diese Frage viel Interesse erzeugte, also füge ich noch mehr Informationen hinzu. Im Anschluss daran GitHub issue Samuel von JavaCV committed einige Änderungen, um den Zugriff auf Metadaten-Einstellungen zu erleichtern.

Einstellung Metadaten kann durch die folgenden Code-Schnipsel erreicht werden:

AVDictionary metadata = new AVDictionary(null); 
for (Entry<String, String> e : videoMetadata.entrySet()) { 
    av_dict_set(metadata, e.getKey(), e.getValue(), 0); 
} 
video_st.metadata(metadata); 

Sie können sie ermöglichen jetzt durch mvn install -Pffmpeg tun oder bis zur nächsten JavacV Version warten, die 0,12 sein sollte.

PS: Wie Sie sehen können, ist dies ziemlich ähnlich zu dem, was ich in meiner Frage vorgestellt habe, also bin ich mir nicht sicher, warum es überhaupt nicht funktioniert hat.