本文导读

阅读本文你将获得一下知识:

了解视频的基本原理。

了解FFmpeg是什么,和一些常用的用法。

用FFmpeg搭建简单的视频直播推流。

FFmpeg在nodeJs中的一些用法。

1.背景

短视频大行其道的年代,作为程序员势必需要了解:视频编辑背后的原理和技术。本文简略的描述了视频的组成原理,和常用的视频编辑工具,顺便提及了 NodeJs 中的用法。

想要了解视频原理,首先应该从图像原理开始说起。

2.图像基础

2.1 像素

图像画面由一个数字序列表示的图像中的一个最小单位色块,被称之像素(pixel/px)。

注意:像素只有位图才会有,是用来记录位图图像的。

我们所说的图像大小为1920*1080,指的就是长宽各有1920和1080的像素点,那么一张1920*1080的图片总共有的像素点为:1920*1080 = 2073600个像素点。

图像的大小如何计算?

图像的大小:像素数量 * 像素大小 = 图片大小,而像素大小 和 像素深度 有关系。RGB表示的真彩色能表示256×256×256=16,777,216,就是我们常见的1600万色,是人眼可见的全部色彩,超出没有意义。RGB的像素深度有1bit、4bit、8bit、16bit、24bit、32bit,如在ps中下图在新建一张画布选择8bit(指rgb每种颜色占8bit),那这样1 px = 3 * 8bit = 24bit,俗称24位图。根据以上公式就能算出如下图图像的大小:500 * 378 * 24 / 8 = 567000Byte = 567000Byte / 1024 = 553.7109375 Kb,和ps显示的图像大小一样。

但往往真实的图片大小远比以上计算的结果小很多, 这是因为导出的图片都经过压缩的,关于图片压缩技术可自行搜索学习。

