• ffmpeg的使用


    本文章记录ffmpeg 源码下载,编译,及使用。
    1、ffmpeg指令:
    1)视频添加文字水印

    ffmpeg -i manman1.mp4 -vf "drawtext=fontsize=100:fontfile=lazy.ttf:text='hello world':x=20:y=20:fontcolor=green:box=0:boxcolor=yellow" manman_watermark.mp4
    
    • 1

    其中,fontsize表示字体大小,fontfile表示字体格式,text中是文字水印显示的具体文字内容,x和y表示的是水印在视频中开始的位置,fontcolor表示水印中字体的颜色,box=1表示有边框,boxcolor表示边框的背景色。
    2)MP4->h264

     ffmpeg -i test.mp4 -codec copy -bsf: h264_mp4toannexb -f h264 test.h264
    
    • 1

    3)h264->mp4

     ffmpeg -i test.264 -vcodec copy -f mp4 test.mp4
    
    • 1

    4)添加时间水印
    FFmpeg不仅可以通过drawtext滤镜使用文字作为水印,文字部分也可以使用当前时间作为显示,只需修改text部分即可。修改后的命令如下:

    ffmpeg -re -i manman1.mp4 -vf "drawtext=fontsize=60:fontfile=lazy.ttf:text='%{localtime\:%Y\-%m\-%d %H-%M-%S}':fontcolor=green:box=1:boxcolor=yellow" manman_watemark.mp4
    
    • 1

    5)定时水印(没好使)
    有时候,我们并不希望视频中的水印一直显示,而是定期显示,FFmpeg也支持这样定期的显示水印,我们直接看一条中每3秒显示一次水印的命令如下:

    ffmpeg -re -i test.mp4 -vf "drawtext=fontsize=60:fontfile=lazy.ttf:text='{localtime\:%Y\-%m-%d %H-%M-%S}':fontcolor=green:box=1:boxcolor=yellow:enable=lt(mod(t\, 3)\, 1)" out.mp4
    
    • 1

    6)图片水印

    ffmpeg -i test.mp4 -vf "movie=logo.jpg[wm];[in][wm]overlay=30:10[out]" image_out.mp4
    
    • 1

    命令中-vf指定了使用滤镜,movie为这里使用的滤镜,overlay滤镜用来描述水印在视频的位置信息。
    在这里插入图片描述
    当图片的背景色为纯色时(如纯白色),可以使用movie与colorkey滤镜做配合做成半透明效果:

    ffmpeg -i test.mp4 -vf "movie=logo.jpg,colorkey=white:0.01:1.0 [wm]; [in] [wm] overlay=30:10 [out]" image1_out.mp4
    
    • 1

    7)水印缩放
    我们的水印图片的大小有的时候可能相对较大,在视频中显示水印的区域有时候却很小,这个时候我们就需要对水印的大小进行缩放,水印的缩放主要通过scale滤镜来实现,其参数就是缩放后的width和height,看一条添缩放后水印的命令:

    ffmpeg -i in.mp4 -vf "movie=logo.jpg,scale=50:10,colorkey=white:0.01:1.0 [wm]; [in] [wm] overlay=30:10 [out]" in_out_watermask_scale.mp4
    
    • 1

    8) 视频水印
    在一般的认知中,大家可能想不到,也不会使用另外的视频作为视频本身的水印,而实际上从技术的角度来讲,是可以做的到的,同样使用movie滤镜,只需把之前水印图片的文件名,替换成要作为水印的视频的文件名即可,是不是很神奇,哈哈。我们来看一个以视频作为水印的命令:

    ffmpeg -i in.mp4 -vf "movie=video_watermark.mp4,scale=100:100,colorkey=white:0.01:1.0 [wm]; [in] [wm] overlay=30:10 [out]" in_out_watermark_scale_video.mp4
    
    • 1

    在这里插入图片描述
    9) 多个水印
    其实把视频作为视频的水印不算什么,我们还可以为同一个视频添加多个水印,具体添加多少,按照FFmpeg强大的处理能力来讲,理论上没有上限,但是添加太多了,一是命令行看起来会天晕地旋,二是在视频本身添加太多的水印会有一种喧宾夺主的感觉,就很没必要了。我们来看看如何添加多个水印。

    ffmpeg -i in.mp4 -i logo.png -i logo.png -filter_complex "overlay=5:5, overlay=x=W-w:y=5" in_out_mul_watermark.mp4
    
    • 1

    10)动图水印
    读到这里,你可能也想到了,除了图片文字,视频,动图(常见gif)作为水印也是很广泛的需求。FFmpeg既然可以将视频作为水印添加,那么将动图作为水印当然也不在话下。先看一个添加gif图循环作为水印的命令。

    ffmpeg -i in.mp4 -ignore_loop 0 -i dongtu.gif -filter_complex "[1:v]scale=192:108[wm];[0:v][wm]overlay=0:H-h:shortest=1" in_out_dynamic_watermark.mp4
    
    • 1

    命令中-ignore_loop用来标识是否循环显示动图,动图同样使用-filter_complex滤镜来实现,使用scale缩放,使用overlay标明布局。

    11)透明水印
    对于水印而言,我们想把它加到视频里,但很多时候我们又不希望它影响到原始的视频,这样,水印的透明功能就显得比较不可或缺了。在添加多个水印的部分,我们试着将多个水印实现了透明的效果。一般而言水印图片是自带alpha通道的图片或者说是底色是纯色,如纯白,这些水印要实现透明效果通过colorkey的滤镜一般可以实现。但是往往很多水印图片并不具备这样的条件,对于这种情况,我们也不是束手无策,我们同样可以通过format,colorchannelmixer等滤镜来实现水印的透明效果。先给出一个实现水印透明的命令如下:

    ffmpeg -i in.mp4 -vf "movie=logo.jpg,format=yuva444p,colorchannelmixer=aa=0.9[wm];[in][wm]overlay=10:30[out]" alpha_out.mp4
    
    • 1

    滤镜format指定了像素的格式,例子中为yuva444p,a代表的是alpha通道,通过滤镜,首先将原始图片转换为带有透明通道的图片,然后使用colorchannelmixer滤镜将水印与原始视频混合,aa表示水印的透明程度,值为1表示不透明,0表示全透明。
    2、ffplay指令
    1)播放摄像头原始数据

    ffplay -f rawvideo -video_size 640x480  -pixel_format yuv420p ./test.yuv420p
    
    • 1

    一、FFMPEG 源码下载解压
    源码官网地址:http://ffmpeg.org/download.html#releases
    在这里插入图片描述
    下载最新版本ffmpeg6.0。
    在这里插入图片描述
    使用命令tar xvJf ffmpeg-6.0.tar.xz 解压。
    在这里插入图片描述
    二、了解FFMPEG源码
    (一)configure编译脚本及帮助命令

    ./configure --help -->ffmpeg_help.txt
    
    • 1

    1、Shell脚本:由第一行Shell解释器声明 #!/bin/sh 代码,可以看出,configure是Shell脚本。
    在这里插入图片描述
    2、configure 脚本作用:该脚本用于生成make工具的构建脚本Makefile文件。
    3、configure脚本执行:该脚本需要进行配置才能执行,如果直接执行,会报错。
    4、configure帮助命令:
    1)脚本复杂:c/c++开源库都会提供一个configure脚本,该脚本的配置非常复杂,但一般都提供一个帮助选项;
    2)帮助信息:执行./configure --help 既可查看帮助信息。建议先将帮助信息熟悉一遍后再进行编译。

    (二)配置configure脚本
    1、FFMPEG编译流程
    1)配置:使用configure脚本进行相关参数的配置。
    2)编译:配置完毕后,直接执行make命令,开始进行编译。

    2、配置的内容
    1)输出配置:配置 生成的相关文件输出路径;
    2)函数库配置:配置静态库,动态库。函数库优化等相关参数。
    3)命令行程序配置:配置是否生成命令行程序,FFMPEG 自带3个命令行程序。
    4)编译组件配置:FFMPEG有22个可选的独立组件配置,可以选择性编译或不编译某些组件。
    5)编码解码配置:配置FFMPEG编解码功能。
    6)交叉编译配置(重点):配置交叉编译工具链、头文件、库文件查找路径参数,GCC编译器参数,CPU架构等参数。

    (三)输出目录配置
    1 、生成文件的输出目录 : FFMPEG 编译后需要生成一系列的函数库 , 及头文件等 ; 需要为这些生成的文件指定输出目录 。
    2、指定生成的文件输出位置 。
    1)定义变量 : 使用 PREFIX=./android/arme64-v8a命令 , 定义输出目录根目录变量;
    2) 路径配置 : 使用 ./configure --prefix=PREFIX 命令 , 指定输出文件的根目录为 ./android/arme64-v8a ;

    # 将输出目录存储到 PREFIX 变量中
    PREFIX=./android/arme64-v8a
    
    # 执行 configure 脚本配置输出文件的根目录
    ./configure --prefix=$PREFIX
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3、自动生成其它目录 : 指定了 --prefix 选项 , 那么其它生成 bin 可执行文件目录 , lib 函数库目录 等类型的文件输出目录会在 --prefix 配置的目录基础上生成 。
    1) 根目录 : 指定了 --prefix 目录为 ./android/arme64-v8a ;
    2) 可执行文件目录 : 自动生成的可执行文件输出目录为 PREFIX/bin , 即 ./android/arme64-v8a/bin ;
    3) 函数库目录 : 自动生成的函数库数据目录为 PREFIX/lib , 即 ./android/arme64-v8a/lib ;
    其它的标准选项配置 ( Standard options ) 请仔细阅读下面的 configure 帮助文档内容 ;
    在这里插入图片描述

    (四)函数库配置
    1、 函数库配置 : FFMPEG 编译时 , 可以选择编译静态库或动态库 , 及设置编译函数库的行为 ;
    2、 默认编译的函数库 : FFMPEG 默认编译静态库 , 此处也推荐在 Android 中使用 FFMPEG 静态库开发音视频功能 , 保持默认状态即可 ;
    3、优化函数库 :
    1)设置后效果 : FFMPEG 编译时可以选择优化函数库大小 , 让编译出来的函数库尽可能小 , 但相应的编译速度会降低很多 ;
    2)设置的要性 : 由于是在 Android 中进行开发 , 为了使打包后的 APK 文件尽可能小 , 这里我们需要开启该选项 ;
    3)设置命令 : 调用 ./configure --enable-small 命令 , 启用优化函数库大小的功能;

    # 启用函数库大小优化
    ./configure --enable-small
    
    • 1
    • 2

    其它的配置选项 ( Configuration ) 请仔细阅读下面的 configure 帮助文档内容 ;
    在这里插入图片描述
    (五)程序配置选项
    1)FFMPEG 命令行程序 : FFMPEG 提供了一些可执行的命令行程序 , 如 ffmpeg.exe , ffplay.exe , ffprobe.exe 等程序 ;
    2) 使用情况 : 在 Android 开发中只需要 FFMPEG 的函数库 , 不需要这些程序 , 建议关闭命令行程序编译选项 ;
    3)配置命令 : 调用 ./configure --disable-programs 命令 , 关闭编译命令行程序的功能 。

    # 关闭编译命令行程序
    ./configure --disable-programs
    
    • 1
    • 2

    其它的配置选项 ( Configuration ) 请仔细阅读下面的 configure 帮助文档内容
    在这里插入图片描述
    (六)组件配置选项
    1、组件配置选项
    默认状态 : FFMPEG 组件选项 , 默认都是打开的 , 如果需要关闭某一个需要单独配置

    2、FFMPEG 常用组件
    1)avdevice 组件 : 操作摄像头等视频设备 , Android 中是不支持该操作 , 需要手动关闭;
    2)avcodec 组件 : 声音 / 图像编解码组件;
    3)avformat 组件 : 音视频封装格式生成或解析;
    4)swresample 组件 : 音频重采样 , 修改音频参数;
    5)swscale 组件 : 视频场景比例缩放 , 色彩映射转换;
    6)postproc 组件 : 后期效果处理 , 这里不需要 , 需要手动关闭;
    7) avfilter 组件 : 过滤器 , 添加字幕水印。

    3、关闭 avdevice 配置命令 : 调用 ./configure --disable-avdevice 命令 , 关闭 avdevice 模块编译。

    # 关闭编译命令行程序
    ./configure --disable-avdevice
    
    • 1
    • 2

    其它的组件配置选项 ( Configuration ) 请仔细阅读下面的 configure 帮助文档内容 。
    在这里插入图片描述
    (七)编码配置
    1、提供的编码配置
    1)编码器 : 关闭指定编码器 , 关闭所有编码器 , 打开指定编码器;
    在这里插入图片描述
    2)解码器 : 关闭指定解码器 , 关闭所有解码器 , 打开指定解码器;
    在这里插入图片描述
    2、 关闭编码配置命令 : 调用 ./configure --disable-encoders 命令 , 关闭编码器模块编译

    # 关闭编译编码器
    ./configure --disable-encoders
    
    • 1
    • 2

    3、 关闭混合封装配置命令 : 调用 ./configure --disable-muxers 命令 , 关闭混合封装模块编译

    # 关闭混合封装
    ./configure --disable-muxers
    
    • 1
    • 2

    4、关闭视频滤镜配置命令 : 调用 ./configure --disable-filters 命令 , 关闭视频滤镜模块编译

    # 关闭视频滤镜
    ./configure --disable-filters
    
    • 1
    • 2

    其它的单个组件配置选项 ( Configuration ) 请仔细阅读下面的 configure 帮助文档内容
    在这里插入图片描述
    三、交叉编译
    (一) ffmpeg4.1.11 + ndk17 编译arm32平台库
    参考文章:参考博客https://blog.csdn.net/shulianghan/article/details/104351312
    1、官网下载ffmpeg4.1.11版本,并解压。省略
    在这里插入图片描述
    2、官网下载ndk17版本。省略。
    具体方法参考文章“ndk开发-交叉编译”。

    3、执行./configure

    1. 进入ffmpeg-4.1.11文件夹;
    cd ffmpeg-4.1.11
    
    • 1

    2)修改权限到root权限;

    sudo su root
    
    • 1

    3)执行命令;

    ./configure
    
    • 1

    执行后,我这里会报错,如下。
    在这里插入图片描述
    解决方案:安装asm.
    下载yasm-1.3.0版本并解压。下载地址http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz

    在这里插入图片描述
    http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
    tar -zxvf yasm-1.3.0.tar.gz
    在这里插入图片描述
    进入yasm-1.3.0文件夹,执行./configure
    在这里插入图片描述
    执行make指令
    在这里插入图片描述
    安装成功。
    再回到ffmpeg-4.1.11文件夹,执行./configure指令,不会报错。

    4)编写编译脚本
    将参考文章https://blog.csdn.net/shulianghan/article/details/104351312中的编译脚本拷贝过来。修改。
    a 新建“build_ffmpeg.sh”文件夹;
    b 拷贝编译脚本,并修改ndk根目录。

    #!/bin/bash
    
    # NDK 根目录(按照自己的路径修改)
    NDK_ROOT=/home/vagrant/software/ndk/android-ndk-r17c
    
    # TOOLCHAIN 变量指向 gcc g++ 等交叉编译工具所在的目录
    TOOLCHAIN=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
    
    # gcc 编译器参数
    FLAGS="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -isystem $NDK_ROOT/sources/android/support/include -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fPIC"
    
    # 编译结果输出路径
    PREFIX=./android/armeabi-v7a
    
    # 执行 configure 脚本生成 Makefile 构建脚本
    ./configure \
    --prefix=$PREFIX \
    --enable-small \
    --disable-programs \
    --disable-avdevice \
    --disable-encoders \
    --disable-muxers \
    --disable-filters \
    --enable-cross-compile \
    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
    --sysroot=$NDK_ROOT/platforms/android-21/arch-arm \
    --extra-cflags="$FLAGS" \
    --arch=arm \
    --target-os=android 
    
    # 清除之前的编译内容
    make clean
    
    # 开启新的 FFMPEG 编译
    make install
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    c 在ffmpeg文件夹新建android/armeabi-v7a文件夹。
    d chmod 777 build_ffmpeg.sh 添加权限
    e ./build_ffmpeg.sh 执行脚本
    生成一下文件,说明编译成功。可以使用file xxx查看生成的库文件是否为arm32平台。
    在这里插入图片描述
    注意:很奇怪,使用同样的linux环境,ndk和ffmpeg第一次用该脚本编译,报错。今天重新做一遍又不会报错。把报错及解决方法记录一下。
    在这里插入图片描述
    修改方法:去掉脚本中“-D__ANDROID_API__=21 -g -DANDROID”,完成脚本如下,可以编译so 动态库和静态库。

    #!/bin/bash
    
    # NDK 根目录
    NDK_ROOT=/home/vagrant/software/ndk/android-ndk-r17c
    
    # TOOLCHAIN 变量指向 gcc g++ 等交叉编译工具所在的目录
    TOOLCHAIN=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
    
    # gcc 编译器参数
    FLAGS="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -isystem $NDK_ROOT/sources/android/support/include -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fPIC"
    
    #FLAGS="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -isystem $NDK_ROOT/sources/android/support/include -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -#funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fPIC"
    
    # 编译结果输出路径
    PREFIX=./android/armeabi-v7a
    
    # 执行 configure 脚本生成 Makefile 构建脚本
    ./configure \
    --prefix=$PREFIX \
    --enable-small \
    --disable-programs \
    --enable-static \
    --enable-shared \
    --disable-avdevice \
    --disable-encoders \
    --disable-muxers \
    --disable-filters \
    --enable-cross-compile \
    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
    --sysroot=$NDK_ROOT/platforms/android-21/arch-arm \
    --extra-cflags="$FLAGS" \
    --arch=arm \
    --target-os=android 
    
    # 清除之前的编译内容
    make clean
    
    # 开启新的 FFMPEG 编译
    make install
    
    #--extra-cflags="$FLAGS" \
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
  • 相关阅读:
    [C#][转载]furion框架地址和教程地址
    Java中使用定时器监听数据变化,当满足某个条件时(例如没有数据更新)自动执行某项任务
    Jeecg Online代码生成器--一对多代码生成
    ubantu搭建cdh6(自己留的草稿版本)
    艾瑞泽5汽车电子控制单元CAN通信数据读写车辆网络系统交互接口
    精简5800三维程序
    Apache网页优化
    UV 裂解的生物素-PEG2-叠氮|CAS:1192802-98-4生物素接头
    V2rayn免费链接上 推会被识别成恶意ip封号吗?
    算法笔记之蓝桥杯&pat系统备考(2)
  • 原文地址:https://blog.csdn.net/zhuowalun8427/article/details/132601483