ffmpeg入门篇-滤镜的基本使用

这篇具有很好参考价值的文章主要介绍了ffmpeg入门篇-滤镜的基本使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

转发自白狼栈:查看原文

滤镜

什么是滤镜?百度百科介绍说“滤镜主要是用来实现图像的各种特殊效果......”。

我们最早在ffmpeg是如何转码的一文中了解过滤镜,来回顾下当时的转码流程图。

ffmpeg入门篇-滤镜的基本使用,ffmpeg

从图中可以看到滤镜前后画的是虚线,表示可有可无,在术语中,滤镜指的是在编码之前针对解码器解码出来的原始数据(即音视频帧)进行处理的动作,我们还可以称它为过滤器。

ffmpeg内置了大概近400种滤镜,我们可以用 ffmpeg -filters 命令查看所有的滤镜,也可以用命令 ffmpeg -h filter=xxx 或者查看官方文档了解每一种滤镜。

实际在大部分音视频的处理过程中都离不开滤镜,所以你应该能明白其重要性。

多个滤镜可以结合在一起使用形成滤镜链或者滤镜图,在每一个滤镜中,不仅可以对输入源进行处理,A滤镜处理好的结果还可以作为B滤镜的输入参数,通过B滤镜继续处理。

针对滤镜的处理,ffmpeg提供了两种处理方式,简单滤镜和复杂滤镜。

简单滤镜

简单滤镜指的是只有一个输入和输出,而且保证输入和输出的流类型相同。

比如我们在上篇文章流的操作(二)如何选择流?末尾提到的把原视频 r3.mp4 等比例缩放一倍

ffmpeg -i r3.mp4 -vf scale=272:480 -y filter.mp4

-vf 是 -filter:v 的简写,类似的我们还可以使用 -filter:a 或者 -af 针对音频流做处理。

-filter的语法规则:-filter[:stream_specifier] filtergraph ( output,per-stream)
stream_specifier流的类型我们一般用a表示音频,v表示视频,filtergraph表示具体的滤镜,这里用的是 scale滤镜。

scale滤镜用于调整视频的大小,比如等比例缩放、等比例放大,不做等比例操作输出就变形了,变形结果我们一般不考虑。

因为我们知道原视频 r1ori.mp4 的分辨率是 544x960,所以等比例缩放一倍,上面的命令直接指定了 272x480,scale滤镜自带很多参数,我们介绍几个常用的。

in_w in_h 或者 iw ih 表示输入视频的宽高
out_w out_h 或者 ow oh 表示输出视频的宽高

当然不一定是视频,输入输出也可以是图片。

所以原视频缩放一倍我们还可以这样写:

ffmpeg -i r3.mp4 -vf scale=iw/2:ih/2 -y filter.mp4

问题一:如果我们要把原视频的宽度调整为300且保持原分辨率,怎么办?

列一个方程 544/960 = 300/x ,x=300x960/540,很麻烦,结果还不一定能整除,为此我们可以直接指定高度等于-1,它会自动做等比例处理。

ffmpeg -i r1ori.mp4 -vf scale=300:-1 -y filter.mp4

结果发现转码失败了,提示

[libx264 @ 0x7ff509053a00] height not divisible by 2 (300x529) 
Error initializing output stream 0:0 -- 
Error while opening encoder for output stream #0:0 - 
maybe incorrect parameters such as bit_rate, rate, width or height [aac @ 0x7ff50904e200] 
Qavg: 28010.410 [aac @ 0x7ff50904e200] 2 frames left in the queue on closing

提示我们 height not divisible by 2 (300x529)即高度529不能被2整除。这是因为一些编解码器要求很多视频的宽高必须是n的倍数(这里n是2),所以我们写脚本处理视频或者图片宽高的时候,切记不要使用-1,正确的用法是使用-2。

ffmpeg -i r1ori.mp4 -vf scale=300:-2 -y filter.mp4 输出结果视频的分辨率是 300 × 530

问题二:老板为了刁难你,提出了一个新的要求:“我想要所有输出视频的分辨率是 300x500且不能变形”,怎么办?

我们知道3:5的宽高比是很少见的,现在常见的分辨率是16:9、4:3,也就是说原视频我们必须要经过一番处理才可以满足老板的变态需求。

针对原视频 r1ori.mp4,如果保证宽度是300,等比例缩放后高度是530,强制设置高度为500就会变形,也就是说我们只能让高度等于500,尽量缩小宽度试试。

