#define __STDC_CONSTANT_MACROS
#ifdef _WIN32
//Windows
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavutil/pixfmt.h"
#include <libswresample/swresample.h>
#include <libavfilter/avfilter.h>
#include <libavfilter/avfiltergraph.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/samplefmt.h>
#include "libavutil/avutil.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
};
#else
//Linux...
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/pixfmt.h>
#ifdef __cplusplus
};
#endif
#endif
#include <stdio.h>
#include<windows.h>
#include <conio.h>
#include <ctype.h>
#include <iostream>
#include <vector>
#include <signal.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
static void writeWavHeader(AVCodecContext *pCodecCtx, AVFormatContext *pFormatCtx, FILE *audioFile) {
//wav文件有44字节的wav头,所以要写44字节的wav头
int8_t *data;
int32_t long_temp;
int16_t short_temp;
int16_t BlockAlign;
int bits = 16;
int32_t fileSize;
int32_t audioDataSize;
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;
}
audioDataSize = (pFormatCtx->duration)*(bits / 8)*(pCodecCtx->sample_rate)*(pCodecCtx->channels);
fileSize = audioDataSize + 36;
data = (int8_t *)"RIFF";
fwrite(data, sizeof(char), 4, audioFile);
fwrite(&fileSize, sizeof(int32_t), 1, audioFile);
data = (int8_t *)"WAVE";
fwrite(data, sizeof(char), 4, audioFile);
data = (int8_t *)"fmt ";
fwrite(data, sizeof(char), 4, audioFile);
long_temp = 16;
fwrite(&long_temp, sizeof(int32_t), 1, audioFile);
short_temp = 0x01;
fwrite(&short_temp, sizeof(int16_t), 1, audioFile);
short_temp = (pCodecCtx->channels);
fwrite(&short_temp, sizeof(int16_t), 1, audioFile);
long_temp = (pCodecCtx->sample_rate);
fwrite(&long_temp, sizeof(int32_t), 1, audioFile);
long_temp = (bits / 8)*(pCodecCtx->channels)*(pCodecCtx->sample_rate);
fwrite(&long_temp, sizeof(int32_t), 1, audioFile);
BlockAlign = (bits / 8)*(pCodecCtx->channels);
fwrite(&BlockAlign, sizeof(int16_t), 1, audioFile);
short_temp = (bits);
fwrite(&short_temp, sizeof(int16_t), 1, audioFile);
data = (int8_t *) "data";
fwrite(data, sizeof(char), 4, audioFile);
fwrite(&audioDataSize, sizeof(int32_t), 1, audioFile);
fseek(audioFile, 44, SEEK_SET);
}
int main()
{
char *filename = "ffmpegTest.mp4";
AVFormatContext *pFormatCtx = NULL;
int audioStream = -1;
int i;
int iFrame = 0;
AVCodecContext *pCodecCtx;
AVCodec *pCodec = NULL;
static AVPacket packet;
uint8_t *pktData = NULL;
int pktSize;
int outSize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
//这里必须使用av_malloc
uint8_t *inbuf = (uint8_t *)av_malloc(outSize);
FILE *wavFile = NULL;
int32_t audioFileSize = 0;
//注册所有的编解码器
av_register_all();
//打开文件
if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) < 0)
{
printf("Could not open input file %s\n", filename);
return 0;
}
if (av_find_stream_info(pFormatCtx)<0)
{
printf("Could not find stream information\n");
}
av_dump_format(pFormatCtx, 0, filename, 0);
for (i = 0; i<pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
audioStream = i;
break;
}
}
pCodecCtx = pFormatCtx->streams[audioStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
//open codec
if (avcodec_open2(pCodecCtx, pCodec, NULL)<0) {
printf("Error avcodec_open failed.\n");
return 1;
}
wavFile = fopen("E:\\flv\\YY.wav", "wb");
if (wavFile == NULL)
{
printf("open error\n");
return 1;
}
//write wav header
writeWavHeader(pCodecCtx, pFormatCtx, wavFile);
//open codec frame
av_free_packet(&packet);
while (av_read_frame(pFormatCtx, &packet) >= 0) {
if (packet.stream_index == audioStream)
{
int len = 0;
if ((iFrame++) >= 4000)
break;
pktData = packet.data;
pktSize = packet.size;
while (pktSize>0) {
outSize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
len = avcodec_decode_audio3(pCodecCtx, (short *)inbuf, &outSize, &packet);
if (len<0) {
printf("Error while decoding\n");
break;
}
if (outSize>0) {
audioFileSize += outSize;
fwrite(inbuf, 1, outSize, wavFile);
fflush(wavFile);
}
pktSize -= len;
pktData += len;
}
}
av_free_packet(&packet);
}
fseek(wavFile, 40, SEEK_SET);
fwrite(&audioFileSize, 1, sizeof(int32_t), wavFile);
audioFileSize += 36;
fseek(wavFile, 4, SEEK_SET);
fwrite(&audioFileSize, 1, sizeof(int32_t), wavFile);
fclose(wavFile);
av_free(inbuf);
if (pCodecCtx != NULL) {
avcodec_close(pCodecCtx);
}
av_close_input_file(pFormatCtx);
printf("输入任意键退出!");
getchar();
}
#ifdef _WIN32
//Windows
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavutil/pixfmt.h"
#include <libswresample/swresample.h>
#include <libavfilter/avfilter.h>
#include <libavfilter/avfiltergraph.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/samplefmt.h>
#include "libavutil/avutil.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
};
#else
//Linux...
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/pixfmt.h>
#ifdef __cplusplus
};
#endif
#endif
#include <stdio.h>
#include<windows.h>
#include <conio.h>
#include <ctype.h>
#include <iostream>
#include <vector>
#include <signal.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
static void writeWavHeader(AVCodecContext *pCodecCtx, AVFormatContext *pFormatCtx, FILE *audioFile) {
//wav文件有44字节的wav头,所以要写44字节的wav头
int8_t *data;
int32_t long_temp;
int16_t short_temp;
int16_t BlockAlign;
int bits = 16;
int32_t fileSize;
int32_t audioDataSize;
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;
}
audioDataSize = (pFormatCtx->duration)*(bits / 8)*(pCodecCtx->sample_rate)*(pCodecCtx->channels);
fileSize = audioDataSize + 36;
data = (int8_t *)"RIFF";
fwrite(data, sizeof(char), 4, audioFile);
fwrite(&fileSize, sizeof(int32_t), 1, audioFile);
data = (int8_t *)"WAVE";
fwrite(data, sizeof(char), 4, audioFile);
data = (int8_t *)"fmt ";
fwrite(data, sizeof(char), 4, audioFile);
long_temp = 16;
fwrite(&long_temp, sizeof(int32_t), 1, audioFile);
short_temp = 0x01;
fwrite(&short_temp, sizeof(int16_t), 1, audioFile);
short_temp = (pCodecCtx->channels);
fwrite(&short_temp, sizeof(int16_t), 1, audioFile);
long_temp = (pCodecCtx->sample_rate);
fwrite(&long_temp, sizeof(int32_t), 1, audioFile);
long_temp = (bits / 8)*(pCodecCtx->channels)*(pCodecCtx->sample_rate);
fwrite(&long_temp, sizeof(int32_t), 1, audioFile);
BlockAlign = (bits / 8)*(pCodecCtx->channels);
fwrite(&BlockAlign, sizeof(int16_t), 1, audioFile);
short_temp = (bits);
fwrite(&short_temp, sizeof(int16_t), 1, audioFile);
data = (int8_t *) "data";
fwrite(data, sizeof(char), 4, audioFile);
fwrite(&audioDataSize, sizeof(int32_t), 1, audioFile);
fseek(audioFile, 44, SEEK_SET);
}
int main()
{
char *filename = "ffmpegTest.mp4";
AVFormatContext *pFormatCtx = NULL;
int audioStream = -1;
int i;
int iFrame = 0;
AVCodecContext *pCodecCtx;
AVCodec *pCodec = NULL;
static AVPacket packet;
uint8_t *pktData = NULL;
int pktSize;
int outSize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
//这里必须使用av_malloc
uint8_t *inbuf = (uint8_t *)av_malloc(outSize);
FILE *wavFile = NULL;
int32_t audioFileSize = 0;
//注册所有的编解码器
av_register_all();
//打开文件
if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) < 0)
{
printf("Could not open input file %s\n", filename);
return 0;
}
if (av_find_stream_info(pFormatCtx)<0)
{
printf("Could not find stream information\n");
}
av_dump_format(pFormatCtx, 0, filename, 0);
for (i = 0; i<pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
audioStream = i;
break;
}
}
pCodecCtx = pFormatCtx->streams[audioStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
//open codec
if (avcodec_open2(pCodecCtx, pCodec, NULL)<0) {
printf("Error avcodec_open failed.\n");
return 1;
}
wavFile = fopen("E:\\flv\\YY.wav", "wb");
if (wavFile == NULL)
{
printf("open error\n");
return 1;
}
//write wav header
writeWavHeader(pCodecCtx, pFormatCtx, wavFile);
//open codec frame
av_free_packet(&packet);
while (av_read_frame(pFormatCtx, &packet) >= 0) {
if (packet.stream_index == audioStream)
{
int len = 0;
if ((iFrame++) >= 4000)
break;
pktData = packet.data;
pktSize = packet.size;
while (pktSize>0) {
outSize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
len = avcodec_decode_audio3(pCodecCtx, (short *)inbuf, &outSize, &packet);
if (len<0) {
printf("Error while decoding\n");
break;
}
if (outSize>0) {
audioFileSize += outSize;
fwrite(inbuf, 1, outSize, wavFile);
fflush(wavFile);
}
pktSize -= len;
pktData += len;
}
}
av_free_packet(&packet);
}
fseek(wavFile, 40, SEEK_SET);
fwrite(&audioFileSize, 1, sizeof(int32_t), wavFile);
audioFileSize += 36;
fseek(wavFile, 4, SEEK_SET);
fwrite(&audioFileSize, 1, sizeof(int32_t), wavFile);
fclose(wavFile);
av_free(inbuf);
if (pCodecCtx != NULL) {
avcodec_close(pCodecCtx);
}
av_close_input_file(pFormatCtx);
printf("输入任意键退出!");
getchar();
}