FFmpeg再学习 -- Windows下安装说明

看了半晌 雷霄骅 的 ffmpeg 的视频。待续稍后总结。

一、FFmpeg 简介

FFmpeg 是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用 LGPL 或GPL 许可证(依据你选择的组件)。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库 libavcodec,为了保证高可移植性和编解码质量, libavcodec 里很多 codec 都是从头开发的。
ffmpeg 项目由以下几部分组成:
1、ffmpeg 视频文件转换命令行工具,也支持经过实时电视卡抓取和编码成视频文
件.
2、ffserver 基于 HTTP、 RTSP 用于实时广播的多媒体服务器.也支持时间平移
3、ffplay 用 SDL 和 FFmpeg 库开发的一个简单的媒体播放器
4、libavcodec 一个包含了所有 FFmpeg 音视频编解码器的库.为了保证最优性能和高可复用性,大多数编解码器从头开发的.
5、libavformat 一个包含了所有的普通音视格式的解析器和产生器的库

更多部分

参看:ffmpeg Documentation

二、下载安装 FFmpeg

下载:Download FFmpeg for Windows      解压后即可使用

该网站中的FFMPEG分为3个版本:Static,Shared,Dev。

前两个版本可以直接在命令行中使用,他们的区别在于:

Static里面只有3个应用程序:ffmpeg.exe,ffplay.exe,ffprobe.exe,每个exe的体积都很大,相关的Dll已经被编译到exe里面去了。

Shared里面除了3个应用程序:ffmpeg.exe,ffplay.exe,ffprobe.exe之外,还有一些Dll,比如说avcodec-54.dll之类的。Shared里面的exe体积很小,他们在运行的时候,到相应的Dll中调用功能。

Dev版本是用于开发的,里面包含了库文件xxx.lib以及头文件xxx.h,这个版本不包含exe文件。打开系统命令行接面,切换到ffmpeg所在的目录,就可以使用这3个应用程序了。

也可以参看下面的链接下个之前的版本。

三、使用

将下载完的软件包解压在任意盘中,然后重命名为 ffmpeg。比如存放在 F 盘。

第一、进入进入DOS操作界面

按 WIN + R 键进入运行界面;输入 cmd,进入 DOS 界面。



第二、进入 F 盘中的 ffmpeg\bin文件夹

输入 F: 回车,进入 F 盘;然后 cd ffmepg\bin 即进入该文件夹。


其中DOS指令令和shell指令对比,参看: UNIX For DOS Users

基本的DOS命令
最关键命令
打开指定文件夹命令 cd {文件路径}
切换到上一级文件夹 cd ..
切换到当前目录下名为xxx的文件夹 cd xxx
改变当前盘符命令 c:
其他命令
查看目录内容命令 dir
创建目录命令 md
文件复制命令 copy
删除文件命令 del
清除屏幕命令 cls
Windows系统提供的额外命令
例如ping, ipconfig等等

第三、测试

命令行中输入ffmpeg.exe,查看弹出的信息。(当然也可以不写后缀 .exe )

F:\ffmpeg\bin>ffmpeg
ffmpeg version N-86625-gbbaca6e Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 7.1.0 (GCC)
  configuration: --enable-gpl --enable-version3 --enable-cuda --enable-cuvid --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-zlib
  libavutil      55. 66.100 / 55. 66.100
  libavcodec     57. 99.102 / 57. 99.102
  libavformat    57. 75.100 / 57. 75.100
  libavdevice    57.  7.100 / 57.  7.100
  libavfilter     6. 94.100 /  6. 94.100
  libswscale      4.  7.101 /  4.  7.101
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...


Use -h to get full help or, even better, run 'man ffmpeg'

测试指令 利用mpeg4编码方式

使用指令 ffmpeg -f image2 -i %02d.jpg -vcodec mpeg4 -s 1920x1080 multi_jpg3.mp4  
F:\ffmpegbin>ffmpeg -f image2 -i %02d.jpg -vcodec mpeg4 -s 1920x1080 multi_jpg3.mp4
ffmpeg version N-86625-gbbaca6e Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 7.1.0 (GCC)
  configuration: --enable-gpl --enable-version3 --enable-cuda --enable-cuvid --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-zlib
  libavutil      55. 66.100 / 55. 66.100
  libavcodec     57. 99.102 / 57. 99.102
  libavformat    57. 75.100 / 57. 75.100
  libavdevice    57.  7.100 / 57.  7.100
  libavfilter     6. 94.100 /  6. 94.100
  libswscale      4.  7.101 /  4.  7.101
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
Input #0, image2, from '%02d.jpg':
  Duration: 00:00:03.16, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: mjpeg, yuvj444p(pc, bt470bg/unknown/unknown), 5184x3456, 25 tbr, 25 tbn, 25 tbc
