求助利用ffmpeg抽取mp4中音频并保存为wav格式

heartandheart 2013-04-13 06:13:18
MP4文件大小19M,抽取后的音频文件大小为130M,还有噪音,时间也被拉长了,请问这是怎么回事?
代码如下:
#include <windows.h>

#include <iostream>
using namespace std;

extern "C"
{
#include "libavcodec\avcodec.h"
#include "libavformat\avformat.h"
}

#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avcodec.lib")

#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000

struct RIFF_HEADER
{
char szRiffID[4];
DWORD dwRiffSize;
char szRiffFormat[4];
};

struct FMT_BLOCK
{
char szFmtID[4];
DWORD dwFmtSize;
WORD wFormatTag;
WORD wChannels;
DWORD dwSamplesPerSec;
DWORD dwAvgBytesPerSec;
WORD wBlockAlign;
WORD wBitsPerSample;
};

struct DATA_BLOCK
{
char szDataID[4];
DWORD dwDataSize;
};

int main()
{
AVFormatContext* pFormatCtx = NULL;
AVCodecContext* pCodecCtx;
AVCodec* pCodec = NULL;
AVPacket packet;

int AudioStream = -1;

char* SrcFile = "test.mp3";

av_register_all();

if(avformat_open_input(&pFormatCtx, SrcFile, NULL, NULL) != 0)
{
cout << "Cannot open source file!" << endl;

return -1;
}

if(av_find_stream_info(pFormatCtx) < 0)
{
cout << "Cannot find stream info!" << endl;

return -1;
}

av_dump_format(pFormatCtx, 0, SrcFile, false);

for(int i = 0; i < pFormatCtx->nb_streams; i++)
{
if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{
AudioStream = i;
break;
}
}

if(AudioStream == -1)
{
cout << "Cannot find a audio stream!" << endl;

return -1;
}

pCodecCtx = pFormatCtx->streams[AudioStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);

if(pCodec == NULL)
{
cout << "Cannot find codec!" << endl;

return -1;
}

if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
{
cout << "Cannot open codec!" << endl;

return -1;
}

uint8_t* pktData;
int pktSize, outSize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
uint8_t* inBuf = (uint8_t*)malloc(outSize);

FILE* pWavFile;
pWavFile = fopen("r.wav", "wb");
while(av_read_frame(pFormatCtx, &packet) >= 0)
{
if(packet.stream_index == AudioStream)
{
pktData = packet.data;
pktSize = packet.size;
while(pktSize > 0)
{
outSize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
int len = avcodec_decode_audio3(pCodecCtx, (int16_t*)inBuf, &outSize, &packet);
if(len < 0)
{
cout << "Error while decoding!" << endl;
break;
}
if(outSize > 0)
{
fwrite(inBuf, 1, outSize, pWavFile);
fflush(pWavFile);
}
pktSize -= len;
//pktData += len;
}
}
av_free_packet(&packet);
}

free(inBuf);

fseek(pWavFile, 0, SEEK_SET);

int bits;
switch(pCodecCtx->sample_fmt)
{
case AV_SAMPLE_FMT_S16:
bits = 16; break;
case AV_SAMPLE_FMT_S32:
bits = 32; break;
case AV_SAMPLE_FMT_U8:
bits = 8; break;
default:
bits = 16; break;
}
printf("bits:%d sample_rate:%d channels:%d sample_fmt:%d\n", bits, pCodecCtx->sample_rate, pCodecCtx->channels, pCodecCtx->sample_fmt);

RIFF_HEADER riffHeader;
memcpy(riffHeader.szRiffID, "RIFF", 4);
riffHeader.dwRiffSize = pFormatCtx->duration * (bits / 8) * pCodecCtx->sample_rate * pCodecCtx->channels + 36;
memcpy(riffHeader.szRiffFormat, "WAVE", 4);
fwrite(&riffHeader, 1, sizeof(riffHeader), pWavFile);

FMT_BLOCK fmtBlock;
memcpy(fmtBlock.szFmtID, "fmt ", 4);
fmtBlock.dwFmtSize = 0x10;
fmtBlock.wFormatTag = 0x01;
fmtBlock.wChannels = pCodecCtx->channels;
fmtBlock.dwSamplesPerSec = pCodecCtx->sample_rate;
fmtBlock.dwAvgBytesPerSec = (bits / 8) * pCodecCtx->sample_rate * pCodecCtx->channels;
fmtBlock.wBlockAlign = (bits / 8) * pCodecCtx->channels;
fmtBlock.wBitsPerSample = bits;
fwrite(&fmtBlock, 1, sizeof(fmtBlock), pWavFile);

DATA_BLOCK dataBlock;
memcpy(dataBlock.szDataID, "data", 4);
dataBlock.dwDataSize = (bits / 8) * pFormatCtx->duration * pCodecCtx->sample_rate * pCodecCtx->channels;
fwrite(&dataBlock, 1, sizeof(dataBlock), pWavFile);
fflush(pWavFile);
fseek(pWavFile, 44, SEEK_SET);

fclose(pWavFile);
avcodec_close(pCodecCtx);
av_close_input_file(pFormatCtx);

cout << "Success!" << endl;
cin.get();

return 0;
}
...全文
1398 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
heartandheart 2013-10-31
  • 打赏
  • 举报
回复
引用 2 楼 neuredfox 的回复:
楼主就想理解这个过程呢, 请问楼主,有无解决这个问题呀。
用一楼的方法直接调用就可以了,放弃代码了
neuredfox 2013-10-25
  • 打赏
  • 举报
回复
楼主就想理解这个过程呢, 请问楼主,有无解决这个问题呀。
SoftSoftSoft2008 2013-04-14
  • 打赏
  • 举报
回复
调用 ffmpeg ,一句话就可以完成了 ffmpeg -i xxx.mp4 -o xxx.mp3

2,542

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