android下初步使用ffmpeg

            接着暑做的一个项目就是在Android下做一个播放器,考虑到编码和解码的问题我们,目前采用的是使用ffmpeg这个开源库(在Android平台下可以实现移植),这个开源库由于是开源的,它的注释很是详细,但是我们这等人居然还是不太懂怎么用,于是我就看了下网上的一些例子,改了一个程序,希望对大家有所帮助:

     其实我的目的很简单就是实现mp3转化为pcm的,这这个pcm数据存放到一个文件中。

      其他的不说了我就先上代码:


#include <string.h>
#include <jni.h>
#include <android/log.h>
#include <ffmpeg/libavcodec/avcodec.h>
#include <ffmpeg/libavformat/avformat.h>
#include <ffmpeg/libswscale/swscale.h>
#include <string.h>


#define LOG_TAG    "***************************lixingyun*****************" // 这个是自定义的LOG的标识
#undef LOG // 取消默认的LOG
#define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) // 定义LOG类型
#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) // 定义LOG类型
#define LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) // 定义LOG类型
#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) // 定义LOG类型
#define LOGF(...)  __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__) // 定义LOG类型
/* This is a trivial JNI example where we use a native method
 * to return a new VM String. See the corresponding Java source
 * file located at:
 *
 *   apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
 */
JNIEXPORT jstring Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv* env,
		jobject thiz) {
	char str[25];
	sprintf(str, "%d", avcodec_version());


	return (*env)->NewStringUTF(env, str);
	// return (*env)->NewStringUTF(env, "Hello from JNI !");0
}


JNIEXPORT jint Java_com_example_hellojni_HelloJni_getVoice(JNIEnv* env,
		jobject thiz) {
	const char *filename = "file:/sdcard/test.mp3";
	const char *outFielName = "/mnt/sdcard/ffmpeg.txt";
	AVFormatContext *pFormatCtx = NULL;
		AVCodecContext *pCodecCtx = NULL;
		AVCodec *aaccodec = NULL;
		AVPacket aacpkt;
		int len = 0;
		int size = 0;
		unsigned char *outbuf = NULL;
	// unsigned char inbuf[INBUF_SIZE*5],*inbuf_ptr;
		int outsize;
		int newpacket = 0;
		int audio_stream = -1;


		int out_ape_fp = -1;
		int in_ape_fp = -1;


		double start_time = 0;
		double duration = 0;


		FILE *out_fp;


		const unsigned char start_code[4] = { 0x00, 0x00, 0x00, 0x01 };


		out_fp = fopen(outFielName, "wb+");
	// memset(inbuf, 0, sizeof(inbuf));


	// inbuf_ptr = inbuf;
		aacpkt.data = NULL;
		aacpkt.size = 0;


		av_init_packet(&aacpkt);


//		if (argc < 2) {
//			printf("Usage: test <file>\n");
//			exit(1);
//		}
		// Register all formats and codecs
		av_register_all();


		// Open video file
		if (av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL) != 0)
			{
			  LOGE("av_open_input_file error\n");
			  return -1; // Couldn't open file
			}




		// Retrieve stream information
		if (av_find_stream_info(pFormatCtx) < 0)
			return -1; // Couldn't find stream information


		// Dump information about file onto standard error
		dump_format(pFormatCtx, 0, filename, 0);
		int i= 0;


		for (i = 0; i < pFormatCtx->nb_streams; i++) {
			if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
				audio_stream = i;
				break;
			}
		}




		if (audio_stream == -1) {
			printf("audio not found!\n");
			return -1;
		} else {
			pCodecCtx = pFormatCtx->streams[audio_stream]->codec;
			aaccodec = avcodec_find_decoder(pCodecCtx->codec_id);
			if (aaccodec == NULL)
				return -1;
			if (avcodec_open(pCodecCtx, aaccodec) < 0)
				return -1;
		}


		LOGI(" bit_rate = %d \r\n", pCodecCtx->bit_rate);
		    LOGI(" sample_rate = %d \r\n", pCodecCtx->sample_rate);
		    LOGI(" channels = %d \r\n", pCodecCtx->channels);
		    LOGI(" code_name = %s \r\n", pCodecCtx->codec->name);
		    //LOGI("extra data size: %d :data%x %x %x %x\n",pInCodecCtx->extradata_size,pInCodecCtx->extradata[0]
		    // ,pInCodecCtx->extradata[1],pInCodecCtx->extradata[2],pInCodecCtx->extradata[3]);
		    LOGI(" block_align = %d\n", pCodecCtx->block_align);


		outbuf = (unsigned char *) malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE * 2);
		outsize = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;


		while (av_read_frame(pFormatCtx, &aacpkt) >= 0) {
			if (aacpkt.stream_index == audio_stream) {
				int declen = 0;
				size = aacpkt.size;
				while (aacpkt.size > 0) {
					outsize = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;
					memset(outbuf, 0, outsize);
					len = avcodec_decode_audio3(pCodecCtx, (int16_t *) outbuf,
							&outsize, &aacpkt);
					if (len < 0) {
						printf("avcodec_decode_audio3 failed!\n");
						break;
					}
					if (outsize > 0) {
						fwrite(outbuf, 1, outsize, out_fp);
						printf("write %d bytes\n", outsize);
					}
					declen += len;
					if (declen == size) {
						av_free_packet(&aacpkt);
						printf("packet decoded succeed!\n");
						break;
					} else if (declen < size) {
						aacpkt.size -= len;
						aacpkt.data += len;
					} else {
						printf("decode error!\n");
						break;
					}


				}


			}
		}


		fclose(out_fp);
		// Close the codec
		avcodec_close(pCodecCtx);


		// Close the video file
		av_close_input_file(pFormatCtx);
		return 0;


}


这个



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值