输入文件的相关参数
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Text;
namespace FFmpegLib
{
/// <summary>
/// 输入文件的相关参数
/// </summary>
public class FFmpegInFileParamsBuilder : FFmpegFileParamsBuilder
{
/// <summary>
/// 源文件地址
/// </summary>
private readonly string src;
/// <summary>
/// 对指定的文件进行参数构建
/// </summary>
/// <param name="src"></param>
public FFmpegInFileParamsBuilder(string src)
{
if (string.IsNullOrWhiteSpace(src)) throw new ArgumentNullException(nameof(src));
this.src = src;
}
/// <summary>
/// 获取当前设置的所有参数
/// </summary>
/// <returns></returns>
public string GetParam()
{
return $"{fileOptions}-i \"{src}\" ";
}
}
/// <summary>
/// 输出文件的参数
/// </summary>
public class FFmpegOutFileParamsBuilder : FFmpegFileParamsBuilder
{
/// <summary>
/// 源文件地址
/// </summary>
private readonly string outfile;
/// <summary>
/// 对指定的文件进行参数构建
/// </summary>
/// <param name="outfile"></param>
public FFmpegOutFileParamsBuilder(string outfiles)
{
if (string.IsNullOrWhiteSpace(outfile)) throw new ArgumentNullException(nameof(outfile));
this.outfile = outfiles;
}
/// <summary>
/// 获取当前设置的所有参数
/// </summary>
/// <returns></returns>
public string GetParam()
{
return $"{fileOptions} \"{outfile}\" ";
}
}
/// <summary>
/// 输入文件的参数
/// </summary>
public abstract class FFmpegFileParamsBuilder
{
/// <summary>
/// 输入文件的选项
/// </summary>
protected readonly StringBuilder fileOptions = new StringBuilder();
/// <summary>
/// 设置允许的扩展名?
/// </summary>
/// <param name="ext"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetAllowExtensions(string ext)
{
fileOptions.Append($"-allowed_extensions {ext} ");
return this;
}
/// <summary>
/// 设置画质?
/// </summary>
/// <param name="level"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetQVLevel(int level)
{
fileOptions.Append($"-q:v {level} ");
return this;
}
/// <summary>
/// 强制设置输入的格式
/// </summary>
/// <param name="fmt"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetFormats(string fmt)
{
fileOptions.Append($"-f {fmt} ");
return this;
}
/// <summary>
/// 设置编码的名称
/// </summary>
/// <param name="cd"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetCodecShorta(string cd)
{
fileOptions.Append($"-c {cd} ");
return this;
}
/// <summary>
/// 设置编码的名称
/// </summary>
/// <param name="cd"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetCode(string cd)
{
fileOptions.Append($"-codec {cd} ");
return this;
}
/// <summary>
/// 预设的名称?用于输出文件?
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetPre(string name)
{
fileOptions.Append($"-pre {name} ");
return this;
}
/// <summary>
/// 设置持续时间
/// </summary>
/// <param name="t">单位秒</param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetDurationTim(double t)
{
fileOptions.Append($"-t {t} ");
return this;
}
/// <summary>
/// 停止于指定的时间?
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetStop(TimeSpan t)
{
fileOptions.Append($"-to {t} ");
return this;
}
/// <summary>
/// 设置文件的最小值
/// </summary>
/// <param name="len"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetLimitSizes(uint len)
{
fileOptions.Append($"-fs {len} ");
return this;
}
/// <summary>
/// 指定起始的时间偏移
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetTimeOffects(TimeSpan t)
{
fileOptions.Append($"-ss {t:hh\\:mm\\:ss\\.ff} ");
return this;
}
/// <summary>
/// 反方向的从文件尾设置其实偏移
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetTimeOffectFrom(TimeSpan t)
{
fileOptions.Append($"-sseof {t:hh\\:mm\\:ss\\.ff} ");
return this;
}
/// <summary>
/// 设置启用偏移设置
/// </summary>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileEnableSeekTimes()
{
fileOptions.Append($"-seek_timestamp ");
return this;
}
/// <summary>
/// 设置录制之类的时候的起始时间,now表示从现在开始
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetTimes(string t)
{
fileOptions.Append($"-timestamp {t} ");
return this;
}
/// <summary>
/// 指定类型,
/// specify target file type ("vcd", "svcd", "dvd", "dv" or "dv50" with optional prefixes "pal-", "ntsc-" or "film-")
/// </summary>
/// <param name="tp"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetTargetType(string tp)
{
fileOptions.Append($"-target {tp} ");
return this;
}
/// <summary>
/// audio pad??
/// </summary>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileEnableAudioPad()
{
fileOptions.Append($"-apad ");
return this;
}
/// <summary>
/// 指定要输出的帧数
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileSetFramesCount(uint c)
{
fileOptions.Append($"-frames {c} ");
return this;
}
/// <summary>
/// 丢弃?
/// </summary>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileEnableDiscard()
{
fileOptions.Append($"-discard ");
return this;
}
/// <summary>
/// 使用处置参数?
/// </summary>
/// <returns></returns>
public FFmpegFileParamsBuilder PerFileEnableDisposition()
{
fileOptions.Append($"-disposition ");
return this;
}
/// <summary>
/// 指定输出count个帧
/// </summary>
/// <param name="count"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder VideoSetFramesToOutput(uint count)
{
fileOptions.Append($"-vframes {count} ");
return this;
}
/// <summary>
/// 指定帧率
/// </summary>
/// <param name="rate"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder VideoSetRate(uint rate)
{
fileOptions.Append($"-r {rate} ");
return this;
}
/// <summary>
/// 设置视频的宽高
/// </summary>
/// <param name="w"></param>
/// <param name="h"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder VideoSetSize(uint w, uint h)
{
fileOptions.Append($"-s {w}x{h} ");
return this;
}
/// <summary>
/// 设置视频宽高比
/// </summary>
/// <param name="w"></param>
/// <param name="h"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder VideoSetAspect(uint w, uint h)
{
fileOptions.Append($"-aspect {w}:{h} ");
return this;
}
/// <summary>
/// 设置视频码率
/// </summary>
/// <param name="sample"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder VideoSetBitPerRawSample(uint sample)
{
fileOptions.Append($"-bits_per_raw_sample {sample} ");
return this;
}
/// <summary>
/// 禁用视频
/// </summary>
/// <returns></returns>
public FFmpegFileParamsBuilder VideoDisable()
{
fileOptions.Append($"-vn ");
return this;
}
/// <summary>
/// 设置视频的处理方式,比如copy
/// </summary>
/// <param name="codec"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder VideoSetCodec(string cdc)
{
fileOptions.Append($"-vcodec {cdc} ");
return this;
}
/// <summary>
/// 设置时间code
/// </summary>
/// <param name="tm"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder VideoSetTimeCode(TimeSpan tm)
{
fileOptions.Append($"-timecode {tm:hh\\:mm\\:ss\\.ff} ");
return this;
}
/// <summary>
/// 设置pass
/// </summary>
/// <param name="pass"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder VideoSetPass(uint pass)
{
fileOptions.Append($"-pass {pass} ");
return this;
}
/// <summary>
/// 设置视频筛选?
/// </summary>
/// <param name="fs"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder VideoSetFilters(string fs)
{
fileOptions.Append($"-vf {fs} ");
return this;
}
/// <summary>
/// 禁用数据?
/// </summary>
/// <returns></returns>
public FFmpegFileParamsBuilder VideoDisableData()
{
fileOptions.Append($"-dn ");
return this;
}
/// <summary>
/// 设置输出的音频的帧数
/// </summary>
/// <param name="cnt"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder AudioSetFramesCount(uint cnt)
{
fileOptions.Append($"-aframes {cnt} ");
return this;
}
/// <summary>
/// 设置音频编码格式?
/// </summary>
/// <param name="q"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder AudioSetQuality(string q)
{
fileOptions.Append($"-aq {q} ");
return this;
}
/// <summary>
/// 设置采样率
/// </summary>
/// <param name="rote">单位hz</param>
/// <returns></returns>
public FFmpegFileParamsBuilder AudioSetSampleRate(uint rate)
{
fileOptions.Append($"-ar {rate} ");
return this;
}
/// <summary>
/// 设置通道数
/// </summary>
/// <param name="cnt"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder AudioSetChannelCount(uint cnt)
{
fileOptions.Append($"-ac {cnt} ");
return this;
}
/// <summary>
/// 禁用音频
/// </summary>
/// <returns></returns>
public FFmpegFileParamsBuilder AudioDisable()
{
fileOptions.Append($"-an ");
return this;
}
/// <summary>
/// 设置音频编码方式,比如copy
/// </summary>
/// <param name="ct"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder AudioSetCodeType(string ct)
{
fileOptions.Append($"-acodec {ct} ");
return this;
}
/// <summary>
/// 设置音量
/// </summary>
/// <param name="vol"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder AudioSetVolume(uint vol)
{
fileOptions.Append($"-vol {vol} ");
return this;
}
/// <summary>
/// 设置音频过滤?
/// </summary>
/// <param name="fs"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder AudioSetFilters(string fs)
{
fileOptions.Append($"-af {fs} ");
return this;
}
/// <summary>
/// 设置字幕大小
/// </summary>
/// <param name="w"></param>
/// <param name="h"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder SubtitleSetSize(uint w, uint h)
{
fileOptions.Append($"-s {w}x{h} ");
return this;
}
/// <summary>
/// 禁用字幕
/// </summary>
/// <returns></returns>
public FFmpegFileParamsBuilder SubtitleDisable()
{
fileOptions.Append($"-sn ");
return this;
}
/// <summary>
/// 字幕的处理方式,比如copy
/// </summary>
/// <param name="cd"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder SubtitleSetCodec(string cd)
{
fileOptions.Append($"-scodec {cd} ");
return this;
}
/// <summary>
/// 字幕的tag?
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder SubtitleSetTag(string tag)
{
fileOptions.Append($"-stag {tag} ");
return this;
}
/// <summary>
/// 设置固定字幕的持续时间
/// </summary>
/// <returns></returns>
public FFmpegFileParamsBuilder SubtitleSetFixSubDuration()
{
fileOptions.Append($"-fix_sub_duration ");
return this;
}
/// <summary>
/// 设置字幕的框的大小
/// </summary>
/// <param name="w"></param>
/// <param name="h"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder SubtitleSetCanvasSize(uint w, uint h)
{
fileOptions.Append($"-canvas_size {w}x{h} ");
return this;
}
/// <summary>
/// 字幕设置为指定的预设值
/// </summary>
/// <param name="preset"></param>
/// <returns></returns>
public FFmpegFileParamsBuilder SubtitleSetToPreset(string preset)
{
fileOptions.Append($"-spre {preset} ");
return this;
}
}
/// <summary>
/// ffmpeg的参数构建器
/// 参考:https://ffmpeg.xianwaizhiyin.net/base-ffmpeg/ffmpeg-cmd-type.html
/// </summary>
public class FFmpegParamsBuilder
{
/// <summary>
/// 全局的选项
/// </summary>
private readonly StringBuilder globalOptions = new StringBuilder();
/// <summary>
/// 输入文件的选项
/// </summary>
private readonly FFmpegInFileParamsBuilder[] infiles;
/// <summary>
/// 输出文件的选项
/// </summary>
private readonly FFmpegOutFileParamsBuilder outfile;
/// <summary>
/// 创建多个输入文件的参数构建器
/// </summary>
/// <param name="src"></param>
/// <param name="outfile"></param>
public FFmpegParamsBuilder(FFmpegInFileParamsBuilder[] inps, FFmpegOutFileParamsBuilder outfile)
{
this.infiles = inps ?? throw new ArgumentNullException(nameof(inps));
this.outfile = outfile ?? throw new ArgumentNullException(nameof(outfile));
}
/// <summary>
/// 创建单个输入文件的构建器
/// </summary>
/// <param name="inp"></param>
/// <param name="outfile"></param>
/// <exception cref="ArgumentNullException"></exception>
public FFmpegParamsBuilder(FFmpegInFileParamsBuilder inp, FFmpegOutFileParamsBuilder outfile)
{
this.infiles = new[] { inp ?? throw new ArgumentNullException(nameof(inp)) };
this.outfile = outfile ?? throw new ArgumentNullException(nameof(outfile));
}
/// <summary>
/// 设置log等级
/// </summary>
/// <param name="level"></param>
/// <returns></returns>
public FFmpegParamsBuilder GlobalSetLogLevel(string level)
{
globalOptions.Append($"-loglevel {level} ");
return this;
}
/// <summary>
/// 设置log等级
/// </summary>
/// <param name="level"></param>
/// <returns></returns>
public FFmpegParamsBuilder GlobalSetLogLevelv(string level)
{
globalOptions.Append($"-v {level} ");
return this;
}
/// <summary>
/// 将会生成报告
/// </summary>
/// <returns></returns>
public FFmpegParamsBuilder GlobalEnableOutReport()
{
globalOptions.Append($"-report ");
return this;
}
/// <summary>
/// 设置单个快申请的最大块大小
/// </summary>
/// <param name="ma"></param>
/// <returns></returns>
public FFmpegParamsBuilder GlobalSetMaxAlloc(uint ma)
{
globalOptions.Append($"-max_alloc {ma} ");
return this;
}
/// <summary>
/// 将会覆盖输出文件
/// </summary>
/// <returns></returns>
public FFmpegParamsBuilder GlobalEnableOverWrite()
{
globalOptions.Append($"-y ");
return this;
}
/// <summary>
/// 禁止覆盖输出文件
/// </summary>
/// <returns></returns>
public FFmpegParamsBuilder GlobalEnableNeverOverWrite()
{
globalOptions.Append($"-n ");
return this;
}
/// <summary>
/// 忽略未知流类型
/// </summary>
/// <returns></returns>
public FFmpegParamsBuilder GlobalIgnoreUnknown()
{
globalOptions.Append($"-ignore_unknown ");
return this;
}
/// <summary>
/// 非复杂筛选器线程数
/// </summary>
/// <returns></returns>
public FFmpegParamsBuilder GlobalEnableFilterThreads()
{
globalOptions.Append($"-filter_threads ");
return this;
}
/// <summary>
/// number of threads for -filter_complex
/// 启用指定个线程?
/// </summary>
/// <returns></returns>
public FFmpegParamsBuilder GlobalEnableFilterComplexThreads()
{
globalOptions.Append($"-filter_complex_threads ");
return this;
}
/// <summary>
/// 开启打印状态
/// </summary>
/// <returns></returns>
public FFmpegParamsBuilder GlobalEnablePrintStats()
{
globalOptions.Append($"-stats ");//-progress
return this;
}
/// <summary>
/// 设置输出进度的文件路径
/// </summary>
/// <returns></returns>
public FFmpegParamsBuilder GlobalSetProgressOutPath(string path)
{
globalOptions.Append($"-progress {path} ");
return this;
}
/// <summary>
/// 音频中设置采样位数8,16,24,32
/// </summary>
/// <param name="rs"></param>
/// <returns></returns>
public FFmpegParamsBuilder GlobalSetBitsPerRawSample(uint rs)
{
globalOptions.Append($"-bits_per_raw_sample {rs} ");
return this;
}
/// <summary>
/// 设置音频的音量
/// </summary>
/// <param name="vol"></param>
/// <returns></returns>
public FFmpegParamsBuilder GlobalSetVolume(uint vol)
{
globalOptions.Append($"-vol {vol} ");
return this;
}
/// <summary>
/// 获取当前设置的所有参数
/// </summary>
/// <returns></returns>
public string GetParam()
{
var inps = new StringBuilder();
foreach (var v in infiles) inps.Append(v.GetParam());
return $" {inps} {outfile.GetParam()} {globalOptions}";
}
}
}