- 主要思路
打开目标文件输入流,读取相关流信息,找出'best'流的索引index,读取流中的frame中数据写入&pkt然后写入文件
- 相关代码
#include <stdio.h> #include <libavutil/log.h> #include <libavformat/avio.h> #include <libavformat/avformat.h> #define ADTS_HEADER_LEN 7; void adts_header(char *szAdtsHeader, int dataLen){ int audio_object_type = 2; int sampling_frequency_index = 7; int channel_config = 2; int adtsLen = dataLen + 7; szAdtsHeader[0] = 0xff; //syncword:0xfff 高8bits szAdtsHeader[1] = 0xf0; //syncword:0xfff 低4bits szAdtsHeader[1] |= (0 << 3); //MPEG Version:0 for MPEG-4,1 for MPEG-2 1bit szAdtsHeader[1] |= (0 << 1); //Layer:0 2bits szAdtsHeader[1] |= 1; //protection absent:1 1bit szAdtsHeader[2] = (audio_object_type - 1)<<6; //profile:audio_object_type - 1 2bits szAdtsHeader[2] |= (sampling_frequency_index & 0x0f)<<2; //sampling frequency index:sampling_frequency_index 4bits szAdtsHeader[2] |= (0 << 1); //private bit:0 1bit szAdtsHeader[2] |= (channel_config & 0x04)>>2; //channel configuration:channel_config 高1bit szAdtsHeader[3] = (channel_config & 0x03)<<6; //channel configuration:channel_config 低2bits szAdtsHeader[3] |= (0 << 5); //original:0 1bit szAdtsHeader[3] |= (0 << 4); //home:0 1bit szAdtsHeader[3] |= (0 << 3); //copyright id bit:0 1bit szAdtsHeader[3] |= (0 << 2); //copyright id start:0 1bit szAdtsHeader[3] |= ((adtsLen & 0x1800) >> 11); //frame length:value 高2bits szAdtsHeader[4] = (uint8_t)((adtsLen & 0x7f8) >> 3); //frame length:value 中间8bits szAdtsHeader[5] = (uint8_t)((adtsLen & 0x7) << 5); //frame length:value 低3bits szAdtsHeader[5] |= 0x1f; //buffer fullness:0x7ff 高5bits szAdtsHeader[6] = 0xfc; } int main(int argc, char *argv[]) { int err_code; char errors[1024]; char *src_filename = NULL; char *dst_filename = NULL; FILE *dst_fd = NULL; int audio_stream_index = -1; int len; AVFormatContext *ofmt_ctx = NULL; AVPacket pkt; av_log_set_level(AV_LOG_DEBUG); if(argc < 3){ av_log(NULL, AV_LOG_DEBUG, "the count of parameters should be more than three!\n"); return -1; } src_filename = argv[1]; dst_filename = argv[2]; // xxx.aac if(src_filename == NULL || dst_filename == NULL){ av_log(NULL, AV_LOG_DEBUG, "src or dts file is null, plz check them!\n"); return -1; } /*register all formats and codec*/ av_register_all(); dst_fd = fopen(dst_filename, "wb"); if (!dst_fd) { av_log(NULL, AV_LOG_DEBUG, "Could not open destination file %s\n", dst_filename); return -1; } /*open input media file, and allocate format context*/ if((err_code = avformat_open_input(&fmt_ctx, src_filename, NULL, NULL)) < 0){ av_strerror(err_code, errors, 1024); av_log(NULL, AV_LOG_DEBUG, "Could not open source file: %s, %d(%s)\n", src_filename, err_code, errors); return -1; } /*retrieve audio stream*/ if((err_code = avformat_find_stream_info(fmt_ctx, NULL)) < 0) { av_strerror(err_code, errors, 1024); av_log(NULL, AV_LOG_DEBUG, "failed to find stream information: %s, %d(%s)\n", src_filename, err_code, errors); return -1; } /*dump input information*/ av_dump_format(fmt_ctx, 0, src_filename, 0); /*initialize packet*/ av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; /*find best audio stream*/ audio_stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0); if(audio_stream_index < 0){ av_log(NULL, AV_LOG_DEBUG, "Could not find %s stream in input file %s\n", av_get_media_type_string(AVMEDIA_TYPE_AUDIO), src_filename); return AVERROR(EINVAL); } /*read frames from media file*/ while(av_read_frame(fmt_ctx, &pkt) >=0 ){ if(pkt.stream_index == audio_stream_index){ char adts_header_buf[7]; adts_header(adts_header_buf, pkt.size); fwrite(adts_header_buf, sizeof(char), 7, dst_fd); len = fwrite( pkt.data, 1, pkt.size, dst_fd); if(len != pkt.size){ av_log(NULL, AV_LOG_DEBUG, "warning, length of writed data isn't equal pkt.size(%d, %d)\n", len, pkt.size); } } av_packet_unref(&pkt); } /*close input media file*/ avformat_close_input(&fmt_ctx); if(dst_fd) { fclose(dst_fd); } return 0; }
文章来源: https://blog.csdn.net/yan822/article/details/91041089