File 'multi_jpg3.mp4' already exists. Overwrite ? [y/N] y
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> mpeg4 (native))
Press [q] to stop, [?] for help
[swscaler @ 000000000250a960] deprecated pixel format used, make sure you did set range correctly
Output #0, mp4, to 'multi_jpg3.mp4':
  Metadata:
    encoder         : Lavf57.75.100
    Stream #0:0: Video: mpeg4 ( [0][0][0] / 0x0020), yuv420p, 1920x1080, q=2-31, 200 kb/s, 25 fps, 12800 tbn, 25 tbc
    Metadata:
      encoder         : Lavc57.99.102 mpeg4
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
[swscaler @ 0000000006f100a0] deprecated pixel format used, make sure you did set range correctly
    Last message repeated 1 times
[swscaler @ 0000000006f100a0] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 0000000006f100a0] deprecated pixel format used, make sure you did set range correctly
frame=   79 fps=4.0 q=24.8 Lsize=    4507kB time=00:00:03.12 bitrate=11833.3kbits/s speed=0.157x
video:4505kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.033575%

当然也可以使用 bat 脚本来实现

新建一个记事本文件 新建文本文档 .txt,将其改为 ffmpeg.bat 即 bat 脚本。

然后编辑,比如 ffmpeg -i input.avi -b:v 640k output.ts  保存。

然后点击 ffmpeg.bat 即可跳转到 DOS 界面执行。

当然可能有局限性,比如上面那个例子我在脚本上就无法执行,现在还没有找到原因。


再举一个有意思的例子,将MP4转换成gif格式

ffmpeg -ss 00:00:00.000 -i haituoshan.mp4 -pix_fmt rgb24 -r 10 -s 1920x1080 -t 00:00:3.000 output.gif

说明:将输入的文件从(-ss)设定的时间开始以10帧频率,输出到1920x1080大小的 gif 中,时间长度为-t 设定的参数。通过这样转换出来的 gif 一般都比较大,可以使用 ImageMagick 来优化图片的大小。

当然你也可以使用图片压缩工具:在线图片压缩-在线图片压缩软件



常用指令参看:

ffmpeg 入门 

FFmpeg实用命令

[FFmpeg] ffmpeg 常用命令

FFmpeg功能命令集合

wiki:Encode/H.264

wiki:Slideshow

ffmpeg 常用命令汇总

四、修改环境变量

点击 计算机->属性->高级系统设置->高级->环境变量

环境变量我们之前讲过,参看:UNIX再学习 -- 环境变量



将“用户变量”中的 PATH 变量值改为你的 ffmpeg\bin 文件夹位置,点击确定保存更改。


备份一下原来的变量值:

%CDSROOT%\openaccess\bin\win32\opt;%CDSROOT%\tools\capture;%CDSROOT%\tools\pspice;%CDSROOT%\tools\
specctra\bin;%CDSROOT%\tools\fet\bin;%CDSROOT%\tools\libutil\bin;%CDSROOT%\tools\bin;%CDSROOT%\
tools\pcb\bin;;%USERPROFILE%\AppData\Local\Microsoft\WindowsApps

注意

如果在这个窗口输入的内容有误,那么有可能会造成 Windows 无法正常启动。如果在"用户变量"设置下没有 PATH条目,点击新建按钮创建。在变量名栏输入 PATH。

这个方法可以让当前用户能够使用 FFmpeg。其他 Windows 用户不能够使用。如果要使每个用户都能够使用,你需要在 "系统变量" 的PATH条目中添加你的 ffmpeg\bin 文件夹位置。注意不要够删除在变量中原来已有的内容。

测试

修改前,无法运行 ffmpeg  程序

修改后,可以运行 ffmpeg 程序


五、VS 下 FFmpeg 开发环境搭建

首先下载相应的 FFmpeg 开发包


然后新建控制台工程

打开 VS;
文件->新建->项目->Win32控制台应用程序,点击完成。
注意,选择的位置最好不要有 空格或者汉字。




拷贝 FFmpeg 开发文件

头文件( *.h)拷贝至项目文件夹的include子文件夹下
导入库文件( *.lib)拷贝至项目文件夹的lib子文件夹下
动态库文件( *.dll) 拷贝至项目文件夹下

