2015-04-30 3 views
17

Я использую класс JavaCV FFmpegFrameRecorder для кодирования кадров предварительного просмотра камеры Android в видео.Настройка метаданных видеопотока с использованием Ffmpeg

Цель будет повторить результат следующей командной строки:

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

Я изменил startUnsafe() метод следующим образом, но это не удалось создать желаемый результат:

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); 

Это по-прежнему правильно кодирует видео, но добавленные метаданные никогда не появляются на ffprobe. Если это помогает, кодировка видео - h264.

Кстати, вот выход ffprobe:

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 

Любые предложения о том, почему он не суметь? Благодарю.

+0

Аналогичный вопрос: http://stackoverflow.com/questions/17024192/how-to-set-header-metadata-to-encoded-video –

ответ

1

FFmpegFrameRecorderclass Вы используете AVFormatContextclass. Вокруг линии 2579 вы можете видеть из сигнатуры методов, что AVFormatContext класса использует собственный код для реализации как

  • public native AVDictionary metadata() метод
  • public native AVFormatContext metadata(AVDictionary metadata) метода.

Ответ на ссылку вы предоставили говорит, что они использовали metadata свойство AVFormatContext непосредственно - что-то вроде первого метода я думаю. Но линия 649 от FFmpegFrameRecorder использует второй метод - я подозреваю. то есть:

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

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

К сожалению, я не могу попробовать это на данный момент, но мне интересно, если вы могли бы сделать что-то вроде этого:

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); 

подпись показывает, что общественность, так что я не см., почему вы не можете получить словарь метаданных от AVFormatContext напрямую. Я не уверен, как работает метод avformat_write_header, поэтому я предложил две вещи выше.

Примечание: У меня нет эта библиотека раньше. Я пробовал, безуспешно использовать Xuggler в прошлом для некоторой базовой кодировки.

4

Кажется, этот вопрос вызвал большой интерес, поэтому я добавляю дополнительную информацию. Вслед за этим GitHub issue Сэмюэль из JavaCV committed некоторые изменения, облегчающие доступ к настройкам метаданных.

Установка метаданных может быть достигнуто с помощью следующего фрагмента кода:

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); 

Вы можете включить его прямо сейчас, делая mvn install -Pffmpeg или ждать до следующего выпуска JavacV, который должен быть 0,12.

PS: Как вы можете видеть, это очень похоже на то, что я представил в моем вопросе, поэтому я не уверен, почему он не работал в первую очередь.

Смежные вопросы