2014-02-24 81 views
1

我正在嘗試爲android構建ffmpeg。我想用它做兩件事。 1.旋轉視頻 2.加入兩個或更多視頻。Android - ffmpeg最佳方法

在我的應用程序中有兩種使用ffmpeg的方法。 1.使ffmpeg可執行,將其複製到/ data/package /並執行ffmpeg命令。 2.使用ndk構建ffmpeg庫.so文件並編寫jni代碼等。

根據我的需要,哪種方法最適合?我可以有一些遵循這些方法的代碼片段嗎?

+0

看看[鏈接](http://stackoverflow.com/a/20991431/3098658) – BlueSword

回答

2

您可以通過兩種方式實現它,我會第一個做到這一點:

將您的ffmpeg文件到您的原始文件夾中。

就需要通過命令使用ffmpeg的可執行文件,但你需要將文件到文件系統文件夾和更改文件的權限,因此使用此代碼:

public static void installBinaryFromRaw(Context context, int resId, File file) { 
    final InputStream rawStream = context.getResources().openRawResource(resId); 
    final OutputStream binStream = getFileOutputStream(file); 

    if (rawStream != null && binStream != null) { 
     pipeStreams(rawStream, binStream); 

     try { 
      rawStream.close(); 
      binStream.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "Failed to close streams!", e); 
     }  

     doChmod(file, 777); 
    }  
} 
public static OutputStream getFileOutputStream(File file) { 
    try { 
     return new FileOutputStream(file); 
    } catch (FileNotFoundException e) { 
     Log.e(TAG, "File not found attempting to stream file.", e); 
    } 
    return null; 
} 

public static void pipeStreams(InputStream is, OutputStream os) { 
    byte[] buffer = new byte[IO_BUFFER_SIZE]; 
    int count; 
    try { 
     while ((count = is.read(buffer)) > 0) { 
      os.write(buffer, 0, count); 
     } 
    } catch (IOException e) { 
     Log.e(TAG, "Error writing stream.", e); 
    } 
} 
public static void doChmod(File file, int chmodValue) { 
    final StringBuilder sb = new StringBuilder(); 
    sb.append("chmod"); 
    sb.append(' '); 
    sb.append(chmodValue); 
    sb.append(' '); 
    sb.append(file.getAbsolutePath()); 

    try { 
     Runtime.getRuntime().exec(sb.toString()); 
    } catch (IOException e) { 
     Log.e(TAG, "Error performing chmod", e); 
    } 
} 

調用此方法:

private void installFfmpeg() { 
    File ffmpegFile = new File(getCacheDir(), "ffmpeg"); 
    String mFfmpegInstallPath = ffmpegFile.toString(); 
    Log.d(TAG, "ffmpeg install path: " + mFfmpegInstallPath); 
    if (!ffmpegFile.exists()) { 
     try { 
      ffmpegFile.createNewFile(); 
     } catch (IOException e) { 
      Log.e(TAG, "Failed to create new file!", e); 
     } 
     Utils.installBinaryFromRaw(this, R.raw.ffmpeg, ffmpegFile); 
    }else{ 
     Log.d(TAG, "It was installed"); 
    } 

    ffmpegFile.setExecutable(true); 
} 

然後,您將擁有可供命令使用的ffmpeg文件。 (這種方式適用於我,但也有人說它不起作用,我不知道爲什麼,希望它不是你的情況)。然後,我們使用的ffmpeg使用此代碼:

String command = "data/data/YOUR_PACKAGE/cache/ffmpeg" + THE_REST_OF_YOUR_COMMAND; 
     try { 
      Process process = Runtime.getRuntime().exec(command); 
      process.waitFor(); 
      Log.d(TAG, "Process finished"); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

正如我所說的,你必須使用由命令ffmpeg的文件,所以你應該在互聯網上搜索,並選擇您要使用,然後命令,添加它進入命令字符串。如果命令失敗,您將不會收到任何日誌的提醒,因此您應該使用終端模擬器嘗試您的命令並確保其正常工作。如果它不起作用,您將看不到任何結果。

希望它是有用的!

+0

嗨貢薩洛,這個作品完美:)。一個問題,你給我的文件是ffmpeg 0.1.11,我怎麼用最新的ffmpeg重新編譯它? – rohit

+0

Hi rohit。我很高興它的工作原理!你應該再次編譯它,如果你不使用linux,那麼這很困難...看到這個鏈接:http://www.roman10.net/how-to-build-ffmpeg-with-ndk-r9/ –

+0

我用過在linux上也可以使用相同的鏈接來構建ffmpeg。但我仍然無法建立它。 btw鏈接是用於創建libffmpeg.so文件而不是用於ffmpeg可執行文件。 – rohit

1

庫方法的優點是,您可以更好地控制轉換的進度,並可以在中間對其進行調整。另一方面,操作可執行文件則容易一些。最後,你可以簡單地安裝ffmpeg4android app並使用他們的API。

+0

嗨亞歷克斯,我以前試過這個應用程序,但它的商業版本支付。是的,這個應用程序正在滿足我的需求。但我不能支付它的許可證。謝謝。 – rohit

+0

是的,我明白你的限制。其實,我不認爲他們的授權模式是可持續的。但我認爲將其列爲選項之一很重要。 –

+0

是的,我完全同意你的看法。在我看到Gonzalo發佈的答案之前,這是我面前的唯一選擇。我可以用他的答案達到我想要的。 – rohit