ffmpeg -i r1ori.mp4 -vf scale=-2:500 -y filter.mp4 输出的结果视频的分辨率是284x500

ffmpeg入门篇-滤镜的基本使用,ffmpeg

如上图,蓝色框表示视频的真实宽高,红色框表示目标宽高,有些像html中的css一样,可以给空出来的部分填充颜色即内边距不就可以了?

【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~

ffmpeg入门篇-滤镜的基本使用,ffmpeg

查阅了文档我们发现pad滤镜可以解决我们的问题。

pad滤镜的语法规则:-pad=width[:height[:x[:y[:color]]]]
1、ffmpeg -i r1ori.mp4 -vf "scale=-2:500,pad=300:500:(300-iw)/2:0" -y filter2.mp4 
2、ffmpeg -i r1ori.mp4 -vf scale=-2:500,pad=300:500:-1:0 -y filter.mp4 
3、ffmpeg -i r1ori.mp4 -vf scale=-2:500,pad=300:500:-1:0:black -y filter.mp4 
4、ffmpeg -i r1ori.mp4 -vf "scale=-2:500,pad=300:ih:(ow-iw)/2:0:green" -y filter.mp4

上面提供4中写法,我们以方法4做个简单介绍。

scale=-2:500,指原视频按照等比例缩放,高度等于500,就是上面大家看到的284x500。

pad=300:ih:(ow-iw)/2:0:green,300:ih即300:500就是红色框的宽高(ow-iw)/2,指的是红色框和蓝色框差值的一半,即两边各需要填充的范围;最后一个参数表示需要填充的颜色,默认是黑色 black,为了调试方便我们把颜色设为green。

现在我们保证了当前视频一定会按照300x500的比例输出且不会变形,但是请注意老板说的“所有输出视频”,也就是说输入视频的分辨率可能是200x300、544x960、500x400、200x800等等各种比例都要保证按照300x500输出,很显然,上面的写法不完全通用,怎么办?

现在我们已知原输入视频的宽高和想要的宽高,针对这种情况,我们制定一套处理规则即可解决:

  1. 宽高都偏小,不拉伸,不缩放
  2. 宽高都偏大,等比例缩小,以高度为准
  3. 宽超出范围,等比例缩小,以宽为准
  4. 高超出范围,等比例缩小,以高为准

在实际的开发过程中,我们要跟代码打交道,平时在命令行中的实现都是练习,所以基于该规则,我们有了下面一段代码

<?php
declare(strict_types=1);

class CalculatorService
{
    /**
     * 用户视频分辨率转换
     * 规则:
     *  宽高都偏小,不拉伸,不缩放
     *  宽高都偏大,等比例缩小,以高度为准
     *  宽超出范围,等比例缩小,以宽为准
     *  高超出范围,等比例缩小,以高为准
     * @param int $inputWidth 输入视频的宽度
     * @param int $inputHeight 输入视频的高度
     * @param int $outWidth 输出视频的宽高
     * @param int $outHeight 输出视频的高度
     * @return string scale
     */
    public function getSize(int $inputWidth, int $inputHeight, int $outWidth, int $outHeight): string
    {
        $scale = "";
        if ($inputWidth <= $outWidth && $inputHeight <= $outHeight) {
            $scale = "scale={$inputWidth}:{$inputHeight},pad={$outWidth}:{$outHeight}:-1:-1:green";
        } elseif (($inputWidth > $outWidth && $inputHeight > $outHeight)
            || ($inputHeight > $outHeight)
        ) {
            $scale = "scale=-2:{$outHeight},pad={$outWidth}:{$outHeight}:-1:0:green";
        } elseif ($inputWidth > $outWidth) {
            $scale = "scale={$outWidth}:-2,pad={$outWidth}:{$outHeight}:0:-1:green";
        }

        return $scale;
    }
}

$calculatorService = new CalculatorService();
var_dump($calculatorService->getSize(200, 300, 300, 500));
var_dump($calculatorService->getSize(544, 960, 300, 500));
var_dump($calculatorService->getSize(500, 400, 300, 500));
var_dump($calculatorService->getSize(200, 600, 300, 500));

// 结果
string(37) "scale=200:300,pad=300:500:-1:-1:green"
string(35) "scale=-2:500,pad=300:500:-1:0:green"
string(35) "scale=300:-2,pad=300:500:0:-1:green"
string(35) "scale=-2:500,pad=300:500:-1:0:green"

为了方便理解,大家可以参考下面的图一一对应。

ffmpeg入门篇-滤镜的基本使用,ffmpeg

