FFmpeg.AutoGen
What I think you need to do:
- Decode audio file
- Extract audio samples from the desired start timestamp until desired end timestamp
- Encode the extracted samples
- Write new audio file
Here are some sources in C which might help you to put it all together:
I think that the effort to use FFmpeg.AutoGen
is too high for your use-case and therefore I propose 2 alternatives: Use NAudio
or FFmpeg
via command line
NAudio
This code reads an MP3, extracts a defined segment and writes it to a WAV file. It is based on the blog post Concatenating Segments of an Audio File with NAudio and can be tweaked quite easily.
using NAudio.Wave;
using System;
namespace NAudioSegments
{
class SegmentProvider : IWaveProvider
{
private readonly WaveStream sourceStream;
private int segmentStart, segmentDuration;
public SegmentProvider(WaveStream sourceStream)
{
this.sourceStream = sourceStream;
}
public WaveFormat WaveFormat => sourceStream.WaveFormat;
public void DefineSegment(TimeSpan start, TimeSpan duration)
{
if (start + duration > sourceStream.TotalTime)
throw new ArgumentOutOfRangeException("Segment goes beyond end of input");
segmentStart = TimeSpanToOffset(start);
segmentDuration = TimeSpanToOffset(duration);
sourceStream.Position = segmentStart;
}
public int TimeSpanToOffset(TimeSpan ts)
{
var bytes = (int)(WaveFormat.AverageBytesPerSecond * ts.TotalSeconds);
bytes -= (bytes % WaveFormat.BlockAlign);
return bytes;
}
public int Read(byte[] buffer, int offset, int count)
{
int totalBytesRead = 0;
int bytesRead = 0;
do
{
bytesRead = ReadFromSegment(buffer, offset + totalBytesRead, count - totalBytesRead);
totalBytesRead += bytesRead;
} while (totalBytesRead < count && bytesRead != 0);
return totalBytesRead;
}
private int ReadFromSegment(byte[] buffer, int offset, int count)
{
var bytesAvailable = (int)(segmentStart + segmentDuration - sourceStream.Position);
var bytesRequired = Math.Min(bytesAvailable, count);
return sourceStream.Read(buffer, offset, bytesRequired);
}
}
class Program
{
static void Main(string[] args)
{
using (var source = new Mp3FileReader(@"<input-path>"))
{
var segmentProvider = new SegmentProvider(source);
// Add desired splitting e.g. start at 2 seconds, duration 1 second
segmentProvider.DefineSegment(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(1));
WaveFileWriter.CreateWaveFile(@"<output-path>", segmentProvider);
}
}
}
}
FFmpeg via command line
You could invoke ffmpeg directly from your C# code via the System.Diagnostics.Process
class (see e.g. this SO question) instead of using FFmpeg.AutoGen.
You could then use the following command line for automatically splitting the audio file in segemnts of the same length beginning at 00:00:00
ffmpeg -i in.m4a -f segment -segment_time 300 -c copy out%03d.m4a
or you can change the start time with the parameter -ss
(replace <start-time>
with the number of seconds). You would need to repeat this for every segment.
ffmpeg -ss <start-time> -i in.m4a -c copy -t 300 out.m4a
Source on superuser