点击右键,选择在资源管理器中打开文件夹,进入项目目录。
(注意,如果手动进入注意文件夹位置,我就是没找好位置,试了半天最后才发现,将上面的这些文件拷贝到错误的文件夹下了)


PS:如果直接使用官网上下载的 FFmpeg 开发文件。则可能还需要将 MinGW 安装目录中的 inttypes.h, stdint.h, _mingw.h 三个文件拷贝至项目文件夹的 include 子文件夹下。
上面的下载配置可是没有这三个文件的,如需要 下载:小练习-FFmpeg配置

配置开发文件

打开属性面板

解决方案资源管理器->右键单击项目->属性

头文件配置

配置属性->C/C++->常规->附加包含目录,输入“ include”(刚才拷贝头文件的目录)

导入库配置

配置属性->链接器->常规->附加库目录,输入“ lib” (刚才拷贝库文件的目录)

配置属性->链接器->输入->附加依赖项,输入“ avcodec.lib; avformat.lib; avutil.lib; avdevice.lib; avfilter.lib; postproc.lib; swresample.lib; swscale.lib”(导入库的文件名)

动态库不用配置

测试

将 FFmpeg.cpp 添加测试代码,改为如下:
// FFmpeg.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#define __STDC_CONSTANT_MACROS

extern "C"
{
#include "libavcodec/avcodec.h"
};

int main()
{
	printf("%s", avcodec_configuration());
    return 0;
}
打断点,如果不打断点,调试的时候一闪而过什么也看不到的。
在return 0; 左边点击一下,出现红点,即为断点。

然后点击本地Windows调试器,出现此项目已经过期,选择 是。


可看到出现结果,说明FFmpeg配置成功。

六、问题分析

有时调试时会出现版本不一致的问题.

查看项目Windows SDK 版本为 8.1 

解决方法:

错误 MSB8036  找不到 Windows SDK 版本10.0.16299.0。

下载并安装:

Windows SDK (ver. 10.0.16299.91) and Microsoft Emulator for Windows 10 mobile (ver. 15254.1)



七、示例演示

在一些嵌入式系统中,视频以 jpeg 图像格式传出来,而且数据量非常大。这种情况下如果要对 jpeg 图像进行解码并且重新编码成 264 之类的格式再放入视频容器中会消耗大量的 CPU 资源,若不是性能特别犀利的 CPU 是无法承受的,这个时候有一个折衷的办法,就是直接将jpeg连续保存起来(也就是保存成 mjpeg 视频格式),然后直接放入视频容器中。
这就话就解释了,为什么要用保存成 mjpeg。因为成千上万张图片通过 264 编码确实好慢。
下面是相关的源码:
#include <stdio.h>
#include "stdafx.h"

extern "C"//包含C文件头
{
#include "libavformat/avformat.h"
};
#define DATASIZE 1024*1024

AVStream *add_vidio_stream(AVFormatContext *oc, enum AVCodecID codec_id)//用以初始化一个用于输出的AVFormatContext结构体
{
	AVStream *st;
	AVCodec *codec;

	st = avformat_new_stream(oc, NULL);
	if (!st)
	{
		printf("Could not alloc stream\n");
		exit(1);
	}
	codec = avcodec_find_encoder(codec_id);//查找mjpeg解码器
	if (!codec)
	{
		printf("codec not found\n");
		exit(1);
	}
	avcodec_get_context_defaults3(st->codec, codec);//申请AVStream->codec(AVCodecContext对象)空间并设置默认值(由avcodec_get_context_defaults3()设置

	st->codec->bit_rate = 400000;//设置采样参数,即比特率  
	st->codec->width = 1080;//设置视频宽高,这里跟图片的宽高保存一致即可
	st->codec->height = 1800;
	st->codec->time_base.den = 10;//设置帧率
	st->codec->time_base.num = 1;

	st->codec->pix_fmt = PIX_FMT_YUV420P;//设置像素格式  
	st->codec->codec_tag = 0;
	if (oc->oformat->flags & AVFMT_GLOBALHEADER)//一些格式需要视频流数据头分开
		st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
	return st;
}

