Android ffmpeg rtmp(source code)

时间:2023-03-08 16:32:49

souce code:

Android.mk

  编译生成APK需要调用的so文件

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE:= libavcodec
LOCAL_SRC_FILES:= lib/libavcodec-57.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE:= libavformat
LOCAL_SRC_FILES:= lib/libavformat-57.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE:= libswscale
LOCAL_SRC_FILES:= lib/libswscale-4.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE:= libavutil
LOCAL_SRC_FILES:= lib/libavutil-55.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE:= libavfilter
LOCAL_SRC_FILES:= lib/libavfilter-6.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE:= libswresample
LOCAL_SRC_FILES:= lib/libswresample-2.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY) #Program
include $(CLEAR_VARS)
#LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
LOCAL_MODULE := hello
LOCAL_SRC_FILES := main.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_LDLIBS := -llog -lz
LOCAL_SHARED_LIBRARIES :=avcodec avdevice avfilter avformat avutil postproc swresample swscaleinclude $(BUILD_SHARED_LIBRARY)
 
C语言实现文件
  编写C、C++文件实现底层的逻辑功能,最终编译为so文件被java调用
 #include <jni.h>
#include <stdio.h>
#include "include/libavcodec/avcodec.h"
#include "include/libavformat/avformat.h"
#include "include/libavfilter/avfilter.h" jstring JNICALL Java_com_example_zhaohu_test_MainActivity_stringFromJNI
(JNIEnv *env, jobject jObj)
{
char info[]= { };
AVFormatContext* pFormatCtx = NULL;
av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
//char* url="/storage/emulated/0/1.mp4";
char* url="rtmp://live.hkstv.hk.lxdns.com/live/hks"; // if(avformat_open_input(&pFormatCtx,url,NULL,NULL) != 0)
// {
// return (*env)->NewStringUTF(env,"open url failed!");
// }
int ret = avformat_open_input(&pFormatCtx,url,NULL,NULL);
//char buf[1024] = { 0 };
//av_strerror(ret,buf,1024);
//sprintf(info,"Couldn't open file %s: %d(%s)\n",url,ret,buf);
//return (*env)->NewStringUTF(env,info); if(!pFormatCtx)
return (*env)->NewStringUTF(env,"pFormat is NULL!"); if(avformat_find_stream_info(pFormatCtx,NULL) < )
{
return (*env)->NewStringUTF(env,"Did not find info");
}
int videoIndex = -;
int i;
for (i = ; i <pFormatCtx->nb_streams ; ++i)
{
if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoIndex = i;
break;
}
}
if(videoIndex == -)
{
return (*env)->NewStringUTF(env,"Did not find video steam!");
} AVCodecContext* pCodecCtx = pFormatCtx->streams[videoIndex]->codec;
AVCodec* pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec == NULL)
return (*env)->NewStringUTF(env,"Did not find video decoder"); if(avcodec_open2(pCodecCtx,pCodec,NULL) < )
{
return (*env)->NewStringUTF(env,"avcodec_open2 failed!");
} //sprintf(info,"%s\n",avcodec_configuration());
sprintf(info,"[Input:] %s\n",url);
sprintf(info,"%s[Format:] %s\n",info,pFormatCtx->iformat->name);
sprintf(info,"%s[codec:] %s\n",info,pCodecCtx->codec->name);
sprintf(info,"%s[Resolution:] %dx%d\n",info,pCodecCtx->width,pCodecCtx->height);
return (*env)->NewStringUTF(env,info);
} /*
* Class: com_example_zhaohu_test_MainActivity
* Method: unimplementedStringFromJNI
* Signature: ()Ljava/lang/String;
*/
jstring JNICALL Java_com_example_zhaohu_test_MainActivity_unimplementedStringFromJNI
(JNIEnv *env, jobject jObj)
{
return (*env)->NewStringUTF(env,"Java_com_example_zhaohu_test_MainActivity_unimplementedStringFromJNI");
}

实现Android代码

  调用C,C++的实现文件

package com.example.zhaohu.test;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView; public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); final TextView infoText = (TextView)findViewById(R.id.info);
//infoText.setText("This is My Test"); infoText.setText(stringFromJNI());
} public native String stringFromJNI();
public native String unimplementedStringFromJNI();
static {
System.loadLibrary("avcodec-57");
System.loadLibrary("avfilter-6");
System.loadLibrary("avformat-57");
System.loadLibrary("avutil-55");
System.loadLibrary("swresample-2");
System.loadLibrary("swscale-4");
System.loadLibrary("hello"); }
}