[英]Setting video stream metadata using Ffmpeg
我正在使用JavaCV FFmpegFrameRecorder類將Android的相機預覽幀編碼為視頻。
目標是復制以下命令行的結果:
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
有關為什么失敗的任何建議? 謝謝。
看來這個問題產生了很多興趣所以我正在添加更多信息。 遵循此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:正如你所看到的,這與我在問題中提出的非常相似,所以我不確定為什么它首先不起作用。
該FFmpegFrameRecorder
類使用的是采用了AVFormatContext
類 。 在第2579行,您可以從方法簽名中看到, AVFormatContext
類使用本機代碼來實現這兩者
public native AVDictionary metadata()
方法 public native AVFormatContext metadata(AVDictionary metadata)
方法。 您提供的鏈接的答案表明他們直接使用了AVFormatContext
的metadata
屬性 - 就像我認為的第一種方法。 但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進行一些基本的編碼是不成功的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.