Android AOSP 环境下实现C++直接调用libmedia.so接口播放视频文件。

年运珧
2023-12-01

最近需要hook android libmedia.so以取得播放进度。

没搞出来,先搞了个c++直接播放MP4的程序:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#define LOG_TAG "INJECT-lx"
#include <android/log.h>


#include <elf.h>
#include <elf_1.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <string.h>

/
#ifdef ANDROID_5
#include <media/mediaplayer.h>
#include <stdint.h>
#include <algorithm>
#include <media/AudioResamplerPublic.h>
#include <media/IMediaHTTPService.h>
#include <media/MediaPlayerInterface.h>
#include <media/MediaAnalyticsItem.h>
#include <media/stagefright/Utils.h>            // for FOURCC definition
#include "android_runtime/AndroidRuntime.h"
#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include "android_media_BufferingParams.h"
#include "android_media_MediaDataSource.h"
#include "android_media_MediaMetricsJNI.h"
#include "android_media_PlaybackParams.h"
#include "android_media_SyncParams.h"
#include "android_media_VolumeShaper.h"
#else
#include <stdint.h>
#include "jni.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <utils/RefBase.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <gui/SurfaceTextureClient.h>
#include <media/mediaplayer.h>
#include <media/AudioSystem.h>
#include <binder/MemoryBase.h>
#include <utils/KeyedVector.h>
#include <utils/String8.h>
#include <system/audio.h>
#include <system/window.h>
#endif
/


#ifndef int32_t
#ifdef _WIN32
typedef int         status_t;
#else
typedef int32_t     status_t;
#endif
#endif


#define LOGD(fmt,args...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,fmt,##args);\
printf(fmt,##args)

extern "C" void *memcpy(void *dest, const void *src, size_t n);

typedef status_t (*t_setDataSource1)(const char *url);
typedef status_t (*pause_t)();

typedef status_t (android::MediaPlayer::*t_setDataSource2)(int fd, int64_t offset, int64_t length);
typedef status_t (android::MediaPlayer::*mp_pause_t)();

struct fields_t {
    jfieldID    context;
    jfieldID    surface_texture;

    jmethodID   post_event;

    jmethodID   proxyConfigGetHost;
    jmethodID   proxyConfigGetPort;
    jmethodID   proxyConfigGetExclusionList;
};
//using std::string;

extern "C"{
	
	int file_exists(char* path){
		FILE* fp = fopen(path, "r");
		if(fp==NULL) return 0;
		fclose(fp);
		return 1;
	}

}

using android::MediaPlayer;
using android::MediaPlayerListener;

namespace android{
class MyMediaPlayerListener: public MediaPlayerListener
{
public:
	void notify(int msg, int ext1, int ext2, const Parcel *obj)
	{
		LOGD("int msg=%d, int ext1=%d, int ext2=%d, const Parcel *obj=%p\n", msg, ext1, ext2, obj);
	}
/*protected:
	~RefBase()
	{
		LOGD("%s->%s->%d\n", __FILE__, __FUNCTION__, __LINE__);
	}
	*/
};
}
using android::sp;
using android::ProcessState;
using android::MyMediaPlayerListener;
int main(int argc, char** argv) {
	LOGD(" [V003] ");
	char mp4file[256];
	strcpy(mp4file, "/sdcard/1.mp4");
	int i;
	char* str,*pstr;
	for(i=0;i<argc;i++){
		str = argv[i];
		if(strstr(str, "p")!=NULL){
			pstr = strchr(str, '=');
			if(pstr!=NULL){
				strcpy(mp4file, pstr+1);
			}
		}
	}
  
  
	LOGD("At %s, line %d\n", __FUNCTION__, __LINE__);
  
	if(!file_exists(mp4file)){
		LOGD("%s not exists\n", mp4file);
		exit(1);
	}
  
	#android 4.2 必须用线程池,开启线程,否则会阻塞,而Android5不会。
	sp<ProcessState> proc = ProcessState::self();
	LOGD("App process: starting thread pool.\n");
	proc->startThreadPool();
  
	int iRet = 0;
    MediaPlayer *p= new MediaPlayer();
    MyMediaPlayerListener* ml = new MyMediaPlayerListener();
	LOGD("At %s, line %d\n", __FUNCTION__, __LINE__);

	FILE* fp = fopen(mp4file, "r");
	fseek(fp, 0, SEEK_END);
	int length = ftell(fp);
	rewind(fp);

	LOGD("At %s, line %d\n", __FUNCTION__, __LINE__);
	
	int fd = fileno(fp);
    iRet = p->setDataSource(fd, 0, length);
    if (0 != iRet)
    {
        LOGD("[setDataSource] iRet = %d\n", iRet);
    }
	LOGD("At %s, line %d\n", __FUNCTION__, __LINE__);

    iRet = p->setListener(ml);
    if (0 != iRet)
    {
        LOGD("[setListener] iRet = %d\n", iRet);
    }   
	LOGD("At %s, line %d\n", __FUNCTION__, __LINE__);

    iRet = p->prepare();
    if (0 != iRet)
    {
        LOGD("[prepare] iRet = %d\n", iRet);
    }
	LOGD("At %s, line %d\n", __FUNCTION__, __LINE__);

    iRet = p->start();
    if (0 != iRet)
    {
        LOGD("[start] iRet = %d\n", iRet);
    }
	LOGD("At %s, line %d\n", __FUNCTION__, __LINE__);

	while(i++<10){
		LOGD("[Playing] %d...\n", i);
		sleep(3);
	}
	LOGD("At %s, line %d\n", __FUNCTION__, __LINE__);
	
    p->stop();
    return 0;
}

Android.mk

LOCAL_PATH := $(call my-dir)

 
include $(CLEAR_VARS) 

#下面这句是android5使用的附加库的方法
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog -landroid_runtime -lmedia -lm -lnativebridge -lnativehelper -lnativeloader -lstagefright -landroid -lbase -lbinder -lcutils -ldl -lmediandk -lutils -lsysutils -ljnigraphics -lz -ldl -lgcc

#LOCAL_LDFLAGS := -Wl,--warn-unresolved-symbols 

#下面这句是android4.2使用的附加库的方法
LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libmedia libbinder

LOCAL_C_INCLUDES :=  -I system/libhidl/base/include/ -I system/libhidl/transport/token/1.0/utils/include/ -I external/piex/ -I frameworks/base/media/jni/ -I system/core/base/include -I ./system/core/include/



LOCAL_MODULE := myMediaPlayer
LOCAL_SRC_FILES:= myMediaPlayer.cpp
include $(BUILD_EXECUTABLE)

执行程序能够听到视频的声音,看不到图像,这个不管了,应该需要某种方式接收图像数据然后显示。

QQ群:95303036

 

 

 类似资料: