2012-03-21 2 views
8

다음 코드 스 니펫을 사용하여 오디오 파일 (MP3, WAV, WMV로 테스트 됨)을 디코딩합니다.libavcodec을 사용하여 오디오를 디코딩하고 libAO를 사용하여 재생합니까?

그러나 오디오를 재생할 때 정적 인 소리가 나고 시간이 흐려집니다. 내가 여기서 잘못하고있는 것에 대한 힌트가 있습니까?

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <math.h> 


extern "C" { 
#include "libavutil/mathematics.h" 
#include "libavformat/avformat.h" 
#include "libswscale/swscale.h" 
#include <ao/ao.h> 

} 

void die(const char *msg) 
{ 
    fprintf(stderr,"%s\n",msg); 
    exit(1); 
} 

int main(int argc, char **argv) 
{ 

    const char* input_filename=argv[1]; 

    //avcodec_register_all(); 
    av_register_all(); 
    //av_ini 

    AVFormatContext* container=avformat_alloc_context(); 
    if(avformat_open_input(&container,input_filename,NULL,NULL)<0){ 
     die("Could not open file"); 
    } 

    if(av_find_stream_info(container)<0){ 
     die("Could not find file info"); 
    } 
    av_dump_format(container,0,input_filename,false); 

    int stream_id=-1; 
    int i; 
    for(i=0;i<container->nb_streams;i++){ 
     if(container->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){ 
      stream_id=i; 
      break; 
     } 
    } 
    if(stream_id==-1){ 
     die("Could not find Audio Stream"); 
    } 

    AVDictionary *metadata=container->metadata; 

    AVCodecContext *ctx=container->streams[stream_id]->codec; 
    AVCodec *codec=avcodec_find_decoder(ctx->codec_id); 

    if(codec==NULL){ 
     die("cannot find codec!"); 
    } 

    if(avcodec_open(ctx,codec)<0){ 
     die("Codec cannot be found"); 
    } 

    //ctx=avcodec_alloc_context3(codec); 

    //initialize AO lib 
    ao_initialize(); 

    int driver=ao_default_driver_id(); 

    ao_sample_format sformat; 
    sformat.bits=16; 
    sformat.channels=2; 
    sformat.rate=44100; 
    sformat.byte_format=AO_FMT_NATIVE; 
    sformat.matrix=0; 

    ao_device *adevice=ao_open_live(driver,&sformat,NULL); 
    //end of init AO LIB 

    AVPacket packet; 
    av_init_packet(&packet); 

    AVFrame *frame=avcodec_alloc_frame(); 

    int buffer_size=AVCODEC_MAX_AUDIO_FRAME_SIZE; 
    uint8_t buffer[buffer_size]; 
    packet.data=buffer; 
    packet.size =buffer_size; 



    int len; 
    int frameFinished=0; 
    while(av_read_frame(container,&packet)>=0) 
    { 

     if(packet.stream_index==stream_id){ 
      //printf("Audio Frame read \n"); 
      int len=avcodec_decode_audio4(ctx,frame,&frameFinished,&packet); 
      //frame-> 
      if(frameFinished){ 
       //printf("Finished reading Frame %d %d\n",packet.size,len); 
       ao_play(adevice, (char*)frame->data, len); 
      } 

     } 


    } 

    av_close_input_file(container); 
    ao_shutdown(); 
    return 0; 
} 

답변

13

확인, 여기에 작업 코드 예제입니다 : 내가 평면 오디오 지원을 추가

int main(int argc, char **argv) 
{ 

    const char* input_filename=argv[1]; 

    //avcodec_register_all(); 
    av_register_all(); 
    //av_ini 

    AVFormatContext* container=avformat_alloc_context(); 
    if(avformat_open_input(&container,input_filename,NULL,NULL)<0){ 
     die("Could not open file"); 
    } 

    if(av_find_stream_info(container)<0){ 
     die("Could not find file info"); 
    } 
    av_dump_format(container,0,input_filename,false); 

    int stream_id=-1; 
    int i; 
    for(i=0;i<container->nb_streams;i++){ 
     if(container->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){ 
      stream_id=i; 
      break; 
     } 
    } 
    if(stream_id==-1){ 
     die("Could not find Audio Stream"); 
    } 

    AVDictionary *metadata=container->metadata; 

    AVCodecContext *ctx=container->streams[stream_id]->codec; 
    AVCodec *codec=avcodec_find_decoder(ctx->codec_id); 

    if(codec==NULL){ 
     die("cannot find codec!"); 
    } 

    if(avcodec_open(ctx,codec)<0){ 
     die("Codec cannot be found"); 
    } 

    //ctx=avcodec_alloc_context3(codec); 

    //initialize AO lib 
    ao_initialize(); 

    int driver=ao_default_driver_id(); 

    ao_sample_format sformat; 
    AVSampleFormat sfmt=ctx->sample_fmt; 
    if(sfmt==AV_SAMPLE_FMT_U8){ 
     printf("U8\n"); 

     sformat.bits=8; 
    }else if(sfmt==AV_SAMPLE_FMT_S16){ 
     printf("S16\n"); 
     sformat.bits=16; 
    }else if(sfmt==AV_SAMPLE_FMT_S32){ 
     printf("S32\n"); 
     sformat.bits=32; 
    } 

    sformat.channels=ctx->channels; 
    sformat.rate=ctx->sample_rate; 
    sformat.byte_format=AO_FMT_NATIVE; 
    sformat.matrix=0; 

    ao_device *adevice=ao_open_live(driver,&sformat,NULL); 
    //end of init AO LIB 

    AVPacket packet; 
    av_init_packet(&packet); 

    AVFrame *frame=avcodec_alloc_frame(); 



    int buffer_size=AVCODEC_MAX_AUDIO_FRAME_SIZE+ FF_INPUT_BUFFER_PADDING_SIZE;; 
    uint8_t buffer[buffer_size]; 
    packet.data=buffer; 
    packet.size =buffer_size; 



    int len; 
    int frameFinished=0; 
    while(av_read_frame(container,&packet)>=0) 
    { 

     if(packet.stream_index==stream_id){ 
      //printf("Audio Frame read \n"); 
      int len=avcodec_decode_audio4(ctx,frame,&frameFinished,&packet); 
      //frame-> 
      if(frameFinished){ 
       //printf("Finished reading Frame len : %d , nb_samples:%d buffer_size:%d line size: %d \n",len,frame->nb_samples,buffer_size,frame->linesize[0]); 
       ao_play(adevice, (char*)frame->extended_data[0],frame->linesize[0]); 
      }else{ 
       //printf("Not Finished\n"); 
      } 

     }else { 
      printf("Someother packet possibly Video\n"); 
     } 


    } 

    av_close_input_file(container); 
    ao_shutdown(); 
    return 0; 
} 
+3

코드는 여기 http://0xdeafc0de.wordpress.com/2013/12/19/ffmpeg- 오디오 재생 샘플/ –

+0

@MaduraAnushanga 오, 당신도 스리랑카 출신입니다 :) –

+0

그래, 나도 그래 : 너도 그래? 성이 이상하게 들리네 ... –

관련 문제