`
chriszeng87
  • 浏览: 743412 次
  • 性别: 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模式获取数据,具体...

    FFMPEG 常用命令.pdf

    2. 解复用 3. 视频转码 4. 视频封装 5. 视频剪切 6. 视频录制 7.叠加水印 8.将MP3转换为PCM数据 9. 推送RTP流、接收RTP流并存为ts文件 10. ffmpeg 编码 11. ffmpeg 解码 12. 截取 YUV 13. 压缩分辨率 14...

    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