void main()
{
	AVFormatContext *ofmt_ctx = NULL;//其包含码流参数较多,是一个贯穿始终的数据结构,很多函数都要用到它作为参数
	const char *out_filename = "out.mkv";//输出文件路径,在这里也可以将mkv改成别的ffmpeg支持的格式,如mp4,flv,avi之类的
	int ret;//返回标志

	av_register_all();//初始化解码器和复用器
	avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);//初始化一个用于输出的AVFormatContext结构体,视频帧率和宽高在此函数里面设置
	if (!ofmt_ctx)
	{
		printf("Could not create output context\n");
		return;
	}

	AVStream *out_stream = add_vidio_stream(ofmt_ctx, AV_CODEC_ID_MJPEG);//创造输出视频流
	av_dump_format(ofmt_ctx, 0, out_filename, 1);//该函数会打印出视频流的信息,如果看着不开心可以不要

	if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE))//打开输出视频文件
	{
		ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
		if (ret < 0) {
			printf("Could not open output file '%s'", out_filename);
			return;
		}
	}

	if (avformat_write_header(ofmt_ctx, NULL) < 0)//写文件头(Write file header)
	{
		printf("Error occurred when opening output file\n");
		return;
	}

	int frame_index = 0;//放入视频的图像计数
	unsigned char *mydata = new unsigned char[DATASIZE];
	AVPacket pkt;
	av_init_packet(&pkt);
	pkt.flags |= AV_PKT_FLAG_KEY;
	pkt.stream_index = out_stream->index;//获取视频信息,为压入帧图像做准备
	while (frame_index<100)//将图像压入视频中
	{
		FILE *file;//打开一张jpeg图像并读取其数据,在这里图像最大为1M,如果超过1M,则需要修改1024*1024这里
		fopen_s(&file, "1.jpg", "rb");
		pkt.size = fread(mydata, 1, DATASIZE, file);
		pkt.data = mydata;
		fclose(file);
		if (av_interleaved_write_frame(ofmt_ctx, &pkt) < 0) //写入图像到视频
		{
			printf("Error muxing packet\n");
			break;
		}
		printf("Write %8d frames to output file\n", frame_index);//打印出当前压入的帧数
		frame_index++;
	}
	av_free_packet(&pkt);//释放掉帧数据包对象
	av_write_trailer(ofmt_ctx);//写文件尾(Write file trailer)
	delete[]mydata;//释放数据对象
	if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
		avio_close(ofmt_ctx->pb);//关闭视频文件
	avformat_free_context(ofmt_ctx);//释放输出视频相关数据结构
	return;
}
这是我写的工程文件:FFmpeg 工程文件
(PS:参看博文里的工程文件,反正我调式是一直失败的,不过源码还是值得参考的)。

执行结果生成 out.mkv 视频


思考,上面实现的是将一张图片循环100次。如果是有编号顺序的图片呢

例如,将编号从 0001~1000 的图片转为视频。
使用 sprintf 将图片名写入字符串,然后使用 fopen_s 打开。
        char bufName[50];
	int i = 0;
	for (i=1;i<=1000;i++)
	//while (frame_index<100)//将图像压入视频中
	{
		sprintf(bufName, "%04d.jpg", i);
		printf("%s\n",bufName);
		FILE *file;//打开一张jpeg图像并读取其数据,在这里图像最大为1M,如果超过1M,则需要修改1024*1024这里
		fopen_s(&file, bufName, "rb");
		pkt.size = fread(mydata, 1, DATASIZE, file);
		pkt.data = mydata;
		fclose(file);
		if (av_interleaved_write_frame(ofmt_ctx, &pkt) < 0) //写入图像到视频
		{
			printf("Error muxing packet\n");
			break;
		}
		//printf("Write %8d frames to output file\n", frame_index);//打印出当前压入的帧数
		//frame_index++;
	}
根据实际情况修改 DATASIZE ,应超过图片大小的最大值。
#define DATASIZE 1024*1024*50
然后,还要根据实际情况修改图片的参数信息。
	st->codec->bit_rate = 400000;//设置采样参数,即比特率  
	st->codec->width = 5184;//设置视频宽高,这里跟图片的宽高保存一致即可
	st->codec->height = 3456;
	st->codec->time_base.den = 2;//设置帧率
	st->codec->time_base.num = 1;
到此就 OK,即可调式生成视频。

八、总结

用时一天半,终于把 FFmpeg 在 Windows 下的操作总结清楚了。说实话一开始对于 DOS 命令、VS 创建项目等都是不熟的,再将遇到的问题逐一解决,总的来说收获挺多的。期间 FFmpeg 测试的时候,将图片或视频转为 gif,也是挺有意思。我的微信公众号又要有的新内容了 哈哈。


已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师:白松林 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值