簡體   English   中英

FFMPEG創建用於將原始幀添加到AVI文件的內部管道(無輸入文件)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM