java - v136 - Configuración de metadatos de flujo de video usando Ffmpeg
v136 youtube get video (2)
La FFmpegFrameRecorder FFmpegFrameRecorder
que está utilizando utiliza una class AVFormatContext
. Alrededor de la línea 2579 se puede ver en las firmas del método, que la clase AVFormatContext
usa código nativo para implementar ambos
-
public native AVDictionary metadata()
-
public native AVFormatContext metadata(AVDictionary metadata)
.
La respuesta al enlace que proporcionó dice que usaron la propiedad de metadata
de AVFormatContext
directamente, algo así como el primer método, creo. Pero la línea 649 de FFmpegFrameRecorder
utiliza el segundo método, sospecho. es decir:
AVDictionary metadata = new AVDictionary(null);
... code to fill up dictionary ...
...
avformat_write_header(oc.metadata(metadata), options);
Desafortunadamente, no puedo intentar esto en este momento, pero me pregunto si podrías hacer algo como esto:
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);
La firma muestra que es público, por lo que no veo por qué no puede obtener el diccionario de AVFormatContext
directamente desde AVFormatContext
. No estoy seguro de cómo funciona el método avformat_write_header
, así que sugerí dos cosas arriba.
Nota : no he usado esta biblioteca antes. Intenté, sin éxito, utilizar Xuggler en el pasado para una codificación básica.
Estoy usando la clase JavaCV FFmpegFrameRecorder para codificar los marcos de vista previa de la cámara de Android en un video.
El objetivo sería replicar el resultado de la siguiente línea de comando:
ffmpeg -i input.mp4 -metadata:s:v:0 rotate="90" output.mp4
startUnsafe()
método startUnsafe()
siguiente manera, pero no se pudo generar la salida deseada:
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);
Esto aún codifica el video correctamente, pero los metadatos agregados nunca aparecen en ffprobe. Si ayuda, la codificación del video es h264.
Por cierto, aquí está la salida de 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
¿Alguna sugerencia sobre por qué está fallando? Gracias.
Parece que esta pregunta generó mucho interés, así que estoy agregando más información. Después de este problema de GitHub, Samuel de JavaCV realizó algunos cambios para permitir un acceso más fácil a la configuración de metadatos.
La configuración de metadatos se puede lograr a través del siguiente fragmento de código:
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);
Puede habilitarlo ahora mismo haciendo mvn install -Pffmpeg
o espere hasta la próxima versión de JavacV, que debería ser 0.12.
PD: Como puede ver, esto es bastante similar a lo que presenté en mi pregunta, así que no estoy seguro de por qué no funcionó en primer lugar.