zoukankan      html  css  js  c++  java
  • FFmpeg

     FFmpeg的名称来自MPEG视频编码标准,前面的“FF”代表“Fast Forward”,FFmpeg是一套可以用来音视频采集、音视频格式转换,编码解码,视频截图,加水印等的开源计算机程序。可以轻易地实现多种视频格式之间的相互转换。

    FFmpeg一共包含四个主要程序:

    • ffmpeg:是一个命令行工具,用来对视音频文件转换格式,也支持对电视卡实时编码;
     ffmpeg -i input.flv -c:v libx264 -c:a libfaac -b:v 800k -b:a 100k -r 25 -ar 48000 -s 1280x720 -f flv out.flv
    • ffsever:是一个HTTP多媒体实时广播流服务器,支持时光平移
    • ffplay:是一个简单的播放器,使用ffmpeg 库解析和解码,通过SDL显示;
    • ffprobe:探测分析视音频文件
    ffprobe -i input -print_format json -show_format -show_streams -show_frames

    这里我们主要说一说ffmpeg

    ffmpeg的使用方式: 

    ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

    常用参数说明:
    主要参数:

      -i 设定输入流

      -f 设定输出格式,指定输出格式为flv,这里的flv可以替换为mp4,ts,hls等,后面接着输出文件名

      -ss 指定截取的开始时间

           -t 指定截取的结束时间,可以用两种方式指定时间,一种是用时分秒指定、中间用冒号分离HH:MM:SS,另一种是直接用秒数指定

           -y 即如果文件存在,直接覆盖写

           -n 永远不会覆盖输出文件

    视频参数:

      -b:v 指定视频码率,默认为200Kbit/s  码率:是一个确定整体视频/音频质量的参数,秒为单位处理的字节数  。 

      -r 设定帧速率,默认为25      帧率:帧率也叫帧频率,帧率是视频文件中每一秒的帧数,肉眼想看到连续移动图像至少需要15帧。  帧:代表一幅静止的图像

      -s  改变视频的分辨率 ,设定画面的宽与高   

      -aspect 设定画面的比例

      -vn 不处理视频

      -vcodec 设定视频编解码器,未设定时则使用与输入流相同的编解码器

           -c:v 指定视频编码格式

           -c:v copy 指定音频不转码 

           -vframes number设置要输出的视频帧数

           -vf  filter_graph 设置视频过滤器

    音频参数:

      -ar 设定采样率

      -ac 设定声音的Channel数

      -acodec 设定声音编解码器,未设定时则使用与输入流相同的编解码器

      -an 不处理音频

           -b:a 指定音频码率 

           -c:a 指定音频编码格式      

           -c:a copy 指定音频不转码     

           -frames number设置要输出的音频帧数

           -af filter_graph 设置音频过滤器

    视频格式转换

    (其实格式转换说法不太准确,但大家都这么叫,准确的说,应该是视频容器转换) 比如一个avi文件,想转为mp4,或者一个mp4想转为ts。 ffmpeg -i input.avi output.mp4

    ffmpeg -i input.mp4 output.ts 

     

    视频抽帧

    1.按平均帧率抽帧

    ffmpeg -i input.mp4 -vf fps=10 -q:v 2 -f out_%5d.jpg

    2.按指定帧号抽帧

    可以使用opencv- videocapture 进行抽帧

        def draw_assignframe(self, filename, dst_path, dst_img_name):
            cap = cv2.VideoCapture(filename)
            time = cap.get(7)
            for i in range(0, int(time)):
                cap.set(1, int(i))
                rval, frame = cap.read()  # cap.read()按帧读取视频,ret,frame是获cap.read()方法的两个返回值。
                # 其中ret是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,它的返回值就为False。frame就是每一帧的图像,是个三维矩阵。
                if rval and str(i) in self.frame_id_list:  # self.frame_id_list中存放需要提取的帧号  
                    cv2.imwrite(os.path.join(dst_path, dst_img_name + '_' + str(i + 1).zfill(5) + self.dst_suffix),
                                frame)  # 图片的路径
            cap.release()

    3. 抽取关键帧

    ffmpeg -i input.mp4 -vf select='eq(pict_type\,I)' -vsync 2  -f out_%5d.jpg     #-vsync 2  https://www.jianshu.com/p/0b772b8d4f73

    视频剪切

    基本剪切方法

    ffmpeg -i test.mp4 -ss 10 -t 15 -codec copy cut.mp4

    参数分析:

    -i : source
    -ss:start time
    -t :duration
    -c :video,audio codec

    时间格式:

    HOURS:MM:SS.MICROSECONDS

    可以设置输出视频的编码格式

    -vcodec xxx
    -acodec xxx

    把-ss, -t参数放在-i参数之后,是对输出文件执行的seek操作
    输入文件会逐帧解码,直到-ss设置的时间点为止,这么操作会很慢,虽然时间点是准确的,但是很容易出现黑屏问题。

    3. 参数优化
    (1)将-ss, -t 参数放在-i参数之前

    ffmpeg -ss 10 -t 15 -i test.mp4 -codec copy cut.mp4

    对输入文件执行seek操作,会seek到-ss设置的时间点前面的关键帧上。
    时间不精确,但是不会出现黑屏

    (2)accurate_seek
    剪切时间更加精确

    ffmpeg -ss 10 -t 15 -accurate_seek -i test.mp4 -codec copy cut.mp4

    PS:accurate_seek必须放在-i参数之前

    (3)avoid_negative_ts
    如果编码格式采用的copy 最好加上 -avoid_negative_ts 1参数

    ffmpeg -ss 10 -t 15 -accurate_seek -i test.mp4 -codec copy -avoid_negative_ts 1 cut.mp4

    码率控制

    码率控制对于在线视频比较重要。因为在线视频需要考虑其能提供的带宽。

    那么,什么是码率?很简单:
    bitrate = file size / duration
    比如一个文件20.8M,时长1分钟,那么,码率就是:
    biterate = 20.8M bit/60s = 20.8*1024*1024*8 bit/60s= 2831Kbps
    一般音频的码率只有固定几种,比如是128Kbps,
    那么,video的就是
    video biterate = 2831Kbps -128Kbps = 2703Kbps。

    说完背景了。好了,来说ffmpeg如何控制码率。
    ffmpg控制码率有3种选择,-minrate -b:v -maxrate
    -b:v主要是控制平均码率。
    比如一个视频源的码率太高了,有10Mbps,文件太大,想把文件弄小一点,但是又不破坏分辨率。
    ffmpeg -i input.mp4 -b:v 2000k output.mp4
    上面把码率从原码率转成2Mbps码率,这样其实也间接让文件变小了。目测接近一半。
    不过,ffmpeg官方wiki比较建议,设置b:v时,同时加上 -bufsize
    -bufsize 用于设置码率控制缓冲器的大小,设置的好处是,让整体的码率更趋近于希望的值,减少波动。(简单来说,比如1 2的平均值是1.5, 1.49 1.51 也是1.5, 当然是第二种比较好)
    ffmpeg -i input.mp4 -b:v 2000k -bufsize 2000k output.mp4

    -minrate -maxrate就简单了,在线视频有时候,希望码率波动,不要超过一个阈值,可以设置maxrate。
    ffmpeg -i input.mp4 -b:v 2000k -bufsize 2000k -maxrate 2500k output.mp4

    只提取视频ES数据

    ffmpeg –i input.mp4 –vcodec copy –an –f m4v output.h264

    将输入的1920x1080缩小到960x540输出

    ffmpeg -i input.mp4 -vf scale=960:540 output.mp4 

    //ps: 如果540不写,写成-1,即scale=960:-1, 那也是可以的,ffmpeg会通知缩放滤镜在输出时保持原始的宽高比。

  • 相关阅读:
    mount: error mounting /dev/root on /sysroot as ext3: Invalid argument
    redhat5.8 alt+ctrl+f1 黑屏
    Linux U盘 启动盘
    Debian For ARM Webmin Server
    Debian For ARM mysql-server install information
    fakeroot: preload library `libfakeroot.so' not found, aborting.
    FAT-fs (mmcblk0p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
    JavaScript获取table中某一列的值的方法
    SpringMvc(注解)上传文件的简单例子
    SpringMVC单文件上传、多文件上传、文件列表显示、文件下载
  • 原文地址:https://www.cnblogs.com/liusouthern/p/9987848.html
Copyright © 2011-2022 走看看