使用Ffmpeg设置videostream元数据

我正在使用JavaCV FFmpegFrameRecorder类将Android的相机预览帧编码到video中。

目标是复制以下命令行的结果:

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

这仍然正确地编码video,但添加的元数据不会出现在ffprobe上。 如果有帮助,video编码是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 

有什么build议,为什么它失败? 谢谢。

Solutions Collecting From Web of "使用Ffmpeg设置videostream元数据"

看来这个问题产生了很多的兴趣,所以我添加了一些更多的信息。 在这个GitHub问题之后,来自JavaCV的Samuel进行了一些更改,以便更容易地访问元数据设置。

设置元数据可以通过以下代码片段来实现:

 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:正如你所看到的,这与我提出的问题非常相似,所以我不确定它为什么不起作用。

您正在使用的AVFormatContext 类使用AVFormatContext 类 。 在第2579行左右,你可以从方法签名中看到, AVFormatContext类使用本地代码来实现两者

  • public native AVDictionary metadata()方法
  • public native AVFormatContext metadata(AVDictionary metadata)方法。

你提供的链接的答案是他们直接使用AVFormatContextmetadata属性 – 就像我想的第一种方法。 但FFmpegFrameRecorder 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做了一些基本的编码。