VC++ 采用 ffmpeg 提取视频的音频 转码 wav 播放全程有很大杂音 如何解决,源码已附上

#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
/* current context */
static int is_full_screen;
static int64_t audio_callback_time;
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);


}
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;
    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\\yu.wav", "wb");


    if (wavFile == NULL)
    {
        printf("open error\n");
        return 1;
    }


    //write wav header
    writeWavHeader(pCodecCtx, pFormatCtx, wavFile);


    //start codec
    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/2, wavFile);
                    fflush(wavFile);
                }
                pktSize -= len;
                pktData += len;
            }
        }
        av_free_packet(&packet);
    }
    fclose(wavFile);
    av_free(inbuf);
    if (pCodecCtx != NULL) {
        avcodec_close(pCodecCtx);
    }
    av_close_input_file(pFormatCtx);
    printf("输入任意键退出!");
    getchar();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值