오픈소스 연구/FFMPEG
libffmpeg.so for Android
ryujt
2011. 12. 14. 13:16
만들기는 6-8 개월 전에 만들었는데, 프로젝트에 쫓기면서 살다보니 이제서야 올립니다. sws_scale() 함수 및 rtsp 등의 프로토콜을 사용하는데 필요한 모든 코드가 포함되어 있습니다. 배속 재생 및 rtsp 버퍼링 등을 지원하는 플레이어를 만들면서 만들었던 것입니다. FFMPEG의 소스 및 빌드 방법은 http://ryulib.tistory.com/123 를 참고하세요. (http://goo.gl/gTyQ8 에 더 쉽고 자세한 강좌가 있으니 참고하세요)
jni로 한 번 래핑해서 사용하셔야 합니다.
래핑을 하시게 되면, 자신이 만든 jni로 컴파일한 so 파일과 함께 로딩해서 사용하시면 됩니다. 아래는 제가 libryumpeg.so 라는 이름으로 동적 링크 라이브러리를 만들어서 사용하는 경우의 예 입니다.
jni에 대해서는 아래 첨부 파일을 참고 하시기 바랍니다.
jni로 한 번 래핑해서 사용하셔야 합니다.
jstring Java_ryulib_ffmpeg_FFMpeg_getStreamInformation(JNIEnv* env, jclass clazz, jint handle) { FFmpegHandle *pHandle = (FFmpegHandle *) handle; char videoInformation[512]; avcodec_string(videoInformation, sizeof(videoInformation), pHandle->pVideoCtx, 0); char audioInformation[512]; avcodec_string(audioInformation, sizeof(audioInformation), pHandle->pAudioCtx, 0); char result[1024 * 4]; sprintf(result, "%s\n%s", videoInformation, audioInformation ); return (*env)->NewStringUTF(env, result); }
래핑을 하시게 되면, 자신이 만든 jni로 컴파일한 so 파일과 함께 로딩해서 사용하시면 됩니다. 아래는 제가 libryumpeg.so 라는 이름으로 동적 링크 라이브러리를 만들어서 사용하는 경우의 예 입니다.
package ryulib.ffmpeg; import android.graphics.Bitmap; public class FFMpeg { static { System.loadLibrary("ffmpeg"); System.loadLibrary("ryumpeg"); } public static final int Error_General = -1; public static final int Error_Can_Not_Open_File = -2; public static final int Error_Can_Not_Find_StreamInfo = -3; public static final int Error_Can_Not_Find_VidoeStream = -4; public static final int Error_Can_Not_Find_AudioStream = -5; public static final int Error_Can_Not_Open_VideoCodec = -6; public static final int Error_Can_Not_Open_AudioCodec = -7; public static final int UnknownPacket = 0; public static final int VideoPacket = 1; public static final int AudioPacket = 2; public static native String getDebugString(); // openFile(), closeFile(), start(), stop(): Main Thread에서 실행합니다. // start(), stop(): Thread-safe 합니다. // TODO : 파일이 없을 경우 어플리케이션이 죽음 public static native int openFile(String fileName); public static native void closeHandle(int handle); public static native String getStreamInformation(int handle); // openFile() 호출 시, 내부에서 start()를 호출한 상태가 된다. public static native void start(int handle); public static native void stop(int handle); public static native int readFrameToBuffer(int handle); public static native byte[] getAudioData(int handle); public static native int getVideoData(int handle, Bitmap bitmap); public static native int getAudioPacketCount(int handle); public static native int getVideoPacketCount(int handle); // seekByTime(), rewindByTime(), forwardByTime(), readAudioPacket(): 동일한 쓰레드에서 사용되야 합니다. public static native boolean seekByTime(int handle, int ms); public static native boolean rewindByTime(int handle, int ms); public static native boolean forwardByTime(int handle, int ms); public static native int getDuration(int handle); public static native int getPosition(int handle); public static native int getVideoWidth(int handle); public static native int getVideoHeight(int handle); public static native int getSampleRate(int handle); public static native int getChannels(int handle); }
jni에 대해서는 아래 첨부 파일을 참고 하시기 바랍니다.