How to Build Android Applications Based on FFmpeg by An Example
来源:互联网 发布:淘宝 收藏夹 被挤爆了 编辑:程序博客网 时间:2024/05/17 21:43
This is a follow up post of the previous blog How to Build FFmpeg for Android. You can read the previous tutorial first, or refer back to it when you feel necessary.
This blog covers how to build a simple Android app based on FFmpeg library. The app will detect the input video file’s resolution and codec information through interface provided by FFmpeg.
Blow is a screenshot of the app,
0. Create a new Android Project FFmpegTest.
When you’re asked to select targeted platform, select 2.2 as it’s the platform used in previous blog. But you’re free to change it.
Also create a folder named jni under the root directory “FFmpegTest” of this project.
1. Download the ffmpeg Source Code and Extract it to jni Folder
Follow the previous blog How to Build FFmpeg for Android to build the library.
2. Write the Native Code that use FFmpeg’s libavcodec library.
You can copy and paste the code below and save it as ffmpeg-test-jni.c under FFmpegTest/jni/ directory. Note that the code below is not completed, you can download the entire code at the end of the post.
/*for android logs*/#define LOG_TAG "FFmpegTest"#define LOG_LEVEL 10#define LOGI(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__);}#define LOGE(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__);}char *gFileName; //the file name of the videoAVFormatContext *gFormatCtx;int gVideoStreamIndex; //video stream indexAVCodecContext *gVideoCodecCtx;static void get_video_info(char *prFilename);static void get_video_info(char *prFilename) { AVCodec *lVideoCodec; int lError; /*register the codec*/ extern AVCodec ff_h264_decoder; avcodec_register(&ff_h264_decoder); /*register demux*/ extern AVInputFormat ff_mov_demuxer; av_register_input_format(&ff_mov_demuxer); /*register the protocol*/ extern URLProtocol ff_file_protocol; av_register_protocol2(&ff_file_protocol, sizeof(ff_file_protocol)); /*open the video file*/ if ((lError = av_open_input_file(&gFormatCtx, gFileName, NULL, 0, NULL)) !=0 ) { LOGE(1, "Error open video file: %d", lError); return; //open file failed } /*retrieve stream information*/ if ((lError = av_find_stream_info(gFormatCtx)) < 0) { LOGE(1, "Error find stream information: %d", lError); return; } /*find the video stream and its decoder*/ gVideoStreamIndex = av_find_best_stream(gFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &lVideoCodec, 0); if (gVideoStreamIndex == AVERROR_STREAM_NOT_FOUND) { LOGE(1, "Error: cannot find a video stream"); return; } else { LOGI(10, "video codec: %s", lVideoCodec->name); } if (gVideoStreamIndex == AVERROR_DECODER_NOT_FOUND) { LOGE(1, "Error: video stream found, but no decoder is found!"); return; } /*open the codec*/ gVideoCodecCtx = gFormatCtx->streams[gVideoStreamIndex]->codec; LOGI(10, "open codec: (%d, %d)", gVideoCodecCtx->height, gVideoCodecCtx->width); if (avcodec_open(gVideoCodecCtx, lVideoCodec) < 0) { LOGE(1, "Error: cannot open the video codec!"); return; }}JNIEXPORT void JNICALL Java_roman10_ffmpegTest_VideoBrowser_naInit(JNIEnv *pEnv, jobject pObj, jstring pFileName) { int l_mbH, l_mbW; /*get the video file name*/ gFileName = (char *)(*pEnv)->GetStringUTFChars(pEnv, pFileName, NULL); if (gFileName == NULL) { LOGE(1, "Error: cannot get the video file name!"); return; } LOGI(10, "video file name is %s", gFileName); get_video_info(gFileName);}JNIEXPORT jstring JNICALL Java_roman10_ffmpegTest_VideoBrowser_naGetVideoCodecName(JNIEnv *pEnv, jobject pObj) { char* lCodecName = gVideoCodecCtx->codec->name; return (*pEnv)->NewStringUTF(pEnv, lCodecName);}
If you’re not familiar with Java JNI, you may need to read about JNI first in order to understand the code. But this is not the focus of this tutorial hence not covered.
3. Build the Native Code.
Create a file named Android.mk under jni directory and copy paste the content below,
LOCAL_PATH := $(call my-dir) #declare the prebuilt library include $(CLEAR_VARS) LOCAL_MODULE := ffmpeg-prebuilt LOCAL_SRC_FILES := ffmpeg-0.8/android/armv7-a/libffmpeg.so LOCAL_EXPORT_C_INCLUDES := ffmpeg-0.8/android/armv7-a/include LOCAL_EXPORT_LDLIBS := ffmpeg-0.8/android/armv7-a/libffmpeg.so LOCAL_PRELINK_MODULE := true include $(PREBUILT_SHARED_LIBRARY) #the ffmpeg-test-jni library include $(CLEAR_VARS) LOCAL_ALLOW_UNDEFINED_SYMBOLS=false LOCAL_MODULE := ffmpeg-test-jni LOCAL_SRC_FILES := ffmpeg-test-jni.c LOCAL_C_INCLUDES := $(LOCAL_PATH)/ffmpeg-0.8/android/armv7-a/include LOCAL_SHARED_LIBRARY := ffmpeg-prebuilt LOCAL_LDLIBS := -llog -ljnigraphics -lz -lm $(LOCAL_PATH)/ffmpeg-0.8/android/armv7-a/libffmpeg.so include $(BUILD_SHARED_LIBRARY)
Create another file named Application.mk under jni directory and copy paste the content below,
# The ARMv7 is significanly faster due to the use of the hardware FPU APP_ABI := armeabi-v7a APP_PLATFORM := android-8
For more information about what Android.mk and Application.mk do, you can refer to the documentation comes with android NDK.
Your folder structure should be something like below after you finish all steps above,
4. Call the Native Code from FFmpegTest Java Code.
You’ll need to load the libraries and declare the jni functions. The code below is extracted from the app source code, which is provided for download at the end of this tutorial.
/*this part communicates with native code through jni (java native interface)*/ //load the native library static { System.loadLibrary("ffmpeg"); System.loadLibrary("ffmpeg-test-jni"); } //declare the jni functions private static native void naInit(String _videoFileName); private static native int[] naGetVideoResolution(); private static native String naGetVideoCodecName(); private static native String naGetVideoFormatName(); private static native void naClose(); private void showVideoInfo(final File _file) { String videoFilename = _file.getAbsolutePath(); naInit(videoFilename); int[] prVideoRes = naGetVideoResolution(); String prVideoCodecName = naGetVideoCodecName(); String prVideoFormatName = naGetVideoFormatName(); naClose(); String displayText = "Video: " + videoFilename + "\n"; displayText += "Video Resolution: " + prVideoRes[0] + "x" + prVideoRes[1] + "\n"; displayText += "Video Codec: " + prVideoCodecName + "\n"; displayText += "Video Format: " + prVideoFormatName + "\n"; text_titlebar_text.setText(displayText); }
5. You can Download the Entire Source Code from here.
Note: the code is tested on Ubuntu 10.04 and Android ndk-5b, but it should work on other platforms (except for Windows, which I’m not sure about.)
转贴:http://www.roman10.net/how-to-build-android-applications-based-on-ffmpeg-by-an-example/- How to Build Android Applications Based on FFmpeg by An Example
- How to Build Android Applications Based on FFmpeg by An Example
- How to Build Android Applications Based on FFmpeg by An Example
- How to Run Android Applications on Ubuntu
- how to write one native program based on android source build system
- An example of how to do a simulation by LAMMPS
- How to Build FFmpeg for Android
- How to Build FFmpeg for Android
- How to Build FFmpeg for Android
- How to Build FFmpeg for Android
- How to build material design on android
- How to develop applications with Qt Mobility based on Symbian device
- How to Build an Android Project with Eclipse
- How to build a Flex development platform based on Myeclipse8.6 & Flex4
- How to Build a CMake-Based Project
- An IMS Application Example Based on SIP Servlets and VoiceXML
- How to load an ImageView by URL in Android
- How To Build CyanogenMod Android (oneplus/bacon) On Linux
- 为什么potplayer中用source而不用splitter
- splitter和source的区别
- MAC 驱动
- 数据字典总结(Sql server 2005)
- How to Build FFmpeg for Android
- How to Build Android Applications Based on FFmpeg by An Example
- 流密码密钥库文件加密探索
- 栈
- 动态创建表格之兼容性
- ODE 的仿真过程
- 如何在linux上抓包
- Windows Phone学习笔记:如何在页面显示前自动转向到其他页面
- 房产数据导入问题
- 从Linux 0.11内核看Linux信号处理机制