在介绍Android版 RTSP客户端之前先吐槽一下ffmpeg的移植。虽然网上的教程已经很多了,但是本人能力有限。花费了一周的时间来移植ffmpeg,花费3小时左右的时间来编写了Android版的RTSP客户端。我要吐槽的就是网上的那些ffmpeg移植教程,我很奇怪那么多人移植没人发现问题吗?我碰到的问题是这杨的,一开始我按照网上的教程一步一步的做,但是最后一步出错了。就是这一步,把每一个lib.a 静态库编译成一个ffmpeg.so出错了。出错内容是一些undefine 'uncompress'之类的提示。这个明显是libz库出问题了,我各种百度google,但是最终还是没有解决掉。网上的教程也没有提到关于这个的问题的解决方法,倒是看到不少人提出了这个错误。最后还是自己去分析了Android.mk,最终发现了解决问题的办法了。这里面我就提出和那些教程不一样的地方,错误的地方是在ffmpeg目录下的Android.mk 里面少了一句LOCAL_LDLIBS := -llog -lz 。其实去耐心去分析的话,应该很快去解决这个问题。所以有时候一处问题去百度google不一定是一个好办法,有时候冷静下来去思考不是一个解决的办法。因为是最后一步出错了,而且从提示来看应该是libz库出问题了,和最后一步密切相关的.mk 文件就是ffmpeg目录下的Android.mk文件了。 然后修改了一下编译选项,这样我们的android版的ffmpeg就可以支持rtsp数据流了。吐槽就吐槽到这里了。下面开始介绍我们的Android版的RTSP客户端。其实实现过程类似与qt版的RTSP客户端,主要是显示部分不同。
由于ffmpeg是一个C库,而Android的开发是用JAVA开发的。这样就有一个语言不兼容的问题了。但是我们使用了NDK就可以实现JAVA代码和C代码的交互使用了。主要是使用了JAVA的JNI技术。对这块知识点不熟悉的朋友可以去百度google学习一下。这里不介绍JNI和NDK的知识点。所以本项目的分为两块,一块是JAVA层代码,一块是C代码。这里我使用了c++来写了。JAVA层代码主要是我们对Android的编程,C层代码主要是我们对rtsp数据流的接受和解码过程。大体框架了解了,我们开始分析一下代码了。主要是测试版的,没有华丽的界面。源代码我会在源代码下载地址里面更新,包括ffmpeg的最新移植支持rtsp的。
package com.ny.rtspclient;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity {
public static String RTSPURL="";
private EditText text_rtsp;
private Button btn_play,btn_cancle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 去除title
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
text_rtsp=(EditText)findViewById(R.id.rtspurl);
btn_play=(Button)findViewById(R.id.btn_play);
btn_cancle=(Button)findViewById(R.id.btn_cancle);
btn_play.setOnC