复杂滤镜

相对于简单滤镜,复杂滤镜是可以处理任意数量输入和输出效果的滤镜图,它几乎无所不能。

复杂滤镜用命令 -filter_complex 表示,它还有一个别名 -lavfi。

上篇文章介绍到流和滤镜结合是一种最重要、最常用的方法。依然是将输入视频 r3.mp4 等比例缩放一倍,我们以手动选择流的方式为例。

ffmpeg -i r3.mp4 -filter_complex "[0]scale=272:480[out]" -map 0:a -map "[out]" -y filter.mp4

简单分析如下:

  1. 命令 "[0]scale=272:480[out]" 中的[0]表示第一个输入的视频,因为要对视频做处理,所以也可以用[0:v]表示,如果要对音频单独处理,就需要用 [0:a] 了;
  2. [0] 结合scale滤镜,表示的就是把第一个输入的视频作为scale滤镜的参数输入;
  3. [out] 中括号是必须要的,out是自定义的一个别名,结合scale滤镜,表示的是把scale滤镜输出的结果命名为[out],但并非是最终输出的结果,只能作为中间过程输出的一个结果;
  4. -map "[out]" 就是直接选择[out] 流作为输出

我们说过,一个滤镜的输出作为另一个滤镜的输入,这样就极大的避免了写多条命令反复编解码操作,我们的原则只有一个,能用一条命令处理的绝不用两条命令。

有损编解码器反复编解码操作会降低原视频质量。

比如现在要把原视频 r1ori.mp4 的中间部分裁剪出来,但仍保持原视频的分辨率544x960,如何做呢?

ffmpeg -i r1ori.mp4 -filter_complex "nullsrc=s=544x960[background]; \
crop=iw:(ih/2 - 110):0:250[middle]; \
[background][middle]overlay=shortest=1:x=(main_w-overlay_w)/2:y=(main_h-overlay_h)/2[out]" \
-map "[out]" 
-map 0:a 
-movflags +faststart 
-y fc.mp4

这个命令就显得稍微长了一些,在这条命令中使用了nullsrc、crop、overlay三种常见滤镜。

nullsrc滤镜用于创建一个空的视频,简单的说就是一个空的画布或者说是绿布,因为默认创建的颜色是绿色的。s用于指定画布的大小,默认是320x240,这里表示我们创建一个544x960的画布,并命名为background;

关于nullsrc还有很多种不同的用户,比如使用nullsrc和CIQRCodeGenerator创建一个“白狼栈”首页的二维码

ffmpeg -f lavfi -i nullsrc=s=200x200,coreimage=filter=CIQRCodeGenerator@inputMessage=\ 
http\\\\\://manks.top/@inputCorrectionLevel=H -frames:v 1 manks.png

crop滤镜用于裁剪视频,也就是说视频的任意区域任意大小,我们都可以裁剪出来。crop=iw:(ih/2 - 110):0:250[middle]; 这里我们裁剪原视频的中间部分并命名为middle;

overlay滤镜表示两个视频相互叠加,shortest官网是这么介绍的:“If set to 1, force the output to terminate when the shortest input terminates. Default value is 0.”,因为我们使用nullsrc创建了一个没有时间轴的画布,所以这里需要以middle的视频时间为最终时间,故设置为1。main_w和main_h表示主视频的宽高,overlay_w和overlay_h表示叠加视频的宽高。如果要把A视频叠加到B视频上,则main_w和main_h表示B视频的宽高,overlay_w和overlay_h表示A视频的宽高。合起来便是把middle叠加到background之上且置于background的中间(相当于有个叠加层的概念);

最后一个参数是-movflags,它跟mp4的元数据有关,设为faststart表示会将moov移动到mdat的前面,在线播放的时候会稍微快一些。

作业:我们在音视频合成案例一文中介绍了两个案例,快去试试你能不能一条命令解决?

关于滤镜的基本介绍我们就介绍到这里,有任何问题可以下方留言。

原文链接 ffmpeg入门篇-滤镜的基本使用 - 知乎文章来源地址https://www.toymoban.com/news/detail-804016.html

