I'm using the JavaCV FFmpegFrameRecorder class to encode Android's camera preview frames into a video.
The goal would be to replicate the result of the following command line:
ffmpeg -i input.mp4 -metadata:s:v:0 rotate="90" output.mp4
I modified the startUnsafe()
method as follows, but it failed to generate the desired output:
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);
This still encodes the video correctly, but the added metadata never appears on ffprobe. If it helps, the video encoding is h264.
By the way, here's the ffprobe output:
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
Any suggestions on why is it failing? Thanks.
Just add use the -metadata in FFmpeg to add any metadata tag, replace the KEY with the name of the metadata value that you'd like to use and the VALUE with that metadata value. Look at the tags for these files with mkvinfo, mediainfo, and ffprobe. You can also add metadata specifically to certain tracks.
The use of –probesize and –analyzeduration help FFMPEG to recognize the audio and video stream parameters of a file, and while they are by no means necessary, their use can help reduce input processing errors, especially when moving across codecs.
What I also know is that MediaInfo does not use ffmpeg under the hood.
It seems this question generated a lot of interest so I'm adding some more info. Following this GitHub issue Samuel from JavaCV committed some changes to allow easier access to metadata settings.
Setting metadata can be achieved through the following code snippet:
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);
You can enable it right now by doing mvn install -Pffmpeg
or wait until the next JavacV release, which should be 0.12.
PS: As you can see, this is pretty similar to what I presented in my question, so I'm not sure why it didn't work in the first place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With