`
chriszeng87
  • 浏览: 736918 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ffmpeg解复用视频文件

阅读更多

转自:http://blog.chinaunix.net/uid-24922718-id-3692670.html

 

 解复用视频文件:就是提取出音频文件和视频文件的ES流数据。而对于aac和h264来说,提取出来的数据直接保存并不能成功的播放,原因就在ffmpeg解出的ES数据比较纯净,没有ADTS头,而很多解码器都是需要ADTS头信息来进行解码的,所以就要对aac数据进行头部adts结构的添加。
     对于h264文件来说,h264有两种封装,
一种是annexb模式,传统模式,有startcode,SPS和PPS是在ES中
一种是mp4模式,一般mp4 mkv会有,没有startcode,SPS和PPS以及其它信息被封装在container中,每一个frame前面是这个frame的长度
很多解码器只支持annexb这种模式,因此需要将mp4做转换:
在ffmpeg中用h264_mp4toannexb_filter可以做转换
实现:
注册filter
avcbsfc = av_bitstream_filter_init("h264_mp4toannexb");
转换bitstream
av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
AVCodecContext *avctx, const char *args,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size, int keyframe)

核心代码:

点击(此处)折叠或打开

  1. #include <libavformat/avformat.h>
  2. #include <libavcodec/avcodec.h>
  3. #include <stdio.h>
  4. static int audioindex = -1;
  5. static int videoindex = -1;
  6. static int isaaccodec = -1;
  7. int main(int argc ,char **argv)
  8. {
  9.     av_register_all();
  10.     FILE *= NULL;
  11.     FILE *= NULL;
  12.     f = fopen("audio","wb");
  13.     g = fopen("video","wb");
  14.     if(!|| !g)
  15.     {
  16.         printf("open write file errorn");
  17.         return 0;
  18.     }
  19.     AVFormatContext *fmtctx = NULL;
  20.     AVPacket audiopack;
  21.     if(avformat_open_input(&fmtctx,argv[1],NULL,NULL) < 0)
  22.     {
  23.         printf("open fmtctx errorn");
  24.         return 0;
  25.     }
  26.     if(avformat_find_stream_info(fmtctx,NULL) < 0)
  27.     {
  28.         printf("find stream info n");
  29.         return 0;
  30.     }
  31.     int streamnum = fmtctx->nb_streams;
  32.     printf("stream num is %dn",streamnum);
  33.     int i=0;
  34.     for(;i<streamnum;i++)
  35.     {
  36.         if(fmtctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audioindex == -1)
  37.         {
  38.             audioindex = i; 
  39.         }
  40.         else if(fmtctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && videoindex == -1)
  41.         {
  42.             videoindex = i;
  43.         }
  44.     }
  45.     printf("audioindex is %dn",audioindex);
  46.     printf("videoindex is %dn",videoindex);
  47.     AVCodecContext *codecctx = fmtctx->streams[videoindex]->codec;
  48.     AVCodec *decode = avcodec_find_decoder(codecctx->codec_id);
  49.     AVCodecContext *audioCodecCtx = fmtctx->streams[audioindex]->codec;
  50.     AVCodec *audiodecode = avcodec_find_decoder(audioCodecCtx->codec_id);
  51.     if(audiodecode->id == AV_CODEC_ID_AAC)
  52.     {
  53.         isaaccodec = 1;
  54.     }
  55.     if(avcodec_open2(codecctx,decode,NULL) < 0)
  56.     {
  57.         return -1;
  58.     }
  59.     if(avcodec_open2(audioCodecCtx,audiodecode,NULL) < 0)
  60.     {
  61.         return -1;
  62.     }
  63.     printf("extradata size is %dn",audioCodecCtx->extradata_size);
  64.     AVBitStreamFilterContext* bsfc = av_bitstream_filter_init("h264_mp4toannexb");
  65.     AVBitStreamFilterContext* aacbsfc = av_bitstream_filter_init("aac_adtstoasc");
  66.     if(!bsfc || !aacbsfc)
  67.     {
  68.         return 0;
  69.     }
  70.     AVFrame picture;
  71.     while(!(av_read_frame(fmtctx,&audiopack)))
  72.     {
  73.         if(audiopack.stream_index == 1)
  74.         {
  75.             if(isaaccodec == 1)
  76.             {
  77.                 char bits[7] = {0};
  78.                 int sample_index = 0 , channel = 0;
  79.                 char temp = 0;
  80.                 int length = 7 + audiopack.size;
  81.                 sample_index = (audioCodecCtx->extradata[0] & 0x07) << 1;
  82.                 temp = (audioCodecCtx->extradata[1]&0x80);
  83.                 switch(audioCodecCtx->sample_rate)
  84.                 {
  85.                     case 44100:
  86.                         {
  87.                             sample_index = 0x7;
  88.                         }break;
  89.                     default:
  90.                         {
  91.                             sample_index = sample_index + (temp>>7);
  92.                         }break;
  93.                 }
  94.                 channel = ((audioCodecCtx->extradata[1] - temp) & 0xff) >> 3;
  95.                 bits[0] = 0xff;
  96.                 bits[1] = 0xf1;
  97.                 bits[2] = 0x40 | (sample_index<<2) | (channel>>2);
  98.                 bits[3] = ((channel&0x3)<<6) | (length >>11);
  99.                 bits[4] = (length>>3) & 0xff;
  100.                 bits[5] = ((length<<5) & 0xff) | 0x1f;
  101.                 bits[6] = 0xfc;
  102.                 fwrite(bits,1,7,f);
  103.             }
  104.             fwrite(audiopack.data,1,audiopack.size,f);
  105.             printf("audio pts is %fn",audiopack.pts*av_q2d(fmtctx->streams[audioindex]->time_base));
  106.         }
  107.         else if(audiopack.stream_index == videoindex){
  108.             AVPacket pkt = audiopack;
  109.             
  110.             int a = av_bitstream_filter_filter(bsfc, codecctx, NULL, &pkt.data, &pkt.size, audiopack.data, audiopack.size, audiopack.flags & AV_PKT_FLAG_KEY);
  111.             if(> 0)
  112.             {
  113.                 audiopack = pkt;
  114.             }
  115.             fwrite(audiopack.data,1,audiopack.size,g);
  116.             int gotfinished = 0;
  117.             if(avcodec_decode_video2(codecctx,&picture,&gotfinished,&audiopack) < 0)
  118.             {
  119.                 printf("decode video errorn");
  120.             }
  121.             if(picture.key_frame)
  122.             {
  123.                 //printf("key framen");
  124.             }
  125.             else{
  126.                 //printf("frame num is %dn",picture.pict_type);
  127.             }
  128.             //printf("video pts is %f, %dn",picture.pkt_dts * av_q2d(fmtctx->streams[videoindex]->codec->time_base),picture.pts );
  129.         }
  130.         av_free_packet(&audiopack);
  131.     }
  132.     fclose(f);
  133. }


最后就可以用vlc 或ffplay来查看解析出来的音频aac文件和264文件,本套代码是通用解析器,任何视频文件都可以解析,只是对于264和aac单独做了处理。
贴上最后的效果图:

分享到:
评论

相关推荐

    解复用FLV文件(基于FFMPEG解析FLV(h264+aac))

    在本文中,我们将深入探讨如何利用FFmpeg解复用FLV(Flash Video)文件,这些文件通常包含H264视频和AAC音频。 首先,FLV是一种常见的网络流媒体格式,最初由Adobe Systems开发,用于在Flash Player中播放视频内容...

    音视频开发12 FFmpeg 解复用详情代码测试-使用不同的文件测试log

    通过对这些不同文件和代码的测试,开发者可以深入理解FFmpeg在处理各种文件格式时的行为,优化解复用流程,确保在实际应用中能够正确地处理音视频数据。这种测试方法对于软件开发来说是非常关键的,因为它能暴露潜在...

    TS复用解复用程序

    TS复用解复用程序是涉及数字视频广播(Digital Video Broadcasting, DVB)技术的一个重要环节,主要处理传输流(Transport Stream, TS)数据。在理解这个程序之前,我们需要先了解TS流的基本概念。 TS是一种专门...

    FFmpeg_15_视频流转码(含解复用、解码、编码

    在"FFmpeg_15_视频流转码(含解复用、解码、编码"这个主题中,我们将深入探讨FFmpeg在视频处理中的核心操作,包括如何进行视频的解复用、解码以及重新编码。 解复用(Demuxing)是视频处理的第一步,它的目的是将一...

    FFmpeg_解复用、复用,VC2010,一步内存操作到位

    解复用是指将多媒体文件中的音视频流分离出来,而复用则是将这些流打包到新的多媒体文件中。这个过程通常涉及到读取容器格式(如 MP4、FLV 或 MKV),提取对应的音视频编码数据,然后可能进行处理或转换,最后再写入...

    ffmpeg实现解复用MP4并解码音视频流

    该代码主要实现解复用MP4的媒体流,并且将视频流 音频流进行解码;保存到文件中; 目录: 1. 打开输入流 2.获取视频解码器 3.获取音频解码器 4.解复用 5.存文件; 存文件需要根据yuv的类型进行不同的存储方式: yuv...

    ffmpeg保存视频流

    ffmpeg是一个跨平台的命令行工具,用于转换多媒体数据,支持多种格式的音频视频文件的解码、编码、转码、复用、解复用等功能。此外,ffmpeg还支持流媒体协议,包括但不限于HTTP、RTMP、RTSP等,这使得通过网络传输音...

    [免费]FFmpeg视频、音频复用(VC2010).rar

    这些库为开发者提供了强大的功能,可以进行音视频的编码、解码、复用、解复用、转换等操作。 2. **视频和音频复用**: 复用是指将多个音视频流合并到一个容器文件中,如MP4、MKV等。FFmpeg通过libavformat库实现了...

    FFmpeg视频、音频复用(VC2010)

    VC2010下,基于FFmpeg实现H264视频、AAC音频复用合成为MP4影音文件,因我的两个资源原本就是一个TS流中解出来的,所以复用后是影音同步的,注释详尽,表示感谢雷霄骅,因我做FFmpeg的项目过程中,用了不少他的代码,...

    mp4 splitter_mp4解复用

    MP4 Splitter是一种工具,主要用于将MP4视频文件中的音频和视频流解复用出来,即将它们从复合的MP4容器格式中分离。这个过程在数字媒体处理中非常重要,因为有时候我们需要单独处理音频和视频,比如进行编辑、转码...

    无损视频合并ffmpeg

    在FFmpeg中,我们可以使用`concat`demuxer(解复用器)来实现这个目标。 以下是使用FFmpeg进行无损视频合并的基本步骤: 1. **创建文本文件**:首先,你需要创建一个包含所有待合并视频文件路径的文本文件,每行一...

    FFMPEG_TS_DEMUX_本地文件_1

    FFmpeg是一款强大的开源跨平台工具,用于处理音频和视频文件。在本教程中,我们将探讨如何使用FFmpeg进行TS(Transport Stream)文件的解复用,并将中间过程存储到本地,这对于初学者理解多媒体处理流程非常有帮助。...

    FFMPEG_FLV_MP4_TS_DEMUX_本地文件_1

    FFmpeg的`flv`解复用器可以解析FLV文件中的音视频数据,将其分离为原始的音频和视频帧。 2. MP4(MPEG-4 Part 14):这是广泛应用的多媒体容器格式,支持多种编解码器和流类型。FFmpeg的`mp4`解复用器能够处理这种...

    FLV解复用代码实现!!!!

    使用ffmpeg协议解复用FLV文件,获得h264视频数据和aac音频数据。 源码已经编译通过 并能够运行 能够进行循环读取文件, 通过数据类型获取音频,视频, 源码采用文件IO模式读取数据,另外还有内存IO模式获取数据,具体...

    android( 2017127_ffmpeg微信小视频录制和快速压缩,这个录制视频和压缩率太高了。

    FFmpeg是一个强大的开源多媒体处理框架,它支持音频、视频的编码、解码、转码、复用、解复用以及过滤等功能。在Android中,我们可以将FFmpeg编译为静态库或者动态库,然后集成到项目中,以便在应用中调用其API进行...

    FFMpeg音频、视频解码实例代码

    当处理一个流媒体视频文件时,首先要进行的是“解复用”(demuxing),这个过程是将文件中的不同流(如视频流和音频流)分离出来。FFmpeg中的`avformat_open_input`函数用于打开输入文件,并加载其元数据,`avformat...

    ffmpeg常用基本命令[参考].pdf

    使用 ffmpeg 可以将视频文件解复用为原始文件。例如,使用以下命令可以将 test.mp4 文件解复用为原始文件: ffmpeg –i test.mp4 –vcodec copy –an –f m4v test.264 视频转码 使用 ffmpeg 可以将视频文件转码...

    ffmpeg_lesson_code_testdemuxer.7z

    总之,"ffmpeg_lesson_code_testdemuxer.7z"是一个包含FFmpeg解复用器测试代码的资源包,对于想要学习或扩展FFmpeg功能的开发者来说,这是一个宝贵的教育资源。通过研究这些代码,你可以掌握如何处理媒体文件的结构...

    C#获取视频文件信息及视频转码操作

    如果需要处理这种格式的视频,可能还需要额外处理VOB文件的特殊性,例如解复用和封装到更通用的格式如MP4或MKV。 总的来说,C#处理视频文件的关键在于理解和使用合适的库,如FFmpeg,以及理解视频文件的元数据和...

Global site tag (gtag.js) - Google Analytics