问题描述
我正在使用ffmpeg在iOS上解码he-aac音频文件,该解码器是 libfdk_aac
,这是音频文件: https://cdn.perterpon.com/listen/test/bbc.mp4这是 av_dump_format
结果:
I’m using ffmpeg to decode he-aac audio file on iOS,which decoder is libfdk_aac
,here is the audio file:https://cdn.perterpon.com/listen/test/bbc.mp4and here is the av_dump_format
result:
Metadata:
major_brand : iso6
minor_version : 0
compatible_brands: iso6dash
Duration: N/A, bitrate: N/A
Stream #0:0(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, 2 channels (default)
Metadata:
handler_name : USP Sound Handler
av_read_frame
和 avcodec_send_packet
返回0,但 avcodec_receive_frame
始终返回 AVERROR(EAGAIN)
av_read_frame
and avcodec_send_packet
return 0, but avcodec_receive_frame
always return AVERROR(EAGAIN)
我尝试使用ffmpeg命令行工具: ffmpeg -i bbc.mp4 bbc.mp3
,它成功了,并且mp3文件可以在iOS上播放.
I’v tried ffmpeg command line tool: ffmpeg -i bbc.mp4 bbc.mp3
, it success, and the mp3 file is good to playback on iOS.
这是我的代码:
av_register_all();
AVFormatContext *avFormatContext = avformat_alloc_context();
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"bbc" ofType:@"mp4"];
int ret;
ret = avformat_open_input(&avFormatContext, [filePath UTF8String], NULL, NULL);
if (0 != ret) {
NSLog(@"avformat_open_input failed: %d", ret);
}
ret = avformat_find_stream_info(avFormatContext, NULL);
if (0 != ret) {
NSLog(@"avformat_find_stream_info: %d", ret);
}
// the libfdk_aac decoder
AVCodec *codec = avcodec_find_decoder_by_name("libfdk_aac");
AVCodecContext *codecContext = avcodec_alloc_context3(codec);
ret = avcodec_open2(codecContext, codec, NULL);
if (0 != ret) {
NSLog(@"avcodec_open2 faild: %d", ret);
}
AVFrame *frame = av_frame_alloc();
AVPacket packet;
av_init_packet(&packet);
// start read data and decode data
while (true) {
ret = av_read_frame(avFormatContext, &packet);
if (0 != ret) {
break;
}
ret = avcodec_send_packet(codecContext, &packet);
if (ret != 0) {
NSLog(@"send package with error: %d", ret);
continue;
break;
}
while (true) {
// the ret below is always return -35, means AVERROR(EAGAIN)
ret = avcodec_receive_frame(codecContext, frame);
if (ret == AVERROR(EAGAIN)) {
NSLog(@"avcodec_receive_frame with EAGAIN error: %d", ret);
break;
} else if (ret == AVERROR_EOF) {
NSLog(@"end of file");
break;
}
}
if (ret == AVERROR(EAGAIN)) {
continue;
}
}
我尝试将 bbc.mp4
文件替换为 bbc.mp3
文件,并将解码器更改为: AVCodec * codec = avcodec_find_decoder(AV_CODEC_ID_MP3);
,所有事情都运转良好.非常非常感谢你.
I'v tried replace bbc.mp4
file to bbc.mp3
file, and change the decoder to: AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_MP3);
,all of the things working every good. Thank you very very very much.
推荐答案
当avcodec_receive_frame返回EAGAIN时,必须再次调用具有更多数据的avcodec_send_packet(或流末尾为空数据包),然后才能再次调用avcodec_receive_frame.
When avcodec_receive_frame returns EAGAIN, you must call avcodec_send_packet with more data (or a null packet at the end of the stream) before calling avcodec_receive_frame again.
这篇关于ffmpeg函数avcodec_receive_frame始终返回EAGAIN错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!