FFMPEG起航之旅

https://blog.csdn.net/explorer_day/article/category/6289310/2

https://www.cnblogs.com/tocy/p/ffmpeg-framework-analysis.html

https://blog.csdn.net/fakine/article/details/79076072

一、FFMPEG的基本概念

  1.FFMPEG的处理的基本流程   

  

  2.FFMPEG基本信息查询

   

  3.录制屏幕的命令

   ffmpeg -f avfoundation  -i 1 -r 30 -s 3360x2100 out.yuv 

   

    ffplay -s 3360x2100 out.yuv : 表示把原始数据指定为多大参数进行展    

            ffmpeg -f avfoundation -list_devices true -i "" :  查询ffmpeg所支持设备里面的列表,也就是上面的 -i 后面所带的参数,1就是代表屏幕

            

     4.声音的录制

      ffmpeg -f avfoundation -i :1 out.wav : 音频的声音录制

     5. 视频的分解与复用

     ffmpeg -i out.mp4  -vcoedc copy -acodec copy out.flv    

     

     抽取音频:ffmpeg -i out.mp4 -an -vcodec copy out.h264c

     抽取视频:ffmpeg -i out.mp4 -vn  -acodec copy out.h264c

    6.提取音视频的原始数据

      ffmpeg -i out.mp4  -an  -c:v  rawvideo  -pix_fmt yuv420p  out1.yuv  : 提取视频的yuv的原始数据

      ffmpeg -i out.mp4  -vn  -ar 44100 -ac 2 -f s16le out.pcm  : 提取音频的pcm的原始数据

      

      处理方式:ffplay -ar 44100 -ac 2  -f s16le out.pcm  :播放时候给出准确的采样率、声道数、播放格式

    7.音视频用滤镜对视频大小裁剪  

       ffmpeg -i out.mp4 -vf crop=in_w-200:in_h-200 -c:v libx264 -c:a copy out11.mp4    把视频大小进行裁剪

    8.ffmpeg对音视频进行裁剪、合并

      ffmpeg -i out.mp4 -ss 00:00:00 -t 3 caijian.mp4   对音视频裁剪3秒钟

      ffmpeg -f concat -i  input.txt  out.mp4                 将input.txt的列表音视频合并在一起    

      input.txt   文件内容是 file  '1.mp4'   

                file   '2.mp4' ...........

    9.图片与视频转换

      ffmpeg -i caijian.mp4  -r 1  -f image2 image-%3d.jpeg(这个是生成的名字)    视频转化成图片

      ffmpeg -i image-%3d.jpeg zsw.mp4       图片转换成视频

    10.ffmpeg直播推拉流

       ffmpeg -re -i zsw.mp4   -c(将音视频一起推送)copy  -f(以什么样格式去推) flv  rtmp://server/live/streamName(远端服务器名称) 将数据推送到某个服务器

       ffmpeg -i rtmp://server/live/streamName -c copy zsw.mp4     把服务器远端数据拉取下来

二、FFMPEG的基础开发

  1.FFMPEG代码结构

   

  2.FFMPEG的对文件删除以及重命名

   avpriv_io_delete("文件的目录") : 删除文件

   avpriv_io_move("原来名字",“新的名字”)  :  文件重命名

  3.FFMPEG对目录的打开以及显示  

   avio_open_dir()、avio_read_dir()、avio_closed_dir()

  4.抽取音频,这个时候是无法播放的,因为是pcm原始数据,需要加头信息,包括采样率、声道、采样格式等信息

  5.抽取视频:NALU里面包含sps是0x07、pps是0x08、关键帧是0x05、非关键帧:P帧是0x61、B帧是0x01。
        NAL单元是5,代表是关键帧,关键帧前面要有sps和pps的数据,还需要添加特征码(startcode)

   H264 NAL(是代表关键帧 I帧)的头解析:最开始帧是00 00 00 01为开头,这个是sps和pps的特征编码,非特征编码用三个字节 00 00 01为开头。

三、项目实战以及细节处理

  1.pcm转aac格式:原始数据必须为1024且需要加一些头文件信息 

    

    PCM --------> AAC  用到faac库

    PCM -------->MP3  用到lame库

  1.网络数据保存到本地的大致流程

       

  网络包:我们要传的url

四、播放器的制作

  1.解封装基本操作流程

       

  2.介绍AVFormatCOntext的成员变量

  .

  3.可以探测出没有头部信息或者没有封装格式  : avformat_find_stream_info(ic, 0);
  4.time_base : 成员变量有num(分子)、den(分母)
   duration : 代表视频的总时长
   avg_frame_rate : 帧率(注:对视频来说,这个挺重要的)

  

   5. AVMediaType : 代笔是音频还是视频的样式

    AVCodecID :  代表编码的格式,是H264还是FLV格式

    format : 视频代表是像素  音频代表是16位还是32位

  

  6. audioIndex = av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);  可以找到音视频的索引

  7.pts:显示时间,dts:解码时间. B帧是分析前一帧和后一帧的差异,没有B帧,pts和dts是相等的

   

  8.AVPacket的空间的创建

   

  9. av_seek_frame

   

   av_seek_frame 的最后一个参数的选取

   

  10. 可以通过AVStream的CodecID去传入找到合适的解码器

   

   11.为编解码器申请内存空间,在申请编解码空间把数据保存

          

    复制AVCodec里面的参数

   

   12.AVFrame : 一帧一帧的处理

         

   易错点,需要特别注意,data和linesize这个两个参数在音视频里面处理得当,下面会仔细讲解

   linesize视频里面表示一行数据的大小,在音频里面表示一个通道的数据大小

   data在视频里面包含平面格式交叉格式

   nb_samples : 代表音频单通道的样本数量

         

           

   13. 调用硬解码时候,C++层调用JAVA层代码需要传递一个函数av_jni_set_java_vm这个函数做处理

   14.视频格式的转换

     获取格式转换的上下文  :vctx = sws_getCachedContext(vctx, frame->width(原宽), frame->height(原高),(AVPixelFormat)(frame->format)(原格式),

                            720(输出宽), 1280(输出高), AV_PIX_FMT_RGBA(转换格式), SWS_FAST_BILINEAR(转换算法), 0, 0, 0);

    格式转换 : sws_scale(vctx, frame->data(原数据), frame->linesize(原大小), 0, frame->height(原高),

                  data(输出数据), line(输出的大小));
          15.音频重采样
    //音频重采样初始化空间
    SwrContext *actx = swr_alloc();
    //音频设置参数
    actx = swr_alloc_set_opts(actx, av_get_default_channel_layout(2), AV_SAMPLE_FMT_S16,ac->sample_rate,
av_get_default_channel_layout(ac->channels), ac->sample_fmt,
ac->sample_rate, 0, 0);
    //音频初始化
    ret = swr_init(actx);
    //音频重采样
    
    swr_convert(actx, out, frame->nb_samples,(const uint8_t **) (frame->data), frame->nb_samples);
 

    
 

   

  

  

   

  

      

   

      

       

      

       

          

原文地址:https://www.cnblogs.com/liunx1109/p/13287714.html