ffmpeg视频转换代码(ffmpeg 视频转换)
admin 发布:2022-12-19 17:05 136
本篇文章给大家谈谈ffmpeg视频转换代码,以及ffmpeg 视频转换对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、FFmpeg的视频解码详解
- 2、利用ffmpeg.exe实现视频转换flv
- 3、php代码怎么调用FFmpeg来实现视频格式转换
- 4、我想用ffmpeg命令行转换一个视频文件,视、音频编码格式不变,只是将画面旋转90度,请问命令行该如何写?
- 5、(高分求代码)基于ffmpeg 获取视频帧保存成图像转成yuv图像序列
- 6、ffmpeg 基本用法
FFmpeg的视频解码详解
第一步:组册组件
av_register_all()
例如:编码器、解码器等等…
第二步:打开封装格式-打开文件
例如:.mp4、.mov、.wmv文件等等...
avformat_open_input();
第三步:查找视频流
如果是视频解码,那么查找视频流,如果是音频解码,那么就查找音频流
avformat_find_stream_info();
第四步:查找视频解码器
1、查找视频流索引位置
2、根据视频流索引,获取解码器上下文
3、根据解码器上下文,获得解码器ID,然后查找解码器
第五步:打开解码器
avcodec_open2();
第六步:读取视频压缩数据-循环读取
没读取一帧数据,立马解码一帧数据
第七步:视频解码-播放视频-得到视频像素数据
第八步:关闭解码器-解码完成
//第一步:组册组件
av_register_all();
//第二步:打开封装格式-打开文件
//参数一:封装格式上下文
//作用:保存整个视频信息(解码器、编码器等等...)
//信息:码率、帧率等...
AVFormatContext* avformat_context = avformat_alloc_context();
//参数二:视频路径
const char *url = [jinFilePath UTF8String]
//参数三:指定输入的格式
//参数四:设置默认参数
int avformat_open_input_result = avformat_open_input(avformat_context, url,NULL, NULL);
if (avformat_open_input_result !=0){
NSLog("打开文件失败");
//不同的平台替换不同平台log日志
return;
}
//第三步:查找视频流-拿到视频信息
//参数一:封装格式上下文
//参数二:指定默认配置
int avformat_find_stream_info_result = avformat_find_stream_info(avformat_context,NULL);
if (avformat_find_stream_info_result 0){
NSLog(" 查找失败");
return;
}
//第四步:查找视频解码器
//1、查找视频流索引位置
int av_stream_index = -1;
for (int i =0; i avformat_context-nb_streams; ++i) {
//判断流类型:视频流、音频流、字母流等等...
if (avformat_context-streams[i]-codec-codec_type == AVMEDIA_TYPE_VIDEO){
av_stream_index = i;
break;
}
}
//2、根据视频流索引,获取解码器上下文
AVCodecContext *avcodec_context = avformat_context-streams[av_stream_index]-codec;
//3、根据解码器上下文,获得解码器ID,然后查找解码器
AVCodec *avcodec = avcodec_find_decoder(avcodec_context-codec_id);
//第五步:打开解码器
int avcodec_open2_result = avcodec_open2(avcodec_context, avcodec,NULL);
if (avcodec_open2_result !=0){
NSLog("打开解码器失败");
return;
}
//第六步:读取视频压缩数据-循环读取
//1、分析av_read_frame参数
//参数一:封装格式上下文
//参数二:一帧压缩数据 = 一张图片
//av_read_frame()
//结构体大小计算:字节对齐原则
AVPacket* packet = (AVPacket*)av_malloc(sizeof(AVPacket));
//3.2 解码一帧视频压缩数据-进行解码(作用:用于解码操作)
//开辟一块内存空间
AVFrame* avframe_in = av_frame_alloc();
int decode_result =0;
//4、注意:在这里我们不能够保证解码出来的一帧视频像素数据格式是yuv格式
//参数一:源文件-原始视频像素数据格式宽
//参数二:源文件-原始视频像素数据格式高
//参数三:源文件-原始视频像素数据格式类型
//参数四:目标文件-目标视频像素数据格式宽
//参数五:目标文件-目标视频像素数据格式高
//参数六:目标文件-目标视频像素数据格式类型
SwsContext *swscontext = sws_getContext(avcodec_context-width,
avcodec_context-height,
avcodec_context-pix_fmt,
avcodec_context-width,
avcodec_context-height,
AV_PIX_FMT_YUV420P,
SWS_BICUBIC,
NULL,
NULL,
NULL);
//创建一个yuv420视频像素数据格式缓冲区(一帧数据)
AVFrame* avframe_yuv420p = av_frame_alloc();
//给缓冲区设置类型-yuv420类型
//得到YUV420P缓冲区大小
//参数一:视频像素数据格式类型-YUV420P格式
//参数二:一帧视频像素数据宽 = 视频宽
//参数三:一帧视频像素数据高 = 视频高
//参数四:字节对齐方式-默认是1
int buffer_size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P,
avcodec_context-width,
avcodec_context-height,
1);
//开辟一块内存空间
uint8_t *out_buffer = (uint8_t *)av_malloc(buffer_size);
//向avframe_yuv420p-填充数据
//参数一:目标-填充数据(avframe_yuv420p)
//参数二:目标-每一行大小
//参数三:原始数据
//参数四:目标-格式类型
//参数五:宽
//参数六:高
//参数七:字节对齐方式
av_image_fill_arrays(avframe_yuv420p-data,
avframe_yuv420p-linesize,
out_buffer,
AV_PIX_FMT_YUV420P,
avcodec_context-width,
avcodec_context-height,
1);
int y_size, u_size, v_size;
//5.2 将yuv420p数据写入.yuv文件中
//打开写入文件
const char *outfile = [joutFilePath UTF8String];
FILE* file_yuv420p = fopen(outfile,"wb+");
if (file_yuv420p ==NULL){
NSLog("输出文件打开失败");
return;
}
int current_index =0;
while (av_read_frame(avformat_context, packet) =0){
//=:读取到了
//0:读取错误或者读取完毕
//2、是否是我们的视频流
if (packet-stream_index == av_stream_index){
//第七步:解码
//学习一下C基础,结构体
//3、解码一帧压缩数据-得到视频像素数据-yuv格式
//采用新的API
//3.1 发送一帧视频压缩数据
avcodec_send_packet(avcodec_context, packet);
//3.2 解码一帧视频压缩数据-进行解码(作用:用于解码操作)
decode_result = avcodec_receive_frame(avcodec_context, avframe_in);
if (decode_result ==0){
//解码成功
//4、注意:在这里我们不能够保证解码出来的一帧视频像素数据格式是yuv格式
//视频像素数据格式很多种类型: yuv420P、yuv422p、yuv444p等等...
//保证:我的解码后的视频像素数据格式统一为yuv420P-通用的格式
//进行类型转换: 将解码出来的视频像素点数据格式-统一转类型为yuv420P
//sws_scale作用:进行类型转换的
//参数一:视频像素数据格式上下文
//参数二:原来的视频像素数据格式-输入数据
//参数三:原来的视频像素数据格式-输入画面每一行大小
//参数四:原来的视频像素数据格式-输入画面每一行开始位置(填写:0-表示从原点开始读取)
//参数五:原来的视频像素数据格式-输入数据行数
//参数六:转换类型后视频像素数据格式-输出数据
//参数七:转换类型后视频像素数据格式-输出画面每一行大小
sws_scale(swscontext,
(const uint8_t *const *)avframe_in-data,
avframe_in-linesize,
0,
avcodec_context-height,
avframe_yuv420p-data,
avframe_yuv420p-linesize);
//方式一:直接显示视频上面去
//方式二:写入yuv文件格式
//5、将yuv420p数据写入.yuv文件中
//5.1 计算YUV大小
//分析一下原理?
//Y表示:亮度
//UV表示:色度
//有规律
//YUV420P格式规范一:Y结构表示一个像素(一个像素对应一个Y)
//YUV420P格式规范二:4个像素点对应一个(U和V: 4Y = U = V)
y_size = avcodec_context-width * avcodec_context-height;
u_size = y_size /4;
v_size = y_size /4;
//5.2 写入.yuv文件
//首先-Y数据
fwrite(avframe_yuv420p-data[0], 1, y_size, file_yuv420p);
//其次-U数据
fwrite(avframe_yuv420p-data[1], 1, u_size, file_yuv420p);
//再其次-V数据
fwrite(avframe_yuv420p-data[2], 1, v_size, file_yuv420p);
current_index++;
NSLog("当前解码第%d帧", current_index);
}
}
}
//第八步:释放内存资源,关闭解码器
av_packet_free(packet);
fclose(file_yuv420p);
av_frame_free(avframe_in);
av_frame_free(avframe_yuv420p);
free(out_buffer);
avcodec_close(avcodec_context);
avformat_free_context(avformat_context);
利用ffmpeg.exe实现视频转换flv
可以的,在java代码中调用ffmpeg.exe程序,同时将需要进行格式转换的原视频文件和输出的视频文件地址当作参数进行设置就OK了。我在C#中实现过的。
最简单且常用的ffmpeg命令行使用方式:
ffmpeg.exe -i inputfilename.mpg outputfilename.flv
(输出文件格式通过后缀名来指定,同时必须指定输出文件名,因为程序不会自动创建输出文件名)
更详尽的参数设置可以参考:
php代码怎么调用FFmpeg来实现视频格式转换
具体代码如下: PHP 独特的语法混合了C、Java、Perl以及PHP自创的语法。 它可以比CGI或者Perl更快速地执行动态网页。用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML(标准通用标记语言下的一个应用)文档中去执行
我想用ffmpeg命令行转换一个视频文件,视、音频编码格式不变,只是将画面旋转90度,请问命令行该如何写?
在你的转码命令里面添加上-vf rotate=PI/2或者-vf rotate=3*PI/2,例如
ffmpeg -i E:\ffmpeg\test.mp4 -y -vf rotate=PI/2 E:\ffmpeg\dest1.mp4
(高分求代码)基于ffmpeg 获取视频帧保存成图像转成yuv图像序列
#include stdio.h
#include windows.h
#include "string.h"
#include "stdlib.h"
// #include "avcodec.h"
// #include "avformat.h"
// #include "avutil.h"
// #include "flvdec.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/avutil.h"
#include "libswscale/swscale.h"
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"swscale.lib")
bool GetNextFrame(AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, int videoStream, AVFrame *pFrame)
{
static AVPacket packet;
static int bytesRemaining=0;
static uint8_t *rawData;
static bool fFirstTime=true;
int bytesDecoded;
int frameFinished;
int ii = 0;
AVPacket packettest;
// First time we're called, set packet.data to NULL to indicate it
// doesn't have to be freed
if(fFirstTime)
{
fFirstTime=false;
packet.data=NULL;
}
// Decode packets until we have decoded a complete frame
while(true)
{
// Work on the current packet until we have decoded all of it
while(bytesRemaining 0)
{
// Decode the next chunk of data
bytesDecoded=avcodec_decode_video2(pCodecCtx, pFrame,
frameFinished, packet);//, rawData, bytesRemaining);
// Was there an error?
if(bytesDecoded 0)
{
fprintf(stderr, "Error while decoding frame\n");
return false;
}
bytesRemaining-=bytesDecoded;
rawData+=bytesDecoded;
// Did we finish the current frame? Then we can return
if(frameFinished)
return true;
}
// Read the next packet, skipping all packets that aren't for this
// stream
do
{
++ii;
// Free old packet
if(packet.data!=NULL)
av_free_packet(packet);
// Read new packet
if(/*av_read_packet*/av_read_frame(pFormatCtx, packet)0)
goto loop_exit;
memcpy(packettest, packet, sizeof(AVPacket));
printf("%d\n", packet.stream_index);
} while(packet.stream_index!=videoStream);
bytesRemaining=packet.size;
rawData=packet.data;
}
loop_exit:
// Decode the rest of the last frame
bytesDecoded=avcodec_decode_video2(pCodecCtx, pFrame, frameFinished,
packet);//, rawData, bytesRemaining);
// Free last packet
if(packet.data!=NULL)
av_free_packet(packet);
return frameFinished!=0;
}
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
{
FILE *pFile;
char szFilename[32];
int y;
/////////////////////
BITMAPFILEHEADER m_fileHeader;
BITMAPINFOHEADER m_infoHeader;
unsigned int uiTmp, uiTmp2;
unsigned char *ucTmp = NULL;
unsigned char ucRGB;
int i;
uiTmp = (width*3+3)/4*4*height;
uiTmp2 = width*height*3;
//文件标识"BM"(即0x4D42)表示位图
m_fileHeader.bfType = 0x4D42;
//整个文件的大小(单位:字节)
m_fileHeader.bfSize = sizeof(m_fileHeader) + sizeof(m_infoHeader) + uiTmp;
//保留。设置为0
m_fileHeader.bfReserved1 = 0;
//保留。设置为0
m_fileHeader.bfReserved2 = 0;
//从文件开始到位图数据的偏移量(单位:字节)
m_fileHeader.bfOffBits = sizeof(m_fileHeader) + sizeof(m_infoHeader);
//信息头长度(单位:字节)。典型值为28
m_infoHeader.biSize = 0x28;
//位图宽度(单位:像素)
m_infoHeader.biWidth = width;
//位图高度(单位:像素)。若其为正,表示倒向的位图。若为负,表示正向的位图
m_infoHeader.biHeight = height;
//位图的面数(为1)
m_infoHeader.biPlanes = 1;
//每个像素的位数
m_infoHeader.biBitCount = 24;
//压缩说明。0(BI_RGB)表示不压缩
m_infoHeader.biCompression = 0;
//用字节数表示的位图数据的大小(为4的位数)
m_infoHeader.biSizeImage = uiTmp;
//水平分辨率(单位:像素/米)
m_infoHeader.biXPelsPerMeter = 0;
//垂直分辨率(单位:像素/米)
m_infoHeader.biYPelsPerMeter = 0;
//位图使用的颜色数
m_infoHeader.biClrUsed = 0;
//重要的颜色数
m_infoHeader.biClrImportant = 0;
/////////////////////
// Open file
sprintf(szFilename, "frame%d.bmp", iFrame);
pFile=fopen(szFilename, "wb");
if(pFile==NULL)
return;
// Write header
// fprintf(pFile, "P6\n%d %d\n255\n", width, height);
// Write pixel data
fwrite(m_fileHeader, sizeof(m_fileHeader), 1, pFile);
fwrite(m_infoHeader, sizeof(m_infoHeader), 1, pFile);
for(y=height-1; y=0; y--) {
if(ucTmp != NULL) {
delete []ucTmp;
ucTmp = NULL;
}
ucTmp = new unsigned char[width*3];
memcpy(ucTmp, pFrame-data[0]+y*pFrame-linesize[0], width*3);
for(i = 0; i width; i++) {
ucRGB = ucTmp[3*i];
ucTmp[3*i] = ucTmp[3*i+2];
ucTmp[3*i+2] = ucRGB;
}
ucRGB = 0;
fwrite(ucTmp, 1, width*3, pFile);
fwrite(ucRGB, 1, (uiTmp-uiTmp2)/height , pFile);
}
// Close file
fclose(pFile);
}
int main(/*int argc, char *argv[]*/)
{
AVFormatContext *pFormatCtx;
unsigned int i;
int videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVFrame *pFrameRGB;
int numBytes;
uint8_t *buffer;
AVInputFormat *fmt;
char filename[50];
//printf("please input a filename:\n");
// scanf("%s",filename);
strcpy(filename,"chicken.avi");
// Register all formats and codecs
av_register_all();
//avformat_network_init();
//pFormatCtx=av_alloc_format_context();
// fmt = av_find_input_format("flv");
// pFormatCtx-iformat = fmt;
// Open video file
if(av_open_input_file(pFormatCtx,filename, /*fmt*/NULL, 0, NULL)!=0)
return -1; // Couldn't open file
// Retrieve stream information
if(av_find_stream_info(pFormatCtx)0)
return -1; // Couldn't find stream information
// Dump information about file onto standard error
dump_format(pFormatCtx, 0, filename, false);
// Find the first video stream
videoStream=-1;
for(i=0; ipFormatCtx-nb_streams; i++)
if(pFormatCtx-streams[i]-codec-codec_type==CODEC_TYPE_VIDEO)
{
videoStream=i;
break;
}
if(videoStream==-1)
return -1; // Didn't find a video stream
// Get a pointer to the codec context for the video stream
pCodecCtx=pFormatCtx-streams[videoStream]-codec;
// Find the decoder for the video stream
pCodec=avcodec_find_decoder(pCodecCtx-codec_id);
if(pCodec==NULL)
return -1; // Codec not found
// Inform the codec that we can handle truncated bitstreams -- i.e.,
// bitstreams where frame boundaries can fall in the middle of packets
/*
if(pCodec-capabilities CODEC_CAP_TRUNCATED)
pCodecCtx-flags|=CODEC_FLAG_TRUNCATED;*/
// Open codec
if(avcodec_open(pCodecCtx, pCodec)0)
return -1; // Could not open codec
// Hack to correct wrong frame rates that seem to be generated by some
// codecs
/*
if(pCodecCtx-frame_rate1000 pCodecCtx-frame_rate_base==1)
pCodecCtx-frame_rate_base=1000;*/
// Allocate video frame
pFrame=avcodec_alloc_frame();
// Allocate an AVFrame structure
pFrameRGB=avcodec_alloc_frame();
if(pFrameRGB==NULL)
return -1;
// Determine required buffer size and allocate buffer
numBytes=avpicture_get_size(PIX_FMT_RGB24/*PIX_FMT_YUV420P*/, pCodecCtx-width,
pCodecCtx-height);
buffer=(uint8_t*)av_malloc(numBytes*sizeof(uint8_t));
// Assign appropriate parts of buffer to image planes in pFrameRGB
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
pCodecCtx-width, pCodecCtx-height);
// Read frames and save first five frames to disk
i=0;
while(GetNextFrame(pFormatCtx, pCodecCtx, videoStream, pFrame))
{
// img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24, (AVPicture*)pFrame,
// pCodecCtx-pix_fmt, pCodecCtx-width, pCodecCtx-height);
// other codes
static struct SwsContext *img_convert_ctx;
// other codes
img_convert_ctx = sws_getContext(pCodecCtx-width,
pCodecCtx-height,
pCodecCtx-pix_fmt,
pCodecCtx-width,
pCodecCtx-height,
PIX_FMT_RGB24,
SWS_BICUBIC, NULL,
NULL,
NULL);
// other codes
// Convert the image from its native format to RGB
sws_scale(img_convert_ctx,
(const uint8_t* const*)pFrame-data,
pFrame-linesize,
0,
pCodecCtx-height,
pFrameRGB-data,
pFrameRGB-linesize);
// Save the frame to disk
if(++i=512)
SaveFrame(pFrameRGB, pCodecCtx-width, pCodecCtx-height, i);
}
printf("\n%d",i);
// Free the RGB image
// delete [] buffer;
av_free(buffer);
av_free(pFrameRGB);
// Free the YUV frame
av_free(pFrame);
// Close the codec
avcodec_close(pCodecCtx);
// Close the video file
av_close_input_file(pFormatCtx);
return 0;
}
这是网上找的代码,自己修改了一下,可以读取视频,并把视频中的帧转成对应的bmp图片。解码后的视频本来就是yuv格式的,只需要写入到相应的文件就可以了。
这个程序还需要相应的dll,lib和头文件。不过,这样没有办法传给你。
ffmpeg 基本用法
1、libavformat:用于各种音视频封装格式的生成和解析,包括获取解码所需信息以生成解码上下文结构和读取音视频帧等功能,包含demuxers和muxer库;
2、libavcodec:用于各种类型声音/图像编解码;
3、libavutil:包含一些公共的工具函数;
4、libswscale:用于视频场景比例缩放、色彩映射转换;
5、libpostproc:用于后期效果处理;
6、ffmpeg:是一个命令行工具,用来对视频文件转换格式,也支持对电视卡实时编码;
7、ffsever:是一个HTTP多媒体实时广播流服务器,支持时光平移;
8、ffplay:是一个简单的播放器,使用ffmpeg 库解析和解码,通过SDL显示;
在这组成部分中,需要熟悉基础概念有
容器(Container)
容器就是一种文件格式,比如flv,mkv等。包含下面5种流以及文件头信息。
流(Stream)
是一种视频数据信息的传输方式,5种流:音频,视频,字幕,附件,数据。
帧(Frame)
帧代表一幅静止的图像,分为I帧,P帧,B帧。
编解码器(Codec)
是对视频进行压缩或者解压缩,CODEC =COde (编码) +DECode(解码)
复用/解复用(mux/demux)
把不同的流按照某种容器的规则放入容器,这种行为叫做复用(mux)
把不同的流从某种容器中解析出来,这种行为叫做解复用(demux)
1、FFmpeg程序把-i参数指定的若干文件内容读入到内存,按照输入的参数或者程序默认的参数来处理并且把结果写入到若干的文件中。输入和输出文件可以是计算机文件、管道、网络流、捕获设备等。
2、FFmpeg用libavformat包调用解复用器(demuxers)来读取输入文件中被编码的数据包(packets),如果有多个输入文件,FFmpeg以有效输入流的最小时间戳来同步,
3、然后解码器(decoder)从已编码的数据包中产生未被压缩的帧(frame),在那之后调用可选的过滤器。
4、这些帧被传递到编码器,编码器会产生新的编码包
5、把新的编码包传递给复用器(muxer)处理并且把结果写入到输出文件中。
在多媒体处理中,filter的意思是被编码到输出文件之前用来修改输入文件内容的一个软件工具。如:视频翻转,旋转,缩放等。
语法:[input_link_label1]… filter_name=parameters [output_link_label1]…
1、视频过滤器 -vf
如input.mp4视频按顺时针方向旋转90度
ffplay -i input.mp4 -vf transpose=1
如input.mp4视频水平翻转(左右翻转)
ffplay -i input.mp4 -vf hflip
2、音频过滤器 -af
实现慢速播放,声音速度是原始速度的50%
offplay input.mp3 -af atempo=0.5
过滤器链(Filterchain)
Filterchain = 逗号分隔的一组filter
语法:“filter1,filter2,filter3,…filterN-2,filterN-1,filterN”
顺时针旋转90度并水平翻转
ffplay -i input.mp4 -vf transpose=1,hflip
过滤器图(Filtergraph)
第一步: 源视频宽度扩大两倍。
ffmpeg -i jidu.mp4 -t 10 -vf pad=2*iw output.mp4
第二步:源视频水平翻转
ffmpeg -i jidu.mp4 -t 10 -vf hflip output2.mp4
第三步:水平翻转视频覆盖output.mp4
ffmpeg -i output.mp4 -i output2.mp4 -filter_complex overlay=w compare.mp4
是不是很复杂?
用带有链接标记的过滤器图(Filtergraph)只需一条命令
基本语法
Filtergraph = 分号分隔的一组filterchain
“filterchain1;filterchain2;…filterchainN-1;filterchainN”
Filtergraph的分类
1、简单(simple) 一对一
2、复杂(complex)多对一, 多对多
简单过滤器图处理流程:
复杂过滤器图处理流程:
对于刚才用三步处理的方式,用过滤器图可以这样做:
ffplay -f lavfi -i testsrc -vf split[a][b];[a]pad=2*iw[1];[b]hflip[2];[1][2]overlay=w
F1: split过滤器创建两个输入文件的拷贝并标记为[a],[b]
F2: [a]作为pad过滤器的输入,pad过滤器产生2倍宽度并输出到[1].
F3: [b]作为hflip过滤器的输入,vflip过滤器水平翻转视频并输出到[2].
F4: 用overlay过滤器把 [2]覆盖到[1]的旁边.
一些多媒体容器比如AVI,mkv,mp4等,可以包含不同种类的多个流,如何从容器中抽取各种流呢?
语法:
-map file_number[:stream_type][:stream_number]
这有一些特别流符号的说明:
1、-map 0 选择第一个文件的所有流
2、-map i:v 从文件序号i(index)中获取所有视频流, -map i:a 获取所有音频流,-map i:s 获取所有字幕流等等。
3、特殊参数-an,-vn,-sn分别排除所有的音频,视频,字幕流
tip:对比上面的图,可以知道,假设有两个文件ffmpeg -i fist.mp4 -i second.mp4 ..output.mp4
如果想去两个文件的音视频流 ffmpeg -i fist.mp4 -i second.mp4 map:0 -map 1 output.mp4
如果想去第一个文件的视频流,第二个文件的音频流ffmpeg -i fist.mp4 -i second.mp4 -map:v:0 -map:a:0 output.mp4
可用的bit流 :ffmpeg –bsfs
可用的编解码器:ffmpeg –codecs
可用的解码器:ffmpeg –decoders
可用的编码器:ffmpeg –encoders
可用的过滤器:ffmpeg –filters
可用的视频格式:ffmpeg –formats
可用的声道布局:ffmpeg –layouts
可用的license:ffmpeg –L
可用的像素格式:ffmpeg –pix_fmts
可用的协议:ffmpeg -protocals
码率和帧率是视频文件的最重要的基本特征,对于他们的特有设置会决定视频质量。如果我们知道码率和时长那么可以很容易计算出输出文件的大小。
帧率:帧率也叫帧频率,帧率是视频文件中每一秒的帧数,肉眼想看到连续移动图像至少需要15帧。
码率:比特率(也叫码率,数据率)是一个确定整体视频/音频质量的参数,秒为单位处理的字节数,码率和视频质量成正比,在视频文件中中比特率用bps来表达。
设置帧率
1、用 -r 参数设置帧率
ffmpeg –i input.mp4 –r fps output.mp4
2、用fps filter设置帧率
ffmpeg -i clip.mpg -vf fps=fps=25 clip.webm
设置码率 –b 参数
-b
ffmpeg -i film.avi -b 1.5M film.mp4
音频:-b:a 视频: - b:v
设置视频码率为1500kbps
ffmpeg -i input.avi -b:v 1500k output.mp4
控制输出文件大小
-fs (file size首字母缩写)
ffmpeg -i input.avi -fs 1024K output.mp4
计算输出文件大小
(视频码率+音频码率) * 时长 /8 = 文件大小K
用-s参数设置视频分辨率,参数值wxh,w宽度单位是像素,h高度单位是像素
ffmpeg -i input_file -s 320x240 output_file
2、预定义的视频尺寸
下面两条命令有相同效果
ffmpeg -i input.avi -s 640x480 output.avi
ffmpeg -i input.avi -s vga output.avi
下表列出了所有的预定义尺寸
Scale filter调整分辨率
Scale filter的优点是可以使用一些额外的参数
语法:
Scale=width:height[:interl={1|-1}]
下表列出了常用的额外参数
下面两条命令有相同效果
ffmpeg -i input.mpg -s 320x240 output.mp4
ffmpeg -i input.mpg -vf scale=320:240 output.mp4
对输入视频成比例缩放
改变为源视频一半大小
ffmpeg -i input.mpg -vf scale=iw/2:ih/2 output.mp4
改变为原视频的90%大小:
ffmpeg -i input.mpg -vf scale=iw 0.9:ih 0.9 output.mp4
在未知视频的分辨率时,保证调整的分辨率与源视频有相同的横纵比。
宽度固定400,高度成比例:
ffmpeg -i input.avi -vf scale=400:400/a
ffmpeg -i input.avi -vf scale=400:-1
相反地,高度固定300,宽度成比例:
ffmpeg -i input.avi -vf scale=-1:300
ffmpeg -i input.avi -vf scale=300*a:300
从输入文件中选取你想要的矩形区域到输出文件中,常见用来去视频黑边。
语法:crop:ow[:oh[:x[:y:[:keep_aspect]]]]
裁剪输入视频的左三分之一,中间三分之一,右三分之一:
ffmpeg -i input -vf crop=iw/3:ih :0:0 output
ffmpeg -i input -vf crop=iw/3:ih :iw/3:0 output
ffmpeg -i input -vf crop=iw/3:ih :iw/3*2:0 output
裁剪帧的中心
当我们想裁剪区域在帧的中间时,裁剪filter可以跳过输入x和y值,他们的默认值是
Xdefault = ( input width - output width)/2
Ydefault = ( input height - output height)/2
ffmpeg -i input_file -v crop=w:h output_file
裁剪中间一半区域:
ffmpeg -i input.avi -vf crop=iw/2:ih/2 output.avi
比较裁剪后的视频和源视频比较
ffplay -i jidu.mp4 -vf split[a][b];[a]drawbox=x=(iw-300)/2:(ih-300)/2:w=300:h=300:c=yellow[A];[A]pad=2 iw[C];[b]crop=300:300:(iw-300)/2:(ih-300)/2[B];[C][B]overlay=w 2.4:40
自动检测裁剪区域�
cropdetect filter 自动检测黑边区域
ffplay jidu.mp4 -vf cropdetect
填充视频(pad)
在视频帧上增加一快额外额区域,经常用在播放的时候显示不同的横纵比
语法:pad=width[:height:[:x[:y:[:color]]]]
创建一个30个像素的粉色宽度来包围一个SVGA尺寸的图片:
ffmpeg -i photo.jpg -vf pad=860:660:30:30:pink framed_photo.jpg
同理可以制作input.mp4视频用30个像素粉色包围视频
ffplay -i input.mp4 -vf pad=iw+60:ih+60:30:30:pink
4:3到16:9
一些设备只能播放16:9的横纵比,4:3的横纵比必须在水平方向的两边填充成16:9,
高度被保持,宽度等于高度乘以16/9,x(输入文件水平位移)值由表达式(output_width - input_width)/2来计算。
4:3到16:9的通用命令是:
ffmpeg -i input.mp4 -vf pad=ih 16/9:ih :(ow-iw)/2:0:color output.mp4
eg:ffplay -f input.mp4 -vf pad=ih 16/9:ih:(ow-iw)/2:0:pink
16:9到4:3
为了用4:3的横纵比来显示16:9的横纵比,填充输入文件的垂直两边,宽度保持不变,高度是宽度的3/4,y值(输入文件的垂直偏移量)是由一个表达式(output_height-input_height)/2计算出来的。
16:9到4:3的通用命令:
ffmpeg -i input.mp4-vf pad=iw :iw 3/4:0:(oh-ih)/2:color output.mp4
eg:ffplay -i input.mp4 =size=320x180 -vf pad=iw:iw 3/4:0:(oh-ih)/2:pink
水平翻转语法: -vf hflip
ffplay -f lavfi -i testsrc -vf hflip
垂直翻转语法:-vf vflip
ffplay -f lavfi -i testsrc -vf vflip
语法:transpose={0,1,2,3}
0:逆时针旋转90°然后垂直翻转
1:顺时针旋转90°
2:逆时针旋转90°
3:顺时针旋转90°然后水平翻转
模糊
语法:boxblur=luma_r:luma_p[:chroma_r:chram_p[:alpha_r:alpha_p]]
ffplay -f lavfi -i testsrc -vf boxblur=1:10:4:10
注意:luma_r和alpha_r半径取值范围是0~min(w,h)/2, chroma_r半径的取值范围是0~min(cw/ch)/2
锐化
语法:-vf unsharp=l_msize_x:l_msize_y:l_amount:c_msize_x:c_msize_y:c_amount
所有的参数是可选的,默认值是5:5:1.0:5:5:0.0
l_msize_x:水平亮度矩阵,取值范围3-13,默认值为5
l_msize_y:垂直亮度矩阵,取值范围3-13,默认值为5
l_amount:亮度强度,取值范围-2.0-5.0,负数为模糊效果,默认值1.0
c_msize_x:水平色彩矩阵,取值范围3-13,默认值5
c_msize_y:垂直色彩矩阵,取值范围3-13,默认值5
c_amount:色彩强度,取值范围-2.0-5.0,负数为模糊效果,默认值0.0
eg:
使用默认值,亮度矩阵为5x5和亮度值为1.0
ffmpeg -i input.mp4 -vf unsharp output.mp4
高斯模糊效果(比较强的模糊):
ffplay -i input.mp4 -vf unsharp=13:13:-2
语法:overlay[=x[:y]
所有的参数都是可选,默认值都是0
Logo在左上角
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay output.mp4
右上角:
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=W-w output.mp4
左下角:
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=0:H-h output.mp4
右下角:
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=W-w:H-h output.mp4
删除logo
语法:-vf delogo=x:y:w:h[:t[:show]]
x:y 离左上角的坐标
w:h logo的宽和高
t: 矩形边缘的厚度默认值4
show:若设置为1有一个绿色的矩形,默认值0.
ffplay -i jidu.mp4 -vf delogo=50:51:60:60:100:0
语法:
drawtext=fontfile=font_f:text=text1[:p3=v3[:p4=v4[…]]]
常用的参数值
x:离左上角的横坐标
y: 离左上角的纵坐标
fontcolor:字体颜色
fontsize:字体大小
text:文本内容
textfile:文本文件
t:时间戳,单位秒
n:帧数开始位置为0
draw/enable:控制文件显示,若值为0不显示,1显示,可以使用函数
1、在左上角添加Welcome文字
ffplay -i color=c=white -vf drawtext=fontfile=arial.ttf:text=Welcom
2、在中央添加Good day
ffplay -i color=c=white -vf drawtext="fontfile=arial.ttf:text='Goodday':x=(w-tw)/2:y=(h-th)/2"
3、设置字体颜色和大小
ffplay -i color=c=white -vf drawtext="fontfile=arial.ttf:text='Happy Holidays':x=(w-tw)/2:y=(h-th)/2:fontcolor=green:fontsize=30"
动态文本
用 t (时间秒)变量实现动态文本
1、顶部水平滚动
ffplay -i jidu.mp4 -vf drawtext="fontfile=arial.ttf:text='Dynamic RTL text':x=w-t 50:fontcolor=darkorange:fontsize=30"
2、底部水平滚动
ffplay -i jidu.mp4 -vf drawtext="fontfile=arial.ttf:textfile=textfile.txt:x=w-t 50:y=h-th:fontcolor=darkorange:fontsize=30"
3、垂直从下往上滚动
ffplay jidu.mp4 -vf drawtext="textfile=textfile:fontfile=arial.ttf:x=(w-tw)/2:y=h-t*100:fontcolor=white:fontsize=30“
在右上角显示当前时间 localtime
ffplay jidu.mp4 -vf drawtext="fontfile=arial.ttf:x=w-tw:fontcolor=white:fontsize=30:text='%{localtime:%H\:%M\:%S}'“
每隔3秒显示一次当前时间
ffplay jidu.mp4 -vf drawtext="fontfile=arial.ttf:x=w-tw:fontcolor=white:fontsize=30:text='%{localtime:%H\:%M\:%S}':enable=lt(mod(t,3),1)"
FFmpeg支持绝大多数图片处理, 除LJPEG(无损JPEG)之外,其他都能被解码,除了EXR,PIC,PTX之外,所有的都能被编码。
截取一张图片使用 –ss(seek from start)参数.
ffmpeg -ss 01:23:45 -i jidu.mp4 image.jpg
从视频中生成GIF图片
ffmpeg -i jidu.mp4 -t 10 -pix_fmt rgb24 jidu.gif
转换视频为图片(每帧一张图)
ffmpeg -i clip.avi frame%4d.jpg
图片转换为视频
ffmpeg -f image2 -i img%4d.jpg -r 25 video.mp4
和视频一样,图片也可以被裁剪和填充
裁剪
ffmpeg -f lavfi -i rgbtestsrc -vf crop=150:150 crop_rg.png
填充
ffmpeg -f lavfi -i smptebars -vf pad=360:280:20:20:orange pad_smpte.jpg
和视频一样图片同样能翻转,旋转和覆盖
翻转
ffmpeg -i orange.jpg -vf hflip orange_hfilp.jpg
ffmpeg -i orange.jpg -vf vflip orange_vfilp.jpg
旋转
ffmpeg -i -vf transpose=1 image_rotated.png
覆盖
ffmpeg -f lavfi -i rgbtestsrc -s 400x300 rgb .png
ffmpeg -f lavfi -i smptebars smpte.png
ffmpeg -i rgb .png -i smpte.png -filter_complex overlay= (W-w)/2:(H-h)/2 rgb_smpte.png
屏幕录像
显示设备名称
ffmpeg -list_devices 1 -f dshow -i dummy
调用摄像头
ffplay -f dshow -i video="Integrated Camera"
保存为文件
ffmpeg -y -f dshow -s 320x240 -r 25 -i video="Integrated Camera" -b:v 800K -vcodec mpeg4 new.mp4
添加字幕subtitles
语法 –vf subtitles=file
ffmpeg -i jidu.mp4 -vf subtitles=rgb.srt output.mp4
视频颤抖、色彩平衡
视频颤抖
ffplay –i jidu.mp4 -vf crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2) sin(n/10):(in_h-out_h)/2 +((in_h-out_h)/2) sin(n/7)
色彩平衡
ffplay -i jidu.mp4 -vf curves=vintage
色彩变幻
ffplay -i jidu.mp4 -vf hue="H=2 PI t: s=sin(2 PI t)+1“
彩色转换黑白
ffplay -i jidu.mp4 -vf lutyuv="u=128:v=128"
设置音频视频播放速度
3倍视频播放视频
ffplay -i jidu.mp4 -vf setpts=PTS/3
¾速度播放视频
ffplay -i jidu.mp4 -vf setpts=PTS/(3/4)
2倍速度播放音频
ffplay -i speech.mp3 -af atempo=2
截图
每隔一秒截一张图
ffmpeg -i input.flv -f image2 -vf fps=fps=1 out%d.png
每隔20秒截一张图
ffmpeg -i input.flv -f image2 -vf fps=fps=1/20 out%d.png
注意:ffmpeg version N-57961-gec8e68c版本最多可以每隔20s截一张图。
多张截图合并到一个文件里(2x3) 每隔一千帧(秒数=1000/fps25)即40s截一张图
ffmpeg -i jidu.mp4 -frames 3 -vf "select=not(mod(n,1000)),scale=320:240,tile=2x3" out.png
本篇文章主要记录ffmpeg的一些基础指令操作,该资料的来源是源于网上的一个ppt文档,感谢文档的总结。
ffmpeg视频转换代码的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于ffmpeg 视频转换、ffmpeg视频转换代码的信息别忘了在本站进行查找喔。
版权说明:如非注明,本站文章均为 AH站长 原创,转载请注明出处和附带本文链接;
- 上一篇:渔代码(渔船编码查询)
- 下一篇:物流查询源代码(物流公司代码查询)
相关推荐
- 05-19怎么做网站,怎么做网站教程视频
- 05-18短视频seo搜索优化,免费观看短视频的软件
- 05-18短视频营销推广方案,短视频营销推广方案模板
- 05-18b站视频推广网站400,b站视频推广有用吗
- 05-17短视频搜索seo,短视频搜索恐龙电影
- 05-15seo完整教程视频教程,seo教学视频教程
- 05-12网站是怎么建立起来的,网站是怎么建立起来的视频
- 05-12今日大新闻,今日大新闻视频大理
- 05-11大地seo,大地视频
- 05-09网页代码,网页代码快捷键
取消回复欢迎 你 发表评论:
- 标签列表
- 最近发表
- 友情链接