2014-01-31 3 views
0

저는 Red5 서버에서 스트림으로 라이브 mp3 데이터를 수신하고 그것을 재생해야하는 Android 앱을 디자인하고 있습니다.ffmpeg로 audiotrack으로 mp3 데이터 재생

스트림에 대한 URL이 없거나 파일을 사용할 수 없기 때문에 미디어 플레이어 클래스를 사용하여 재생할 수 없습니다. 또 다른 옵션은 오디오 트랙 클래스를 사용하는 것이지만 PCM 데이터 만 필요합니다. 그래서 mp3를 pcm으로 변환해야합니다. 따라서 ffmpeg를 사용하십시오. 변환

내 코드는 문제가 avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt); -1을 반환 항상

AVCodec *codec; 
AVCodecContext *c= NULL; 
int out_size, len; 
uint8_t *outbuf; 

int iplen=(*env)->GetArrayLength(env, mp3buf); 
int16_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; 
AVPacket avpkt; 
av_init_packet(&avpkt); 
av_register_all(); 
avcodec_register_all(); 

codec = avcodec_find_decoder(CODEC_ID_MP3); 
if(!codec){ 
    __android_log_print(ANDROID_LOG_DEBUG, "logfromjni", "Codec not found"); 
} 
c = avcodec_alloc_context(); 
outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); 
avpkt.data = (*env)->GetByteArrayElements(env,mp3buf,NULL); 

avpkt.size = (*env)->GetArrayLength(env, mp3buf); 
out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; 
int ao=avcodec_open(c, codec); 
    if (ao < 0) { 
     __android_log_print(ANDROID_LOG_DEBUG, "logfromjni", "avcodec not open"); 
    } 
    len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt); 

입니다.

무엇이 잘못 되었습니까?

도움을 주시면 감사하겠습니다.

+0

오류의 원인을 찾으려면 ffmpeg 출력을보십시오. 장치에서 수행하기 어려운 경우 ffmpeg 출력을 리디렉션하고 자체 콜백으로 로깅을 수행 할 수 있습니다 ('av_log_set_callback' 및'av_log_set_level' 참조) – pogorskiy

답변

0

MP3는 프레임 기반 형식이므로 의미있는 결과를 얻으려면 decode_audio3에 전체 프레임을 전달해야합니다. 그것은 zlib와는 다르다. 어떤 크기의 데이터 (1 바이트조차도)의 덩어리로 가득 채워 결국 결과물을 얻을 수있다. 다음 사항을 확인하십시오 :

  • 서버가 적절한 프레임으로 데이터를 전송합니다.
  • 클라이언트 측에서 프레임을 적절하게 처리합니다 (서버에서 2kb send()가 recv()에서 두 개의 2kb 블록이 아니라 단일 4kb 블록에서 발생 함을 기억하십시오).
  • 전체 블록을 decode_audio3에 전달합니다.
+0

전체 프레임의 문제에 직면했을 수 있다고 생각합니다. 어떻게 프레임을 보장 할 수 있습니까? 유효하거나 완전한 블록이 수신되었습니다 .. –

+0

서버 크기에서 블록을 보낼 때 먼저 프레임 길이 (DWORD로)와 프레임 내용을 보냅니다. 이렇게하면 전체 프레임이 수신되었는지 여부를 클라이언트에서 항상 알 수 있습니다. –