// main.c
// ffmpeg
//
// Created by gang.zhou on 2019-08-10.
// Copyright © 2019 jove. All rights reserved.
//
#include <stdio.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>
#define MAX_AUDIO_FRAME_SIZE 192000
static void encodeAudio(AVCodecContext *ctx, AVPacket *pkt, AVFrame *frame, FILE *accF) {
if (NULL == ctx || NULL == pkt && NULL == frame && NULL == accF) {
exit(0);
}
int ret;
ret = avcodec_send_frame(ctx, frame);
printf("111\n");
if (ret < 0) {
fprintf(stderr, "Error sending the frame to the encoder\n");
exit(1);
}
while (ret >= 0) {
ret = avcodec_receive_packet(ctx, pkt);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return;
else if (ret < 0) {
fprintf(stderr, "Error encoding audio frame\n");
exit(1);
}
fwrite(pkt->data, 1, pkt->size, accF);
av_packet_unref(pkt);
}
}
static void decodeAudio(int out_buffer_size, SwrContext *swrContext, uint8_t *buffer, AVCodecContext *avCodecContext, AVPacket *avPacket, AVFrame *avFrame, FILE *pcmF) {
if (avcodec_send_packet(avCodecContext, avPacket) < 0) {
printf("avcodec_send_packet error \n");
exit(0);
}
for (;;) {
int ret = avcodec_receive_frame(avCodecContext, avFrame);
if (0 == ret) {
if (avFrame->pts >= 0) {
int data_size = av_get_bytes_per_sample(avCodecContext->sample_fmt);
if (data_size < 0) {
printf("av_get_bytes_per_sample error\n");
exit(0);
}
swr_convert(swrContext, &buffer, MAX_AUDIO_FRAME_SIZE
, (const uint8_t **) avFrame->data, avFrame->nb_samples);
fwrite(buffer, 1, out_buffer_size, pcmF);
av_frame_unref(avFrame);
}
} else if (AVERROR_EOF == ret) {
break;
} else if (AVERROR(EAGAIN) == ret) {
break;
} else {
printf("avcodec_receive_frame error \n");
exit(0);
}
}
av_packet_unref(avPacket);
}
int main(int argc, const char *argv[]) {
avformat_network_init();
AVFormatContext *avFormatContext = NULL;
if (avformat_open_input(&avFormatContext, "/Users/gang.zhou/ffmpeg/ffmpeg/zaojiaoji.mp4", NULL, NULL)) {
printf("avformat_open_input error\n");
exit(0);
}
if (avformat_find_stream_info(avFormatContext, NULL) < 0) {
printf("avformat_find_stream_in\n");
exit(0);
}
int aStreamIndex = -1;
int vStreamIndex = -1;
int sStreamIndex = -1;
for (int i = 0; i < avFormatContext->nb_streams; ++i) {
if (avFormatContext->streams[i]->codecpar->codec_type
== AVMEDIA_TYPE_VIDEO) {
vStreamIndex = i;
printf("Find Video Stream : %d \n", i);
} else if (avFormatContext->streams[i]->codecpar->codec_type
== AVMEDIA_TYPE_AUDIO) {
aStreamIndex = i;
printf("Find Audio Stream : %d \n", i);
} else if (avFormatContext->streams[i]->codecpar->codec_type
== AVMEDIA_TYPE_SUBTITLE) {
sStreamIndex = i;
printf("Find Subtitle Stream : %d \n", i);
}
}
if (-1 != aStreamIndex) {
AVCodec *avCodec =
avcodec_find_decoder(avFormatContext->streams[aStreamIndex]->codecpar->codec_id);
if (NULL == avCodec) {
printf("avcodec_find_decoder error \n");
exit(0);
}
printf("open decoder :%s\n", avCodec->name);
AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
printf("%s\n", codec->name);
AVCodecContext *avCodecContext = avFormatContext->streams[aStreamIndex]->codec;
printf("channels = %d\n", avCodecContext->channels);
printf("channel_layout = %lld\n", avCodecContext->channel_layout);
printf("bit_rate = %lld\n", avCodecContext->bit_rate);
printf("sample_rate = %d\n", avCodecContext->sample_rate);
printf("sample_fmt = %d\n", avCodecContext->sample_fmt);
printf("%d\n", avCodecContext->sample_fmt == AV_SAMPLE_FMT_FLTP);
avcodec_open2(avCodecContext, avCodec, NULL);
AVPacket *avPacket = av_packet_alloc();
if (NULL == avPacket) {
exit(0);
}
AVFrame *avFrame = av_frame_alloc();
if (NULL == avFrame) {
exit(0);
}
uint64_t out_channel_layout = AV_CH_LAYOUT_STEREO;
int out_nb_samples = avCodecContext->frame_size;
enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;
int out_sample_rate = 44100;
int out_channels = av_get_channel_layout_nb_channels(out_channel_layout);
int out_buffer_size = av_samples_get_buffer_size(NULL, out_channels, out_nb_samples, out_sample_fmt, 1);
uint8_t *out_buffer = (uint8_t *) av_malloc(MAX_AUDIO_FRAME_SIZE * 2);
int64_t in_channel_layout = av_get_default_channel_layout(avCodecContext->channels);
SwrContext *au_convert_ctx = swr_alloc();
au_convert_ctx = swr_alloc_set_opts(au_convert_ctx, out_channel_layout, out_sample_fmt, out_sample_rate,
in_channel_layout, avCodecContext->sample_fmt, avCodecContext->sample_rate, 0, NULL);
swr_init(au_convert_ctx);
FILE *pcmF = fopen("/Users/gang.zhou/ffmpeg/ffmpeg/wk.pcm", "wb");
FILE *aacF = fopen("/Users/gang.zhou/ffmpeg/ffmpeg/wk.aac", "wb");
while (!av_read_frame(avFormatContext, avPacket)) {
if (avPacket->stream_index == aStreamIndex) {
if (avPacket->pts >= 0) {
decodeAudio(out_buffer_size, au_convert_ctx, out_buffer, avCodecContext, avPacket, avFrame, pcmF);
}
}
}
if (avPacket->stream_index == aStreamIndex) {
decodeAudio(out_buffer_size, au_convert_ctx, out_buffer, avCodecContext, avPacket, avFrame, pcmF);
}
fflush(pcmF);
fclose(pcmF);
pcmF = fopen("/Users/gang.zhou/ffmpeg/ffmpeg/wk.pcm", "rb");
FILE *wavF = fopen("/Users/gang.zhou/ffmpeg/ffmpeg/wk.wav", "wb");
fseek(pcmF, 0L, SEEK_END);
int totalDataLen = ftell(pcmF) + 44 - 8;
fseek(pcmF, 0L, SEEK_SET);
unsigned char wavHeader[44] = {0};
wavHeader[0] = 'R';
wavHeader[1] = 'I';
wavHeader[2] = 'F';
wavHeader[3] = 'F';
wavHeader[4] = (totalDataLen & 0xff);
wavHeader[5] = (totalDataLen >> 8 & 0xff);
wavHeader[6] = (totalDataLen >> 16 & 0xff);
wavHeader[7] = (totalDataLen >> 24 & 0xff);
wavHeader[8] = 'W';
wavHeader[9] = 'A';
wavHeader[10] = 'V';
wavHeader[11] = 'E';
wavHeader[12] = 'f';
wavHeader[13] = 'm';
wavHeader[14] = 't';
wavHeader[15] = ' ';
wavHeader[16] = 0x10;
wavHeader[17] = 0;
wavHeader[18] = 0;
wavHeader[19] = 0;
wavHeader[20] = 1;
wavHeader[21] = 0;
wavHeader[22] = 2;
wavHeader[23] = 0;
wavHeader[24] = (44100 & 0xff);
wavHeader[25] = (44100 >> 8 & 0xff);
wavHeader[26] = (44100 >> 16 & 0xff);
wavHeader[27] = (44100 >> 24 & 0xff);
wavHeader[28] = (44100 * 4 & 0xff);
wavHeader[29] = (44100 * 4 >> 8 & 0xff);
wavHeader[30] = (44100 * 4 >> 16 & 0xff);
wavHeader[31] = (44100 * 4 >> 24 & 0xff);
wavHeader[32] = 4;
wavHeader[33] = 0;
wavHeader[34] = 16;
wavHeader[35] = 0;
wavHeader[36] = 'd';
wavHeader[37] = 'a';
wavHeader[38] = 't';
wavHeader[39] = 'a';
wavHeader[40] = ((totalDataLen - 36) & 0xff);
wavHeader[41] = ((totalDataLen - 36) >> 8 & 0xff);
wavHeader[42] = ((totalDataLen - 36) >> 16 & 0xff);
wavHeader[43] = ((totalDataLen - 36) >> 24 & 0xff);
fwrite(wavHeader, 1, 44, wavF);
u_int8_t buffer[1024] = {0};
int readBytes;
while ((readBytes = fread(buffer, 1, 1024, pcmF)) > 0) {
fwrite(buffer, 1, readBytes, wavF);
}
fflush(wavF);
fclose(pcmF);
fclose(wavF);
avcodec_close(avCodecContext);
av_frame_free(&avFrame);
av_packet_free(&avPacket);
avformat_free_context(avFormatContext);
}
return 0;
}
网友评论