到了这里,关于ffmpeg入门篇-滤镜的基本使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FFmpeg进阶:视频滤镜大全

    在做视频特效的时候,很多特效其实不用自己写,FFmpeg的视频滤镜里面提供了很丰富的滤镜特效。这里翻译了一下FFmpeg官方文档的所有视频滤镜的介绍,供大家参考。由于很多地方概念比较生疏,翻译的可能不恰当,欢迎反馈修改意见。 滤镜名称 滤镜介绍 addroi 在视频帧中标

    2024年02月03日
    浏览(28)
  • ffmpeg的滤镜

    FFmpeg 是一款开源的跨平台音视频处理工具,它提供了众多功能强大的滤镜用于视频/音频的加工处理。其中,滤镜(Filter)是 FFmpeg 中一个十分重要且常用的组件,它们可以实现对视频和音频的各种操作和变化,如转码、编解码、剪裁、裁剪、缩放、旋转、倒置、加水印、去除噪

    2023年04月18日
    浏览(27)
  • FFmpeg进阶: 音频滤镜大全

    在做音频处理模块的时候,为了对声音进行优化处理,我很多时候会使用各种算法对音频进行变换,效果包括变音变调、声音降噪等等。其实FFmpeg库里的滤镜模块包含了很多有用的音频滤镜算法,这对于提升开发效率避免重复造轮子是很有帮助的。这里翻译了一下FFmpeg官方文

    2024年02月02日
    浏览(27)
  • FFmpeg- 常用的滤镜命令

    下面来熟悉一下常用的对视频操作的几个命令。这次需要完成的命令也包括在其中。 视频的画面大小的剪切(crop filter) 将输入的视频的帧,以左上角为坐标的原点,剪切成x,y坐标开始的指定大小。 语法: 简单的解释: x,y :是偏移量。 ow,oh :是输出的宽和高。 iw ih :还可以使用

    2023年04月16日
    浏览(35)
  • 关于FFMPEG中的filter滤镜的简单介绍

    滤镜的作用主要是对原始的音视频数据进行处理以实现各种各样的效果。比如叠加水印,翻转缩放视频等。 下图表示的正常转码流程,滤镜在解码和编码中间,虚线表示可有可无。 使用命令查看ffmpeg支持的滤镜 ffmpeg -filters  查看某个滤镜的详细参数 ffmpeg -h filter=pad  上图显

    2024年02月14日
    浏览(28)
  • FFmpeg滤镜: 调整视频的亮度-对比度-饱和度

    亮度是指图片的明暗程度,对比度是指图片明暗的差异,饱和度则是指图片颜色的饱满程度。在计算机中每个图片上的像素点都由三个字节来进行表示,分别代表着像素的RGB数据。 图片上每个像素的每种颜色都可以有从0到255的变化,数值越高,颜色的亮度越大,因此当改变

    2024年02月13日
    浏览(43)
  • linux 入门(七)-ffmpeg使用

    ubuntu下安装ffmpeg: 转码视频格式只需要执行下面的命令即可: 输出如下: 指定尺寸 原视频1280x720, 大小3.3m, 修改后720x360 ,大小1.5M. 修改帧率 原视频帧率60, 大小3.3M. 修改帧率为20后, 大小为2.9M 限定视频大小 该命令会限制输出文件的大小为1MB. 但是-fs参数并不会保证输出的文件在

    2024年03月09日
    浏览(29)
  • Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目

    最近在学习android NDK开发相关内容,借ffmpeg练练手。ffmpeg是做音视频方面功能的基础,后面会随着个人的学习更新一系列ffmpeg博客,防止自己遗忘。 这个系列博客主要目的是基于ffmpeg通过NDK开发的方式完成一个基本的视频播放器。 本篇博客主要实现了 ffmpeg编译 以及 引入 a

    2023年04月08日
    浏览(33)
  • Compose使用OpenGL+CameraX快速实现相机“拍视频实时滤镜“、”拍照+滤镜“

    一、前言 短视频热潮还没有褪去,写这篇文章主要是帮助大部分人,能快速上手实现类似效果,实际上是: CameraX拿相机数据,OpenGL给CameraX提供一个Surface,数据放到OpenGL渲染的线程上去做图像相关操作 OpenGL滤镜来自 aserbao_AndroidCamera 视频录制核心代码参考改造自 Google 的 g

    2023年04月17日
    浏览(34)
  • ps2021神经ai滤镜无法使用,ps2021没法用神经元滤镜

    网上买正版,更新下就好了,盗版的都会有各种这样的问题。ps2021神经AI滤镜是需简要上传云端,由Adobe官方服务器人工智能运算的。 Ps2021版本新增了Ai神经元滤镜,它不是与软件一起安装的,只能在线调用,破解版的ps刚发布不久是可以使用的,后来就不能使用了,目前为止

    2024年02月10日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包