音频转换后,时间长度从20秒变成了2秒
最近正在学习ffmpeg,打算从音频转换学起,下边是写的一段转换音频的代码。
把一个wav的音频转换成mp3后,原来20秒的音频只有2秒了。音频的内容从头到尾都是有的,就是速度变快了,应该是一些帧被抛弃了。
初学ffmpeg,搞了好长时间还是不知道是什么原因,请大家帮忙参谋参谋。这里先谢谢了。
下边是代码:
// 使用的是vc2003
void CAudio::OnBtnAudioConvert()
{
// TODO: Add your control notification handler code here
CString str;
GetDlgItem(IDC_EDIT_FILENAME)-> GetWindowText(str);
if (str== " ")
{
MessageBox( "请选择一个有效的视频文件。 ",_T( "提示 "),MB_ICONINFORMATION);
return;
}
AVFormatContext *pFormatCtx;
int i, audioStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVPacket packet;
int frameFinished;
int numBytes;
const char *filename =str;
/* must be called before using avcodec lib */
avcodec_init();
// 注册所有的格式和编解码器
av_register_all();
// Open audio file
if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0)
{
m_ListAudioInfo.AddString( "无法打开文件: "+str);
return ;
}
// Retrieve stream information
if(av_find_stream_info(pFormatCtx) <0)
{
m_ListAudioInfo.AddString( "无法在该文件中找到音频流... ");
return ;
}
audioStream=-1;
for(i=0; i <pFormatCtx-> nb_streams; i++)
if(pFormatCtx-> streams-> codec-> codec_type==CODEC_TYPE_AUDIO)
{
audioStream=i;
break;
}
if(audioStream==-1)
return; // Didn 't find a audio stream
// Get a pointer to the codec context for the audio stream
pCodecCtx=pFormatCtx-> streams[audioStream]-> codec;
// Find the decoder for the audio stream
pCodec=avcodec_find_decoder(pCodecCtx-> codec_id);
if(pCodec==NULL)
return; // Codec not found
// Open codec
if(avcodec_open(pCodecCtx, pCodec) <0)
return; // Could not open codec
// -------------------------- 输出文件 -----------------------------
AVFormatContext *pOutFormatCtx;
AVOutputFormat *fmt;
AVStream *audio_st;
char *outputfile = "c:\\light_wave.mp3 ";
// 根据文件名的后缀,猜测文件格式
fmt = guess_format(NULL, outputfile, NULL);
if (!fmt)
{
fprintf(stderr, "Could not find suitable output format\n ");
exit(1);
}
/* allocate the output media context */
pOutFormatCtx = av_alloc_format_context();
if (!pOutFormatCtx)
{
fprintf(stderr, "Memory error\n ");
exit(1);
}
pOutFormatCtx-> oformat = fmt;
/* set the output parameters (must be done even if no
parameters). */
//AVFormatParameters ap;
//ap.sample_rate =;
//if (av_set_parameters(oc, &ap) < 0) {
if (fmt-> audio_codec!=CODEC_ID_NONE)
audio_st =av_new_stream(pOutFormatCtx,fmt-> audio_codec);//add_audio_stream(oc, fmt-> audio_codec);
//dump_format(oc, 0, outputfile, 1);
avcodec_get_context_defaults(audio_st-> codec);
/****** Open the audio ***********/
AVCodecContext *c;
AVCodec *codec;
c=avcodec_alloc_context();
c = audio_st-> codec;
c-> codec_id =pOutFormatCtx-> oformat-> audio_codec;
c-> codec_type =CODEC_TYPE_AUDIO;
c-> bit_rate =pCodecCtx-> bit_rate;
c-> sample_rate =pCodecCtx-> sample_rate;
c-> channels =pCodecCtx-> channels;
if (av_set_parameters(pOutFormatCtx, NULL) < 0)
{
fprintf(stderr, "Invalid output format parameters\n ");
exit(1);
}
/* 查找音频编码器*/
codec = avcodec_find_encoder(c-> codec_id);
if (!codec) {
fprintf(stderr, "codec not found\n ");
exit(1);
}
// 打开输出编解码器
if (avcodec_open(c, codec) < 0)
{
fprintf(stderr, "could not open codec\n ");
exit(1);
}
/****** Open the audio ***********/
/* open the output file, if needed*/
if (!(fmt-> flags & AVFMT_NOFILE))
{
if (url_fopen(&pOutFormatCtx-> pb, outputfile, URL_WRONLY) < 0) {
fprintf(stderr, "Could not open '%s '\n ", outputfile);
exit(1);
}
}
/* 写文件头*/
av_write_header(pOutFormatCtx);
/*** Write audio into file ******/
AVPacket pkt;
av_init_packet(&pkt);
av_init_packet(&packet);
numBytes = 10000;
short *buffer =NULL;// (short*) malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
uint8_t *outbuf =(uint8_t*) malloc(numBytes);
static unsigned int buffer_size=0;
// 开始逐帧读取音频
while(av_read_frame(pFormatCtx, &packet)> =0)
{
// Is this a packet from the audio stream?
if(packet.stream_index==audioStream)
{
if (&packet)
buffer =(short*)av_fast_realloc(buffer,&buffer_size,FFMAX(packet.size*sizeof(*buffer),AVCODEC_MAX_AUDIO_FRAME_SIZE));
frameFinished =buffer_size;
avcodec_decode_audio(pCodecCtx, buffer, &frameFinished, packet.data, packet.size);
// Did we get a audio frame?
if(frameFinished)
{
/* encode the samples */
pkt.size= avcodec_encode_audio(c, outbuf, packet.size, buffer);
pkt.pts= av_rescale_q(c-> coded_frame-> pts, c-> time_base, audio_st-> time_base);
pkt.flags |= PKT_FLAG_KEY;
pkt.stream_index =audioStream;
pkt.data= outbuf;
/* write the compressed frame in the media file */
if (av_write_frame(pOutFormatCtx, &pkt) != 0)
{
fprintf(stderr, "Error while writing audio frame\n ");
exit(1);
}
}
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
av_free_packet(&pkt);
}
/* 写文件尾*/
av_write_trailer(pOutFormatCtx);
for(i = 0; i < pOutFormatCtx-> nb_streams; i++) {
av_freep(&pOutFormatCtx-> streams-> codec);
av_freep(&pOutFormatCtx-> streams);
}
if (!(fmt-> flags & AVFMT_NOFILE)) {
/* close the output file */
url_fclose(&pOutFormatCtx-> pb);
}
/* free the stream */
av_free(pOutFormatCtx);
// Close the codec
avcodec_close(pCodecCtx);
// Close the video file
av_close_input_file(pFormatCtx);
}
[解决办法]
我最近也在研究ffmpeg ,你的ar参数有没有设置正确呀。你先看下你的wav的采样频率是多少。然后设置ar参数。
如果你的wav采样为8000 则为-ar 8000 .纯粹支持呵呵!
[解决办法]
查一下pcm流的采样率,要和MP3编码的采样率对得上,如果象你说的是变快了,就是pcm得采样率小于mp3编码需要的pcm流的采样率
比如pcm的采样率是8K,而你mp3编码器设定原始pcm数据流为48K,这样编出来的mp3就短了6倍