Update README.md

Former-commit-id: 4a9ae3d2f8
This commit is contained in:
Malte Rosenbjerg 2020-05-24 19:28:00 +02:00
parent 82d401b1cf
commit da527f128b

504
README.md
View file

@ -10,11 +10,141 @@
Install-Package FFMpegCore
```
A great way to use FFMpeg encoding when writing video applications, client-side and server-side. It has wrapper methods that allow conversion to all web formats: MP4, OGV, TS and methods of capturing screens from the videos.
A great way to use FFMpeg encoding when writing video applications, client-side and server-side. It has wrapper methods that allow conversion to popular web formats, such as Mp4, WebM, Ogv, TS, and methods for capturing screenshots from videos, among other.
# API
## FFProbe
FFProbe is used to gather media information:
```csharp
var mediaInfo = FFProbe.Analyse(inputFile);
```
or
```csharp
var mediaInfo = await FFProbe.AnalyseAsync(inputFile);
```
## FFMpeg
FFMpeg is used for converting your media files to web ready formats.
Easily build your FFMpeg arguments using the fluent argument builder:
Convert input file to h264/aac scaled to 720p w/ faststart, for web playback
```csharp
FFMpegArguments
.FromInputFiles(inputFilePath)
.WithVideoCodec(VideoCodec.LibX264)
.WithConstantRateFactor(21)
.WithAudioCodec(AudioCodec.Aac)
.WithVariableBitrate(4)
.WithFastStart()
.Scale(VideoSize.Hd)
.OutputToFile(output)
.ProcessSynchronously(),
```
Easily capture screens from your videos:
```csharp
var mediaFileAnalysis = FFProbe.Analyse(inputFilePath);
// process the snapshot in-memory and use the Bitmap directly
var bitmap = FFMpeg.Snapshot(mediaFileAnalysis, new Size(200, 400), TimeSpan.FromMinutes(1));
// or persists the image on the drive
FFMpeg.Snapshot(mediaFileAnalysis, outputPath, new Size(200, 400), TimeSpan.FromMinutes(1))
```
Convert to and/or from streams
```csharp
await FFMpegArguments
.FromPipe(new StreamPipeDataWriter(inputStream))
.WithVideoCodec("vp9")
.ForceFormat("webm")
.OutputToPipe(new StreamPipeDataReader(outputStream))
.ProcessAsynchronously();
```
Join video parts into one single file:
```csharp
FFMpeg.Join(@"..\joined_video.mp4",
@"..\part1.mp4",
@"..\part2.mp4",
@"..\part3.mp4"
);
```
Join images into a video:
```csharp
FFMpeg.JoinImageSequence(@"..\joined_video.mp4", frameRate: 1,
ImageInfo.FromPath(@"..\1.png"),
ImageInfo.FromPath(@"..\2.png"),
ImageInfo.FromPath(@"..\3.png")
);
```
Mute videos:
```csharp
FFMpeg.Mute(inputFilePath, outputFilePath);
```
Save audio track from video:
```csharp
FFMpeg.ExtractAudio(inputVideoFilePath, outputAudioFilePath);
```
Add or replace audio track on video:
```csharp
FFMpeg.ReplaceAudio(inputVideoFilePath, inputAudioFilePath, outputVideoFilePath);
```
Add poster image to audio file (good for youtube videos):
```csharp
FFMpeg.PosterWithAudio(inputImageFilePath, inputAudioFilePath, outputVideoFilePath);
// or
var image = Image.FromFile(inputImageFile);
image.AddAudio(inputAudioFilePath, outputVideoFilePath);
```
Other available arguments could be found in `FFMpegCore.Arguments` namespace.
### Input piping
With input piping it is possible to write video frames directly from program memory without saving them to jpeg or png and then passing path to input of ffmpeg. This feature also allows us to convert video on-the-fly while frames are being generated or received.
The `IPipeSource` interface is used as the source of data. It could be represented as encoded video stream or raw frames stream. Currently, the `IPipeSource` interface has single implementation, `RawVideoPipeSource` that is used for raw stream encoding.
For example:
Method that is generating bitmap frames:
```csharp
IEnumerable<IVideoFrame> CreateFrames(int count)
{
for(int i = 0; i < count; i++)
{
yield return GetNextFrame(); //method of generating new frames
}
}
```
Then create `ArgumentsContainer` with `InputPipeArgument`
```csharp
var videoFramesSource = new RawVideoPipeSource(CreateFrames(64)) //pass IEnumerable<IVideoFrame> or IEnumerator<IVideoFrame> to constructor of RawVideoPipeSource
{
FrameRate = 30 //set source frame rate
};
FFMpegArguments
.FromPipe(videoFramesSource)
// ... other encoding arguments
.OutputToFile("temporary.mp4")
.ProcessSynchronously();
```
if you want to use `System.Drawing.Bitmap` as `IVideoFrame`, there is a `BitmapVideoFrameWrapper` wrapper class.
## Binaries
If you prefer to manually download them, visit [ffbinaries](https://ffbinaries.com/downloads).
If you prefer to manually download them, visit [ffbinaries](https://ffbinaries.com/downloads) or [zeranoe Windows builds](https://ffmpeg.zeranoe.com/builds/).
#### Windows
@ -52,379 +182,24 @@ The default value (`\\FFMPEG\\bin`) can be overwritten via the `FFMpegOptions` c
```c#
public Startup()
{
FFMpegOptions.Configure(new FFMpegOptions { RootDirectory = "./bin" });
FFMpegOptions.Configure(new FFMpegOptions { RootDirectory = "./bin", TempDirectory = "/tmp" });
}
```
#### Option 2
The root directory for the ffmpeg binaries can be configured via the `ffmpeg.config.json` file.
The root and temp directory for the ffmpeg binaries can be configured via the `ffmpeg.config.json` file.
```json
{
"RootDirectory": "./bin"
"RootDirectory": "./bin",
"TempDirectory": "/tmp"
}
```
# Compatibility
Some versions of FFMPEG might not have the same argument schema. The lib has been tested with version `3.3` to `4.1`
Some versions of FFMPEG might not have the same argument schema. The lib has been tested with version `3.3` to `4.2`
# API
## FFProbe
FFProbe is used to gather video information
```csharp
static void Main(string[] args)
{
string inputFile = "G:\\input.mp4";
// loaded from configuration
var video = new VideoInfo(inputFile);
string output = video.ToString();
Console.WriteLine(output);
}
```
Sample output:
```csharp
Video Path : G:\input.mp4
Video Root : G:\\
Video Name: input.mp4
Video Extension : .mp4
Video Duration : 00:00:09
Audio Format : none
Video Format : h264
Aspect Ratio : 16:9
Framerate : 30fps
Resolution : 1280x720
Size : 2.88 Mb
```
## FFMpeg
Convert your video files to web ready formats:
```csharp
static void Main(string[] args)
{
string inputFile = "input_path_goes_here";
var encoder = new FFMpeg();
FileInfo outputFile = new FileInfo("output_path_goes_here");
var video = VideoInfo.FromPath(inputFile);
// easily track conversion progress
encoder.OnProgress += (percentage) => Console.WriteLine("Progress {0}%", percentage);
// MP4 conversion
encoder.Convert(
video,
outputFile,
VideoType.Mp4,
Speed.UltraFast,
VideoSize.Original,
AudioQuality.Hd,
true
);
// OGV conversion
encoder.Convert(
video,
outputFile,
VideoType.Ogv,
Speed.UltraFast,
VideoSize.Original,
AudioQuality.Hd,
true
);
// TS conversion
encoder.Convert(
video,
outputFile,
VideoType.Ts
);
}
```
Easily capture screens from your videos:
```csharp
static void Main(string[] args)
{
string inputFile = "input_path_goes_here";
FileInfo output = new FileInfo("output_path_goes_here");
var video = VideoInfo.FromPath(inputFile);
new FFMpeg()
.Snapshot(
video,
output,
new Size(200, 400),
TimeSpan.FromMinutes(1)
);
}
```
Join video parts:
```csharp
static void Main(string[] args)
{
FFMpeg encoder = new FFMpeg();
encoder.Join(
new FileInfo(@"..\joined_video.mp4"),
VideoInfo.FromPath(@"..\part1.mp4"),
VideoInfo.FromPath(@"..\part2.mp4"),
VideoInfo.FromPath(@"..\part3.mp4")
);
}
```
Join image sequences:
```csharp
static void Main(string[] args)
{
FFMpeg encoder = new FFMpeg();
encoder.JoinImageSequence(
new FileInfo(@"..\joined_video.mp4"),
1, // FPS
ImageInfo.FromPath(@"..\1.png"),
ImageInfo.FromPath(@"..\2.png"),
ImageInfo.FromPath(@"..\3.png")
);
}
```
Strip audio track from videos:
```csharp
static void Main(string[] args)
{
string inputFile = "input_path_goes_here",
outputFile = "output_path_goes_here";
new FFMpeg()
.Mute(
VideoInfo.FromPath(inputFile),
new FileInfo(outputFile)
);
}
```
Save audio track from video:
```csharp
static void Main(string[] args)
{
string inputVideoFile = "input_path_goes_here",
outputAudioFile = "output_path_goes_here";
new FFMpeg()
.ExtractAudio(
VideoInfo.FromPath(inputVideoFile),
new FileInfo(outputAudioFile)
);
}
```
Add audio track to video:
```csharp
static void Main(string[] args)
{
string inputVideoFile = "input_path_goes_here",
inputAudioFile = "input_path_goes_here",
outputVideoFile = "output_path_goes_here";
FFMpeg encoder = new FFMpeg();
new FFMpeg()
.ReplaceAudio(
VideoInfo.FromPath(inputVideoFile),
new FileInfo(inputAudioFile),
new FileInfo(outputVideoFile)
);
}
```
Add poster image to audio file (good for youtube videos):
```csharp
static void Main(string[] args)
{
string inputImageFile = "input_path_goes_here",
inputAudioFile = "input_path_goes_here",
outputVideoFile = "output_path_goes_here";
FFMpeg encoder = new FFMpeg();
((Bitmap)Image.FromFile(inputImageFile))
.AddAudio(
new FileInfo(inputAudioFile),
new FileInfo(outputVideoFile)
);
/* OR */
new FFMpeg()
.PosterWithAudio(
inputImageFile,
new FileInfo(inputAudioFile),
new FileInfo(outputVideoFile)
);
}
```
Control over the 'FFmpeg' process doing the job:
```csharp
static void Main(string[] args)
{
string inputVideoFile = "input_path_goes_here",
outputVideoFile = "input_path_goes_here";
FFMpeg encoder = new FFMpeg();
// start the conversion process
Task.Run(() => {
encoder.Convert(new VideoInfo(inputVideoFile), new FileInfo(outputVideoFile));
});
// stop encoding after 2 seconds (only for example purposes)
Thread.Sleep(2000);
encoder.Stop();
}
```
### Enums
Video Size enumeration:
```csharp
public enum VideoSize
{
HD,
FullHD,
ED,
LD,
Original
}
```
Speed enumeration:
```csharp
public enum Speed
{
VerySlow,
Slower,
Slow,
Medium,
Fast,
Faster,
VeryFast,
SuperFast,
UltraFast
}
```
Audio codecs enumeration:
```csharp
public enum AudioCodec
{
Aac,
LibVorbis
}
```
Audio quality presets enumeration:
```csharp
public enum AudioQuality
{
Ultra = 384,
Hd = 192,
Normal = 128,
Low = 64
}
```
Video codecs enumeration:
```csharp
public enum VideoCodec
{
LibX264,
LibVpx,
LibTheora,
Png,
MpegTs
}
```
### ArgumentBuilder
Custom video converting presets could be created with help of `ArgumentContainer` class:
```csharp
var container = new ArgumentContainer();
container.Add(new VideoCodecArgument(VideoCodec.LibX264));
container.Add(new ScaleArgument(VideoSize.Hd));
```
or use Fluent API
```csharp
var container = new ArgumentContainer()
.VideoCodec(VideoCodec.LibX264)
.Scale(VideoSize.Hd);
```
```csharp
var ffmpeg = new FFMpeg();
var result = ffmpeg.Convert(container, new FileInfo("input.mp4"), new FileInfo("output.mp4"));
```
Other availible arguments could be found in `FFMpegCore.FFMPEG.Argument` namespace.
If you need to create your custom argument, you just need to create new class, that is inherited from `Argument`, `Argument<T>` or `Argument<T1, T2>`
For example:
```csharp
public class OverrideArgument : Argument
{
public override string GetStringValue()
{
return "-y";
}
}
```
### Input piping
With input piping it is possible to write video frames directly from program memory without saving them to jpeg or png and then passing path to input of ffmpeg. This feature also allows us to convert video on-the-fly while frames are beeing generated/created/processed.
`IPipeSource` interface is used as source of data. It could be represented as encoded video stream or raw frames stream. Currently `IPipeSource` interface has single implementation, `RawVideoPipeSource` that is used for raw stream encoding.
For example:
Method that is generate bitmap frames:
```csharp
IEnumerable<IVideoFrame> CreateFrames(int count)
{
for(int i = 0; i < count; i++)
{
yield return GetNextFrame(); //method of generating new frames
}
}
```
Then create `ArgumentsContainer` with `InputPipeArgument`
```csharp
var videoFramesSource = new RawVideoPipeSource(CreateFrames(64)) //pass IEnumerable<IVideoFrame> or IEnumerator<IVideoFrame> to constructor of RawVideoPipeSource
{
FrameRate = 30 //set source frame rate
};
var container = new ArgumentsContainer
{
new InputPipeArgument(videoFramesSource),
... //Other encoding arguments
new OutputArgument("temporary.mp4")
};
var ffmpeg = new FFMpeg();
var result = ffmpeg.Convert(arguments);
```
if you want to use `System.Drawing.Bitmap` as `IVideoFrame`, there is `BitmapVideoFrameWrapper` wrapper class.
## Contributors
@ -438,5 +213,6 @@ if you want to use `System.Drawing.Bitmap` as `IVideoFrame`, there is `BitmapVid
### License
Copyright © 2018, [Vlad Jerca](https://github.com/vladjerca).
Released under the [MIT license](https://github.com/jonschlinkert/github-contributors/blob/master/LICENSE).
Copyright © 2020
Released under [MIT license](https://github.com/rosenbjerg/FFMpegCore/blob/master/LICENSE)