마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

ffmpeg 동영상 파일에서 오디오 추출

0 추천

안녕하세요. 그루터기님의 강좌로 개발환경을 만들고

지금 동영상 파일에서 오디오를 추출하는 기능을 구현하고 있습니다.

예제에 나와있는 디코딩된 음원파일이 아닌 인코딩 되어있는 상태로 그대로 분리하려고 하는데

어떤 동영상은 정상적으로 분리되고 어떤것은 안되는데, 혹시 코드에 문제가 있는지 궁금하여 올립니다.

즉, 이렇게 짜여진 코드가 ffmpeg 입장에서 보았을 때 정상적인지 궁금합니다^^;

int ExtractAudio(const char src[], const char dest[]) {

 
av_register_all();
avcodec_register_all();
 
__android_log_print(ANDROID_LOG_DEBUG, "test", "dest : %s", dest);
__android_log_print(ANDROID_LOG_DEBUG, "test", "src : %s", src);
 
//파일을 열고 컨텍스트에 파일 형식을 불러온다.
AVFormatContext * pInputFormatContext = NULL;
int err = avformat_open_input(&pInputFormatContext, src, NULL, NULL);
if (err < 0) {
__android_log_print(ANDROID_LOG_DEBUG, "test",
"avformat_open_input Err! %d",err);
return 0;
}
 
//저장할 파일 및 소스 오픈
FILE *destFile = fopen(dest, "wb");
FILE *srcFile = fopen(src, "rb");
if (destFile == NULL || srcFile == NULL) {
__android_log_print(ANDROID_LOG_DEBUG, "test", "fopen Err!");
__android_log_print(ANDROID_LOG_DEBUG, "test", "fopen Err!");
return 0;
}
 
fseek(srcFile, 0, SEEK_END);
DCFSize = ftell(srcFile);
fseek(srcFile, 0, SEEK_SET);
 
//코덱 및 오디오 스트림 인덱스
int nAudioStreamIdx = -1;
AVCodec *pAudioCodec = NULL;
 
//스트림 정보를 찾는 함수
err = av_find_stream_info(pInputFormatContext);
if (err < 0) {
__android_log_print(ANDROID_LOG_DEBUG, "test",
"av_find_stream_info Err!");
__android_log_print(ANDROID_LOG_DEBUG, "test",
"av_find_stream_info Err!");
return 0;
}
 
err = av_find_best_stream(pInputFormatContext, AVMEDIA_TYPE_AUDIO, -1, -1,
&pAudioCodec, NULL);
 
//에러처리 임시
if (err < 0) {
nAudioStreamIdx = 1;
if (err == AVERROR_STREAM_NOT_FOUND)
__android_log_print(ANDROID_LOG_DEBUG, "test",
"AVERROR_STREAM_NOT_FOUND");
if (err == AVERROR_DECODER_NOT_FOUND)
__android_log_print(ANDROID_LOG_DEBUG, "test",
"AVERROR_DECODER_NOT_FOUND ");
} else
nAudioStreamIdx = err;
 
//AVPacket 선언 및 초기화
AVPacket Packet;
av_init_packet(&Packet);
 
while (av_read_frame(pInputFormatContext, &Packet) >= 0) {
//전에 저장했던 stream index를 비교해서 audio 패킷을 분류한다.
if (Packet.stream_index == nAudioStreamIdx)
{
fwrite(Packet.data, 1, Packet.size, destFile);
PaketPos = Packet.pos;
//__android_log_print(ANDROID_LOG_DEBUG, "test","Extract Progress : %d",getExtractProgress());
}
}
PaketPos = DCFSize;
 
return 1;
}
이런제길 (120 포인트) 님이 2013년 8월 15일 질문

1개의 답변

0 추천
av_read_frame 전에  avcodec_open2(pInputFormatContext, pAudioCodec, NULL);
같은 것으로 구한  코덱 정보에 대해 오픈을 해 주는 코드가 빠진듯은 합니다만.
디코딩이 되는 것도 있다니.. 이상하네요.
ffmpeg 버젼이 오낙 다양해서. API 가 빠진 버젼을 쓰셨을 수도 있지만 한번 시도 해보세요.
 
그리고 해당 오디오 코덱을 지원하지 못하면 디코딩을 못 할 수 있습니다. 지원안되는 영상의 오디오 코덱을 확인해보세요.
사악미소 (65,330 포인트) 님이 2013년 8월 16일 답변
답변 감사합니다.
디코딩된 파일은 용량이 커지다보니 디코딩하지않고 오디오 스트림만 따로 저장해서 인코딩된(mp3, aac, ac3 등) 음원 파일만을 분리하려다보니 코덱오픈이 필요하지 않을것같아서 쓰지 않았습니다.
음원 파일을 나중에 디코딩하게 될 때 코덱오픈을 하는데 어떤건 음원만 추출해서 정상적으로 재생되는데 디코딩이 안될때가 있더군요 ㅎ 코덱문제인것 같아서 확인하는데 어떤 코덱을 지원하는지 감이 잘 안잡히네요 ㅠㅠ
코덱의 경우 PC에서 동영상 플레이어로 재생 한 후 파일 정보 보기 같은 옵션을 통해 확인하시면 되며, 자세한 옵션을 알고 싶으시면 mediaInfo 프로그램을 사용해서 확인하시면 됩니다. http://mediaarea.net/ko/MediaInfo
...