[英]FFMPEG Create internal pipeline for adding raw frames to AVI file (no input file)
我有一个应用程序,该应用程序读取原始视频文件,对每个帧进行一些图像处理,然后将生成的BGRA格式的byte []帧提供给FFMPEG容器,最终创建一个AVI文件。 由于此过程与我所看到的任何其他FFMPEG示例略有不同,因为它没有现有的输入文件,所以我想知道是否有人知道如何执行此操作。
我初始化FFMPEG容器:
ProcessBuilder pBuilder = new ProcessBuilder(raid.getLocation()
+ "\\ffmpeg\\bin\\ffmpeg.exe", "-r", "30", "-vcodec",
"rawvideo", "-f", "rawvideo", "-pix_fmt", "bgra", "-s",
size, "-i", "pipe:0", "-r", "30", "-y", "-c:v", "libx264",
"C:\export\2015-02-03\1500\EXPORT6.avi");
try
{
process = pBuilder.start();
}
catch (IOException e)
{
e.printStackTrace();
}
ffmpegInput = process.getOutputStream();
对于每个传入的byte []数组帧,我将其添加到容器中(“ src”是我要转换为字节数组的BufferedImage):
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(src, ".png", baos);
ffmpegInput.write(baos.toByteArray());
}
catch (IOException e)
{
e.printStackTrace();
}
视频加载完帧后,我关闭容器:
try
{
ffmpegInput.flush();
ffmpegInput.close();
}
catch (IOException e)
{
e.printStackTrace();
}
AVI文件已创建,但在打开时显示错误。 FFMPEG记录器将其显示为错误:
ffmpeg version N-71102-g1f5d1ee Copyright (c) 2000-2015 the FFmpeg developers built with gcc 4.9.2 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib
libavutil 54. 20.101 / 54. 20.101
libavcodec 56. 30.100 / 56. 30.100
libavformat 56. 26.101 / 56. 26.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 13.101 / 5. 13.101
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100
Input #0, rawvideo, from 'pipe:0':
Duration: N/A, bitrate: 294912 kb/s
Stream #0:0: Video: rawvideo (BGRA / 0x41524742), bgra, 640x480, 294912 kb/s, 30 tbr, 30 tbn, 30 tbc
No pixel format specified, yuv444p for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.
[libx264 @ 00000000003bcbe0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2
[libx264 @ 00000000003bcbe0] profile High 4:4:4 Predictive, level 3.0, 4:4:4 8-bit
Output #0, avi, to 'C:\export\2015-02-03\1500\EXPORT6.avi':
Metadata:
ISFT : Lavf56.26.101
Stream #0:0: Video: h264 (libx264) (H264 / 0x34363248), yuv444p, 640x480, q=-1--1, 30 fps, 30 tbn, 30 tbc
Metadata:
encoder : Lavc56.30.100 libx264
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
frame= 0 fps=0.0 q=0.0 Lsize= 6kB time=00:00:00.00 bitrate=N/A
video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)
任何见解或想法将不胜感激!
用以下内容替换ProcessBuilder
内容:
new ProcessBuilder(PATHOFYOURFFMPEG, "-r", "30", "-s", SIZEOFYOURFRAME,
"-vcodec", "rawvideo", "-f", "rawvideo", "-pix_fmt", "bgra", "-i",
"pipe:0", "-r", "30", PATHANDFILEEXTENTION);
基本上,这就是说输入帧以30 fps的速度输入,其编解码器和格式为rawvideo,像素格式为“ bgra
”(此处的拼写很重要。我拼错了这一点,并花了我一个工作日bgra
弄清楚)。 输入是pipe:0
。 (例如,对于stdin为0,对于stdout为1,对于stderr为2)。 令人困惑的部分是在Java方面,您必须从进程中获取其“ OutputStream
”并将帧数据( byte []
)作为ffmpeg的stdin传递。 很困惑吗?
最后,我再次重新定义了-r
和“ 30”。 这不是一个错误。 因此,基本上-i之前的内容用于输入,而-i
之后定义的内容用于输出! 所以在这里我只是说输出视频也将是30 fps。 希望这可以帮助!!!
PS:我试图将byte[]
传递到队列和数组列表以进行缓存。 由于某些原因,Java一遍又一遍只缓存1个副本。 在我弄清楚这一点时,已经过去了半天。 因此,在将数据传递到ffmpeg之前,请先对其进行框架化处理。
我相信将[ ffmpeg_folder
] /bin
添加到%PATH%
然后调用
ffmpeg .
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.