我正在为Android NDK编译一个用于Android的播放器。
我可以通过FFmpeg打开文件并写下:
av_register_all();
char* str = (*env) -> GetStringUTFChars(env, argv, 0);
__android_log_print(ANDROID_LOG_INFO, "HelloNDK!", str, str);
if (av_open_input_file (&pFormatCtx, str, NULL, 0, NULL) != 0)
return -2; // Couldn't open file
// Retrieve stream information
if (av_find_stream_info(pFormatCtx) < 0)
return -3; // Couldn't find stream information
// Dump information about file onto standard error
dump_format(pFormatCtx, 0, argv, 0);
// Find the first video stream
videoStream =- 1;
audioStream =- 1;
for (i = 0; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO && audioStream <0) {
audioStream = i;
}
}
if (audioStream == -1)
return -5;
aCodecCtx = pFormatCtx->streams[audioStream]->codec;
// Set audio settings from codec info
aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
if (!aCodec) {
fprintf (stderr, "Unsupported codec! \n");
return -1;
}
avcodec_open (aCodecCtx, aCodec);
我现在如何解码音频并将其返回给Java程序?也许有人可以给我一个例子
编辑: 使用avcodec_decode_audio3时 获取以下内容: 03-22 07:54:00.988:INFO / DEBUG(31): * * * * * * * * * * * * ** * * * * 03-22 07:54:00.988:INFO / DEBUG(31):构建指纹:'generic / sdk / generic /:2.2 / FRF91 / 43546:eng / test-keys' 03-22 07:54:00.988:INFO / DEBUG(31):pid:435,tid:435&gt;&gt;&gt; org.libsdl.app&lt;&lt;&lt; 03-22 07:54:00.998:INFO / DEBUG(1931):信号11(SIGSEGV),故障地址00000000 03-22 07:54:00.998:INFO / DEBUG(1931):r0 00000000 r1 00000000 r2 81893210 r3 00000000 03-22 07:54:01:00:INFO / DEBUG(1931):r4 8189324c r5 818931d0 r6 00000000 r7 00000000 03-22 07:54:01:00:INFO / DEBUG(1931):r8 00000200 r9 00000600 10 00000300 00000500 fp 03-22 07:54:01.019:INFO / DEBUG(1931):ip 81350868 sp bef4c438 lr 8112cb3b pc 8112cb6c cpsr 80000030 03-22 07:54:01.369:INFO / DEBUG(31):#00 pc 0012cb6c / data / data / org.libsdl.app / lib / libtest.so 03-22 07:54:01.369:INFO / DEBUG(31):#01 pc 0012db46 / data / data / org.libsdl.app / lib / libtest.so 03-22 07:54:01.379:INFO / DEBUG(31):#02 pc 0013052e / data / data / org.libsdl.app / lib / libtest.so 03-22 07:54:01.379:INFO / DEBUG(31):#03 pc 00132142 / data / data / org.libsdl.app / lib / libtest.so 03-22 07:54:01.389:INFO / DEBUG(31):#04 pc 001a2836 / data / data / org.libsdl.app / lib / libtest.so 03-22 07:54:01.399:INFO / DEBUG(31):#05 pc 00024ee6 / data / data / org.libsdl.app / lib / libtest.so 03-22 07:54:01.399:INFO / DEBUG(31):#06 pc 00013974 / system / lib / libdvm.so 03-22 07:54:01.409:INFO / DEBUG(31):#07 pc 0003de3c / system / lib / libdvm.so 03-22 07:54:01.409:INFO / DEBUG(31):#08 pc 00037216 / system / lib / libdvm.so 03-22 07:54:01.419:INFO / DEBUG(31):#09 pc 000432ec / system / lib / libdvm.so 03-22 07:54:01.419:INFO / DEBUG(31):#10 pc 00018714 / system / lib / libdvm.so 03-22 07:54:01.439:INFO / DEBUG(31):#11 pc 0001e8c4 / system / lib / libdvm.so 03-22 07:54:01.439:INFO / DEBUG(31):#12 pcd 0001d790 / system / lib / libdvm.so 03-22 07:54:01.439:INFO / DEBUG(31):#13 pc 0005408e / system / lib / libdvm.so 03-22 07:54:01.449:INFO / DEBUG(31):#14 pc 0005bde2 / system / lib / libdvm.so 03-22 07:54:01.449:INFO / DEBUG(31):#15 pc 00018714 / system / lib / libdvm.so 03-22 07:54:01.459:INFO / DEBUG(31):#16 pc 0001e8c4 / system / lib / libdvm.so 03-22 07:54:01.469:INFO / DEBUG(31):#17 pc 0001d790 / system / lib / libdvm.so 03-22 07:54:01.469:INFO / DEBUG(31):#18 pc 00053eec / system / lib / libdvm.so 03-22 07:54:01.479:INFO / DEBUG(31):#19 pc 0004072c / system / lib / libdvm.so 03-22 07:54:01.479:INFO / DEBUG(31):#20 pc 00034454 / system / lib / libdvm.so 03-22 07:54:01.489:INFO / DEBUG(31):#21 pc 0002c930 / system / lib / libandroid_runtime.so 03-22 07:54:01.489:INFO / DEBUG(31):#22 pc 0002d85c / system / lib / libandroid_runtime.so 03-22 07:54:01.499:INFO / DEBUG(31):#23 pc 00008c86 / system / bin / app_process 03-22 07:54:01.519:INFO / DEBUG(31):#24 pc 0000d362 / system / lib / libc.so
我可以使用avcodec_decode_audio2吗? 我最近几天已经达到了以下代码:
AVFormatContext * pFormatCtx;
int i, videoStream, audioStream;
AVCodecContext * pCodecCtx;
AVCodec * pCodec;
AVFrame * pFrame;
AVPacket packet;
int frameFinished;
float aspect_ratio;
AVCodecContext * aCodecCtx;
AVCodec * aCodec;
AVCodecContext * c = NULL;
int out_size, len;
int16_t * audio_buf;
uint8_t * outbuf;
uint8_t inbuf [AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
av_register_all ();
char * str = (* env) -> GetStringUTFChars (env, argv, 0);
if (av_open_input_file (& pFormatCtx, str, NULL, 0, NULL)! = 0)
return -150;
if (av_find_stream_info (pFormatCtx) nb_streams; i + +) {
if (pFormatCtx-> streams [i] -> codec-> codec_type == CODEC_TYPE_VIDEO & & videoStream streams [i] -> codec-> codec_type == CODEC_TYPE_AUDIO & & audioStream streams [audioStream] -> codec;
aCodec = avcodec_find_decoder (aCodecCtx-> codec_id);
if (! aCodec) {
fprintf (stderr, "Unsupported codec! \ n");
return -45;
}
avcodec_open (aCodecCtx, aCodec);
c = avcodec_alloc_context ();
packet_queue_init (& audioq);
while (av_read_frame (pFormatCtx, & packet)> = 0) {
if (packet.stream_index == videoStream) {
} Else if (packet.stream_index == audioStream) {
packet_queue_put (& audioq, & packet);
int len1, data_size;
data_size = 417;
len1 = avcodec_decode_audio2 (aCodecCtx, (int16_t *) audio_buf, & data_size,
packet.data, packet.size);
return packet.size;
} Else {
av_free_packet (& packet);
}
}
return 0;
在这种情况下,当avcodec_decode_audio2得到-1时。我做错了什么?
注意: 当我开车int data_size = 417;然后DEBUG没有出现,函数返回-1,但是当我驱动一个:int data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;然后vyskakievaet DEBUG在你的功能,所以在我自己!怎么解决这个问题?
EDIT2: 我的新代码:
JNIEXPORT jint JNICALL Java_org_libsdl_app_SDLActivity_main( JNIEnv* env, jobject obj, int argc, jstring argv, jbyteArray array) {
AVFormatContext *pFormatCtx;
int i, videoStream, audioStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVPacket packet;
int frameFinished;
float aspect_ratio;
AVCodecContext *aCodecCtx;
AVCodec *aCodec;
SDL_Overlay *bmp;
SDL_Surface *screen;
SDL_Rect rect;
SDL_Event event;
SDL_AudioSpec wanted_spec, spec;
AVCodecContext *c= NULL;
int out_size, len;
int16_t *audio_buf;
uint8_t *outbuf;
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
char *pAudioBuffer = (char *) av_malloc (AVCODEC_MAX_AUDIO_FRAME_SIZE * 2);
av_register_all();
char *str = (*env)->GetStringUTFChars(env, argv, 0);
if(av_open_input_file(&pFormatCtx, str, NULL, 0, NULL)!=0)
return -150; // Couldn't open file
if(av_find_stream_info(pFormatCtx)nb_streams; i++) {
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO &&
videoStream streams[i]->codec->codec_type==CODEC_TYPE_AUDIO &&
audioStream streams[audioStream]->codec;
aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
if(!aCodec) {
fprintf(stderr, "Unsupported codec!\n");
return -45;
}
avcodec_open(aCodecCtx, aCodec);
c=avcodec_alloc_context();
packet_queue_init(&audioq);
while (av_read_frame(pFormatCtx, &packet)>= 0) {
if (aCodecCtx->codec_type == AVMEDIA_TYPE_AUDIO) {
int data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;
int size=packet.size;
while(size > 0) {
int len = avcodec_decode_audio3(aCodecCtx, (int16_t *) pAudioBuffer, &data_size, &packet);
jbyte *bytes = (*env)->GetByteArrayElements(env, array, NULL);
memcpy(bytes, (int16_t *) pAudioBuffer, size);
(*env)->ReleaseByteArrayElements(env, array, bytes, 0);
size = packet.size-len;
}
}
}
return 5;
}
答案 0 :(得分:4)
使用audiotrack课程为您完成工作。你可以这样做。
JAVA方面。
AudioTrack track;
int bufSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufSize, AudioTrack.MODE_STREAM);
track.play();
while(true){
readBufferFromNative(); //update buffer from native code
....................
....................
}
在本机端:您需要首先读取帧并将其转换为原始pcm格式,然后开始连续填充音频缓冲区。当缓冲区已满时,它将自动播放。
JNIEXPORT int JNICALL Java_com_ffmpeg_Main_jniMainEntry(JNIEnv* env, jobject obj, jstring input) {
const char * pszFileName = (*env)->GetStringUTFChars(env, input, 0);
AVFormatContext * m_fc;
int err;
AVPacket pkt;
char * pAudioBuffer = (char *) av_malloc (AVCODEC_MAX_AUDIO_FRAME_SIZE * 2);
int i;
avcodec_register_all ();
avdevice_register_all ();
av_register_all ();
err = av_open_input_file(&m_fc, pszFileName, 0, 0, 0);
err = av_find_stream_info(m_fc);
for(i = 0; i<m_fc->nb_streams; i++) {
if((m_fc->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) || (m_fc->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)) {
AVCodec *codec = avcodec_find_decoder(m_fc->streams[i]->codec->codec_id);
if (codec == 0)
continue;
err = avcodec_open(m_fc->streams[i]->codec, codec);
if (err <0)
continue;
}
}
while (av_read_frame(m_fc, &pkt)>= 0) {
if (m_fc-> streams[pkt.stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
int data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;
int size=pkt->size;
while(size > 0) {
int len = avcodec_decode_audio3(m_fc->streams[pkt.stream_index]->codec, (int16_t *) pAudioBuffer, &data_size, &pkt);
LOGD("data_size %d len %d", data_size, len);
size = pkt->size-len;
}
}
}
}
答案 1 :(得分:0)
我无法发表评论,所以我将此作为答案发布。
我也尝试使用ffmpeg播放aac音频,但对如何使其工作有很多疑问。
我尝试使用http://code.google.com/p/aacplayer-android/作为参考,但代码的作者没有使用avcodec_decode_audio3进行解码。通过AudioTrack进行的播放结果很多,我认为缓冲区没有被解码器快速填充,以便录音带能够播放。
我还有其他办法吗?
再一次,很抱歉将此作为答案发布。