接着暑做的一个项目就是在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;
}
这个