FFmpeg 抽取出音频流数据

这个程序实现了从音视频文件中抽取出音频流数据并保存成wav音频格式文件的功能。


#include "avcodec.h"
#include "avformat.h"
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <windows.h>

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

struct RIFF_HEADER{
        char    szRiffID[4]; //= {'R','I','F','F'};
        DWORD   dwRiffSize;
        char    szRiffFormat[4]; //"WAVE"
};

struct WAVE_FORMAT{
        char szWaveID[4];
        DWORD wFSize;
        WORD wFormatTag;
        WORD wChannels;
        DWORD dwSamplesPerSec;
        DWORD dwAvgBytesPerSec;
        WORD wBlockAlign;
        WORD wBitsPerSample;
};

struct FMT_BLOCK{
        char szFmtID[4];// 'f','m','t',' '
        DWORD dwFmtSize;
        WAVE_FORMAT wavFormat;
};

struct DATA_BLOCK{
        char szDataID[4]; // 'd','a','t','a'
        DWORD dwDataSize;
};

int main()
{
        AVFormatContext *pFormatCtx;
        int             i, audioStream;
        AVCodecContext  *pCodecCtx;
        AVCodec         *pCodec;
        AVPacket         packet;
        
        char* infile="b.mp4";
        
        av_register_all();
        
        if (av_open_input_file(&pFormatCtx, infile, NULL, 0, NULL) != 0)
                return -1; // Couldn't open file
        
        if (av_find_stream_info(pFormatCtx) < 0)
                return -1; // Couldn't find stream information
        
        dump_format(pFormatCtx, 0, infile, false);
        
        
        audioStream = -1;
        for (i=0; i<pFormatCtx->nb_streams; i++)
        {
                if(pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO){
                        audioStream=i;
                        break;
                }
        }
        if (audioStream == -1)
                return -1; // Didn't find a video stream
        
        pCodecCtx = pFormatCtx->streams[audioStream]->codec;
        
        pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
        if (pCodec == NULL)
                return -1; // Codec not found
        
        if (avcodec_open(pCodecCtx, pCodec) < 0)
                return -1; // Could not open codec
        
        uint8_t *pktdata;
        int pktsize;
        int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE*100;
        uint8_t * inbuf = (uint8_t *)malloc(out_size);
        FILE* pFileWav;
        int fileSize;
        
        pFileWav= fopen("b.wav","wb");
        fseek(pFileWav,44,SEEK_SET);
        fileSize = 44;
        while(av_read_frame(pFormatCtx, &packet)>=0) {
                if(packet.stream_index==audioStream) {
                        pktdata = packet.data;
                        pktsize = packet.size;
                        while(pktsize>0)
                        {
                                out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE*100;
                                //解码
                                int len = avcodec_decode_audio(pCodecCtx,(short*)inbuf,&out_size,pktdata,pktsize);
                                if (len<0)
                                {
                                        printf("Error while decoding.\n");
                                        break;
                                }
                                if(out_size>0)
                                {
                                        fwrite(inbuf,1,out_size,pFileWav);//pcm记录
                                        fflush(pFileWav);
                                        fileSize += out_size;
                                }
                                pktsize -= len;
                                pktdata += len;
                        }
                }        
                av_free_packet(&packet);
        }
        //写头部信息
        fseek(pFileWav,0,SEEK_SET);
        RIFF_HEADER riffHeader;
        memcpy(riffHeader.szRiffID,"RIFF",4);
        riffHeader.dwRiffSize = fileSize - 8;
        memcpy(riffHeader.szRiffFormat,"WAVE",4);
        fwrite(&riffHeader,1,sizeof(riffHeader),pFileWav);
        
        WAVE_FORMAT waveFormat;
        memcpy(waveFormat.szWaveID,"fmt ",4);
        waveFormat.wFSize = 0x10;
        waveFormat.wFormatTag = 1 ; //pcm
        waveFormat.wChannels = pCodecCtx->channels;
        waveFormat.dwSamplesPerSec = pCodecCtx->sample_rate;
        waveFormat.wBlockAlign =  pCodecCtx->bits_per_sample/8 * waveFormat.wChannels;//(多个声道)每个采样的字节数,
        waveFormat.dwAvgBytesPerSec = waveFormat.dwSamplesPerSec*waveFormat.wBlockAlign; // 每秒钟的字节数
        waveFormat.wBitsPerSample = pCodecCtx->bits_per_sample; //一个声道每个采样的bit数
        fwrite(&waveFormat,1,sizeof(waveFormat),pFileWav);
        
        DATA_BLOCK dataBlock;
        memcpy(dataBlock.szDataID,"data",4);
        dataBlock.dwDataSize = fileSize - 44;
        fwrite(&dataBlock,1,sizeof(dataBlock),pFileWav);
        
        avcodec_close(pCodecCtx);
        av_close_input_file(pFormatCtx);
        return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值