★文末名片可以免费领取音视频开发学习资料,内容包括(FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。

见下方!↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

3.视频基础

3.1 视频和图像的关系?

视频就是图片一帧一帧连起来的产物,连起来的越快看着越流畅,用帧率(就是每秒播放图片的数量FPS)来衡量视频的流畅度。那么根据图片大小的算法就能算出视频的大小。

视频的大小 = 时长(秒) * 帧率(FPS)* 图片大小

那么1920×1280分辨率, 30FPS,时长1秒的视频的大小就是:1920 * 1280 * 24 / 8 * 30 / 1024 / 1024 = 210.9375 M,那么1小时的影片需要:210.9 * 60 * 60 / 1024 = 741.4453125 G,不禁一句我x,为啥我下载的大片才1G多,莫慌,视频要是这么简单,那我们太天真了,所以就有了下文「视频编码」

3.2 视频是怎么来的?

几个概念

  • 帧(Frame):就是一张静止的画面, 是视频的最小单位。

  • 帧速率(FPS):每秒播放图片的数量。

  • 码率(Bit Rate):视频文件在单位时间内使用的数据流量,决定视频的质量和大小,单位是kb/s或者Mb/s。一般来说同样分辨率下,视频文件的码流越大,压缩比就越小,画面质量就越高。码流越大,说明单位时间内取样率越大,数据流,精度就越高,处理出来的文件就越接近原始文件,图像质量越好,画质越清晰,要求播放设备的解码能力也越高。

    码率的常见三种模式:
    - CBR- 全程码率恒定- 文件大小可预测- 编码压力小,直播常用
    - VBR- 码率可变- 简单场景码率低,复杂场景码率高
    - CRF- 固定质量模式- CRF值越低,视频看起来质量越高
    复制代码

4.视频构成

视频和音频就像是饭和菜,封装格式就相当于碗。

注意:下文所有视频均代表包含音频的视频

4.1 视频封装格式

常见封装格式有MP4、AVI、FLV、mov、RMVB、MKV、WMV、3GP、ASF等。

4.2编码格式

视频编码是对采用视频压缩算法将一种视频格式装换成另一种视频格式的描述,音频编码同理。

常见的视频编码格式有:AC-1MPEG2/H.262VP8MPEG4VP9H.261H.263H.264H.265等。

常见的音频编码格式有:WMAMP3AC-3AACAPEFLACWAV等。

4.2.1视频压缩原理

主要是将视频像素数据(RGB,YUV等)压缩成为视频码流,从而降低视频的数据量,也就是处理像素。

YUV:RGB一样是一种颜色编码格式,相比RGB更利于压缩。其中"Y"表示明亮度(Lumina nce或Luma),也就是灰阶值;而"U"和"V"表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。

视频压缩分为下面两种类型

1. 帧内压缩

也叫空间压缩,类似于图像压缩,属于有损压缩算法,达不到很高的压缩比。

2. 帧间压缩

主要是通过记录关键帧,通过压缩关键帧之间连续帧的冗余信息(连续帧内相同的像素区域)的过程。

为了记录关键帧,将视频的画面帧分为三类:

  • I帧:帧内编码帧(intra picture),能展示最完整的画面, 可压缩的空间小,编码过程属于帧内编码。

  • P帧:前向预测编码在帧(predictive-frame),需要参考前面的I帧或者P帧来找出不同部分进行编码,压缩比比较高。

  • B帧 双向预测,也就是B帧记录的是本帧与前后帧的差别。也就是说要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是对解码性能要求较高。

GOP(Group of Pictures)值

编码器将多张图像进行编码后生产成一段一段的 GOP ,每一组IPB帧的序列包含多少帧,也就是一个I帧结束后需要经过多少帧才能出现下一个I帧。所以同码率下 GOP 值越大,B帧和P帧越多,视频质量越高。

在压缩或者解压缩视频的过程用到编解码器(Codec)。总的过程可以:

视频的编码的过程:

下图来源于即时通讯网。

视频解码的过程:

4.2.2音频压缩原理

音频压缩是在保证信号在听觉方面不产生失真的前提下,对音频数据信号进行尽可能大的压缩, 去除冗余信息。冗余信号包含人耳听觉范围外的音频信号以及被掩蔽掉的音频信号等。例如,人耳所能察觉的声音信号的频率范围为20Hz~20KHz,除此之外的其它频率人耳无法察觉,都可视为冗余信号。此外,根据人耳听觉的生理和心理声学现象,当一个强音信号与一个弱音信号同时存在时,弱音信号将被强音信号所掩蔽而听不见,这样弱音信号就可以视为冗余信号而不用传送。

音频压缩不是今天的主角,想深入学习可参考如下链接:

baike.baidu.com/item/%E9%9F…

www.kamilet.cn/how-audio-c…


下面进入本文的第二个主角

5.FFmpeg

5.1 FFmpeg什么?

FFmpeg is a collection of libraries and tools to process multimedia content such as audio, video, subtitles and related metadata.

简单说就是一个跨平台的视频处理的程序。

5.2 FFmpeg的原理

整个过程基本可以说成:解复用 => 解码 => 编码 => 复用器。

 _______              ______________
|       |            |              |
| input |  demuxer   | encoded data |   decoder
| file  | ---------> | packets      | -----+
|_______|            |______________|      |v_________|         || decoded || frames  ||_________|________             ______________       |
|        |           |              |      |
| output | <-------- | encoded data | <----+
| file   |   muxer   | packets      |   encoder
|________|           |______________|
复制代码

5.3FFmpeg安装

FFmpeg分为3个版本:Static、 Shared、 Dev

Mac安装:

brew install ffmpeg
复制代码

其他安装请参考官网。

5.4 FFmpeg用法

它能分别对视频的的各个组成进行编码,它对音视频的编码格式支持也比较全面。例如:对视频容器的装换、音视频的压缩、视频截取、截图、滤镜、音频提取等等,非常强大。

命令行语法:

ffmpeg [全局参数] [输入文件参数] -i [输入文件] [输出文件参数] [输出文件]
​
复制代码

视频信息:

// 获取视频信息
ffmpeg -i input.mp4
​
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input2.mp4':Metadata:major_brand     : isomminor_version   : 512compatible_brands: isomiso2mp41encoder         : Lavf58.29.100description     : Packed by Bilibili XCoder v2.0.2Duration: 00:08:24.45, start: 0.000000, bitrate: 2180 kb/s   // 时长,码率Stream #0:0(und): Video: hevc (Main) (hev1 / 0x31766568), yuv420p(tv), 1920x1080 [SAR 1:1 DAR 16:9], 2046 kb/s, 25 fps, 25 tbr, 16k tbn, 25 tbc (default)  // 第一个流是视频流,编码格式是hevc(封装格式为hev1),每一帧表示为yuv420p,分辨率1920*1080,码率2046kb/s, fps为25。Metadata:handler_name    : VideoHandlerStream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default) // 第二个流是音频流,编码格式是aac(封装格式为mp4a)采样率是44100 Hz,声道是立体声,码率92Kbit/s。Metadata:handler_name    : SoundHandler
复制代码

码率的装换:

ffmpeg -i input.mp4 -b:v 64k -bufsize 64k output.mp4
复制代码

帧率装换:

ffmpeg -i input.mp4 -r 5 output.mp4
复制代码

分辨率装换:

ffmpeg -i input.mp4 -vf scale=480:-1 output.mp4 // 1080p 转为 480p
复制代码

视频倍速:

ffmpeg -i test1 "setpts=PTS/5" test4.mp4 // 视频5倍速装换
fmpeg -i input.mp4 -filter:a "atempo=2.0" 4s.mp4 // 音频2倍速播放
ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" -vn 4s.mp4 // 音视频同时2倍速
复制代码

提取音视频:

ffmpeg -i input.mp4 -an output.mp4 //提取视频
ffmpeg -i input.mp4 -vn output.mp3 //提取音频
复制代码

视频比例转换:

ffmpeg -i input.mp4 -aspect 21:9 output.mp4
复制代码

视频容器转换:

ffmpeg -i input.mp4 output.avi
复制代码

视频截图:

ffmpeg -ss 00:00:05 -i input.mp4 -vframes 1 -q:v 5 -f image2 pic-%03d.jpeg
// -ss 00:00:05 从第五秒开始  -vframes 1 只截取1帧  -q:v 5 图片质量1-5
复制代码

视频截取:

ffmpeg -ss 00:00:02 -i input.mp4 -t 6.5 -c copy cut.mp4
ffmpeg -ss 00:00:02 -i input.mp4 -to 00:00:10 -c copy cut.mp4
复制代码

连续图片或视频生成gif图:

ffmpeg -i output.mp4 -to 10 -r 30 -vf scale=100:-1 gg.gif // 截取视频某个部分生成gif  100:-1 指定宽度,高度保持原始比例
​
ffmpeg -r 5 -i pic-%03d.jpeg 11.gif   // 多图生成gif
​
// 图片还可生成视频
ffmpeg -r 20 -i pic-%03d.jpeg gif.mp4
​
ffmpeg -f concat -i "concat:part1.mp4|part2.mp4|3.mp4|part4.mp4" -c copy output.mp4 // 多个视频拼接成一个
复制代码

图片或视频加滤镜:

// 模糊滤镜
ffmpeg -y -i pic-012.jpeg -vf boxblur=7 blur.jpeg
// 变色
ffmpeg -i pic-012.jpeg -vf colorbalance=rm=1 colorbalance1.jpg // 调整rgb某个维度的权重实现变色。
ffmpeg -i pic-012.jpeg -vf colorchannelmixer=.3:.4:.3:0:.3:.4:.3:0:.3:.4:.3 colorchannelmixer1.jpg // 对rgba四个通道进行重新计算,并分别给定权重比例。
ffmpeg -i pic-012.jpeg -vf hue=h=30:s=1 hue1.jpg // 改变色调,相当在调色板上调色
ffmpeg -i pic-012.jpeg -vf lutyuv="y=negval:u=negval:v=negval" lutyuv1.jpg // lutyuv用于yuv颜色空间
ffmpeg -i pic-012.jpeg -vf negate=0 negate1.jpg // 反转
ffmpeg -i pic-012.jpeg -vf swapuv swapuv1.jpg  // UV 互换
ffmpeg -i pic-012.jpeg -vf crop=w=200:h=300:x=500:y=800 crop1.jpg // 裁剪
​
复制代码

添加水印:

ffmpeg -i input.mp4 -i pic-012.jpeg -filter_complex "[1:v] scale=176:144 [logo];[0:v][logo]overlay=x=0:y=0" out.mp4 //给视频添加图片水印
​
ffmpeg -i input.mp4 -vf "drawtext=fontsize=100:fontcolor=white:alpha=0.3:text='%{localtime\:%Y\-%m\-%d %H-%M-%S}':y=h-line_h-100:x=(w-text_w)/2" output22.mp4// 添加文字水印
​
ffmpeg -i input.mp4 -i pic-012.jpeg -filter_complex "[1:v] scale=176:144 [logo];[0:v][logo]overlay=x=0:y=0" out.mp4
​
ffmpeg -i input.mp4 -vf drawtext="fontsize=100:text='我是水印':fontcolor=green:enable=lt(mod(t\,3)\,1)" interval-sy.mp4
// t 时间,s
// mod(t\,2) 计算t%2
// lt(mod(t\,2)\,1) 如果mod(t\,2)<1,返回1,否则返回0
// enable=lt(mod(t\,2)\,1) 每隔1s显示一次水印,enable=lt(mod(t\,3)\,1) 每隔3s.
复制代码

添加字幕:

// 第一步 用you-get下载B站视频
// 第二步 用 danmaku2ass.py 转换弹幕 https://github.com/m13253/danmaku2ass
// 第三步 可以用ffmpeg转换弹幕
ffpmeg -i input.ass input.srt
​
// 第四步 给视频添加字幕或弹幕 字幕可添加多个
ffmpeg -i input.mp4 -vf subtitles=input.ass output.mp4
复制代码

为音频添加封面:

ffmpeg -loop 1 -i cover.jpg -i input.mp3 -c:v libx264 -c:a aac -b:a 192k -shortest output.mp4
​
// -loop 1表示一直循环, -shortest 音频结束视频输出就结束
复制代码

视频画中画:

ffmpeg -re -i input.mp4 -vf "movie=output.mp4,scale = 480*320[test]; [in][test] overlay [out]" -vcodec libx264 videoInvideo.mp4
复制代码

多宫格:

ffmpeg -y -i input.mp4 -i input.mp4 \
-i input.mp4 -i input.mp4 \
-filter_complex "nullsrc=size=640x480[base]; \
[0:v]scale=320x240[topleft]; \
[1:v]scale=320x240[topright]; \
[2:v]scale=320x240[bottomleft]; \
[3:v]scale=320x240[bottomright]; \
[base][topleft]overlay=shortest=1[tmp1]; \
[tmp1][topright]overlay=shortest=1:x=320[tmp2]; \
[tmp2][bottomleft]overlay=shortest=1:y=240[tmp3]; \
[tmp3][bottomright]overlay=shortest=1:x=320:y=240" \
-vcodec libx264 9_video_filtered.flv
// nullsrc创建画布
复制代码

视频压缩:

ffmpeg -i input.mp3 -ab 128 output.mp3 // 压缩音频
​
ffmpeg -i input.mp4 -vf scale=1280:-1 -c:v libx264 -preset veryslow -crf 24 output.mp4 // 压缩视频
复制代码

视频直播推流:

// 录制视频保存在本地
ffmpeg -f avfoundation -i "1" -vcodec libx264 -preset ultrafast -f h264 -r 30 ~/Downloads/test.h264
​
// 推送已下载在文件夹的视频
ffmpeg -re -i ~/Downloads/xxx.mp4  -vcodec libx264 -acodec aac -strict -2 -f flv rtmp://localhost:1935/live
​
// 录制桌面
ffmpeg -f avfoundation -i "1" -vcodec libx264 -preset ultrafast -acodec libfaac -f flv rtmp://localhost:1935/rtmplive/room
​
// 录制桌面和麦克风
ffmpeg -f avfoundation -i "1:0" -vcodec libx264 -preset ultrafast -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost:1935/live/room
​
// 录制桌面和麦克风,并打开摄像头拍摄
ffmpeg -f avfoundation -framerate 30 -i "1:0" \-f avfoundation -framerate 30 -video_size 640x480 -i "0" \-c:v libx264 -preset ultrafast \-filter_complex 'overlay=main_w-overlay_w-10:main_h-overlay_h-10' -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost:2016/rtmplive/room
​
复制代码

5.5 直播DEMO搭建

  1. 安装支持rtmp的docker镜像:docker pull tiangolo/nginx-rtmp

  2. 启动tiangolo/nginx-rtmp容器:docker run -d -p 1935:1935 --name nginx-rtmp tiangolo/nginx-rtmp 查看nginx配置: docker exec -it nginx-rtmp /bin/bash 推流地址:rtmp://10.17.8.189:1935/live

  3. Ffmpeg 推流:ffmpeg -f avfoundation -i "1:0" -vcodec libx264 -preset ultrafast -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost:1935/live/room

  4. 用支持支持rtmp的播放器(IINA)或者ffplay打开: ffplay rtmp://10.17.8.189:1935/live

一个简单的直播 demo 就跑起来了。


5.6FFmpeg 在Node中的用法

Fluent-ffmpeg

Fluent-ffmpeg是将复杂的ffmpeg命令抽象成nodeJs的模块,前提是系统已安装 FFmpeg

一些简单的用法

// 视频信息
ffmpeg.ffprobe(input, function (err, metadata) {console.dir(metadata);
});
​
// 提取音频
ffmpeg(input).audioCodec("libmp3lame").on("error", function (err) {console.log("发生错误: " + err.message);}).on("end", function () {console.log("提取音频完成 												

视频原理和FFmpeg相关推荐

  1. 初探视频原理和FFmpeg

    编者按:本文作者郭文涛,奇舞团前端开发工程师. 本文导读 阅读本文你将获得以下知识: 了解视频的基本原理. 了解 FFmpeg 是什么,和一些常用的用法. 用 FFmpeg 搭建简单的视频直播推流. ...

  2. java在线制作视频,调用ffmpeg(一)

    目地:写一个java制作视频的网站. 大致流程:用户上传n张图片和背景音乐,网站返回一个视频. 大家都知道,java是通过命令行来调用ffmpeg的,java没有现成的比较好的封装ffmpeg的jar ...

  3. 学习 koa 源码的整体架构,浅析koa洋葱模型原理和co原理

    前言 这是学习源码整体架构系列第七篇.整体架构这词语好像有点大,姑且就算是源码整体结构吧,主要就是学习是代码整体结构,不深究其他不是主线的具体函数的实现.本篇文章学习的是实际仓库的代码. 学习源码整体 ...

  4. 视频操作之ffmpeg基础使用

    ffmpeg基础使用 ffmpeg安装介绍 ffmpeg常用命令介绍 ffmpeg安装介绍 官网:https://ffmpeg.zeranoe.com/builds/,该网站中的FFMPEG分为3个版 ...

  5. 视频禁音 - 在线将视频原声调成静音工具

    怎么把视频静音处理?一刀工具箱提供视频片段消音,把视频中的某一片段静音处理,消除视频素材声音,把视频设置成无声,把原视频静音,视频不想让对方听到声音! 代码片段 buildVideo(){let th ...

  6. Mybatis插件原理和PageHelper结合实战分页插件(七)

    今天和大家分享下mybatis的一个分页插件PageHelper,在讲解PageHelper之前我们需要先了解下mybatis的插件原理.PageHelper 的官方网站:https://github ...

  7. java处理视频_Java使用FFmpeg处理视频[视频直播三]

    承接上文. [拓展] 有人问我,怎么配置互联网环境的Mevan,这里拓展一下. settings_outweb.xml xmlns:xsi="http://www.w3.org/2001/X ...

  8. HBase学习指南之HBase原理和Shell使用

    HBase学习指南之HBase原理和Shell使用 参考资料: 1.https://www.cnblogs.com/nexiyi/p/hbase_shell.html,hbase shell 转载于: ...

  9. IAP的原理和stm8的IAP

    一.引出(IAP的原理和stm8上实现IAP的问题) 具有IAP功能的单片机,程序可以分为两部分:IAP和APP.APP是用来实现真正功能的程序,而IAP是用来远程重新编程APP的程序.单片机上电时会 ...

最新文章

  1. 自然语言处理算法工程师历史最全资料汇总-基础知识点、面试经验
  2. 字典学习(Dictionary Learning)
  3. 一张图看懂项目管理的47个过程
  4. SAP EWM中仓库任务WT创建的函数
  5. java程序的最小程序单位_微信小程序中rpx与rem单位使用
  6. 网狐棋牌(五) TCPSocketEnging分析
  7. sql查询结果字段名与字段值倒过来了
  8. php求数组交集的自定义函数,php数组交集函数
  9. LeetCode 325. 和等于 k 的最长子数组长度(哈希表记录第一次出现的状态)
  10. HAproxy开启日志记录
  11. 编译mGi软键盘部分[原创]
  12. 为OLED屏添加GUI支持2:2D图形库
  13. Reporting Services 空白页面
  14. [引用]关于C#操作INI文件的总结
  15. js事件循环机制-宏任务微任务
  16. ftp连接服务器连接不上,xshell可以连接上
  17. 基于51单片机的数码管密码锁设计资料
  18. 日本企业给我们的启示
  19. 怎么扩展服务器内存?
  20. spine 局部换装

热门文章

  1. 三分钟读懂新一代人工智能——ChatGPT
  2. 基于LCC谐振补偿网络的无线充电技术的研究
  3. 一段代码识别当前浏览器是pc端、手机端还是平板
  4. Go中的MPG模式解析
  5. 【PhotoShop基础B篇】准确控制曝光
  6. 酷派大神F1联通版(8927W)刷MIUI 7,打造方便父母使用的老人机
  7. 金蝶apusic9.0版本安装包
  8. 互联网晚报 | 05月16日 星期一 | 上海:6月1日至6月中下旬全面恢复正常生产生活;微软IE浏览器将于6月16日正式退役...
  9. Markdown的基本使用
  10. 理工附中2021年高考成绩查询,人大附中、理工附中、101中学、十二中等5区10校高考成绩汇总!...