2014-02-24 3 views
1

나는 안드로이드에 대한 ffmpeg를 구축하려고합니다. 나는 그것으로 두 가지를 이루고 싶다. 1. 비디오를 회전하십시오. 2. 둘 이상의 비디오를 결합하십시오.안드로이드 - ffmpeg 최상의 접근

내 응용 프로그램에서 ffmpeg를 사용하는 데는 두 가지 방법이 있습니다. 1. ffmpeg 실행 파일을/data/package /로 복사하고 ffmpeg 명령을 실행합니다. 2. ffmpeg 라이브러리 .so 파일을 ndk로 빌드하고 jni 코드 등을 작성하십시오.

내 요구 사항에 따라 어떤 접근 방식이 가장 좋습니까? 그런 접근법을 따르는 코드 스 니펫을 만들 수 있습니까?

+0

[link] (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

안녕하세요. 나는 그것이 작동하게되어 기쁘다! 다시 컴파일해야하고 리눅스를 사용하지 않으면 매우 어렵습니다.이 링크를보십시오 : http://www.roman10.net/how-to-build-ffmpeg-with-ndk-r9/ –

+0

제가 사용했습니다. 리눅스에서 ffmpeg를 빌드하기위한 동일한 링크. 그러나 나는 아직도 그것을 지을 수 없다. 그리고 btw link는 libffmpeg.so 파일을 만들고 ffmpeg를 실행하기위한 것이 아닙니다. – rohit

1

라이브러리 접근법의 장점은 변환 진행 상황을보다 잘 제어 할 수 있고 중간에 조정할 수 있다는 것입니다. 다른 한편으로는, 실행 파일을 조작하는 것이 약간 쉽습니다. 마지막으로 ffmpeg4android app을 설치하고 해당 API로 작업 할 수 있습니다.

+0

안녕하세요 알렉스, 전에이 응용 프로그램을했지만 상용 버전이 지급됩니다. 그리고 네,이 응용 프로그램은 내 필요를 충족시키고 있습니다. 그러나 나는 면허증을 가질 여유가 없다. 감사. – rohit

+0

네, 귀하의 한계를 이해합니다. 사실, 나는 그들의 라이센싱 모델이 지속 가능하다고 생각하지 않는다. 그러나 그것을 옵션 중 하나로 나열하는 것이 중요하다고 생각합니다. –

+0

예, 전적으로 당신에게 동의합니다. Gonzalo가 올린 답변을보기 전에는 내 앞에서 유일한 옵션이었습니다. 나는 그의 대답을 사용하여 내가 원하는 것을 얻을 수있다. – rohit

관련 문제