Sven
Sven

Reputation: 447

FFmpeg.AutoGen example of how to split audio file

I want to use the FFmpeg.AutoGen project from here: https://github.com/Ruslan-B/FFmpeg.AutoGen

I'm not familiar with the ffmpeg API, so I wanted to get an example of how to split an audio file into little files, for example the audio file is about 2 hours long (can be mp3,ogg,wav,etc.) and I want to split it into several little files of x minutes. The splitting should be done on the main audio file with timestamps from and to, for example from = 00:25:00 (meaning 25 minutes), to = 00:31:12 (meaning 31 minutes, 12 seconds) and the output should be the section from the main audio file, the result is 00:06:12 (meaning 6 minutes, 12 seconds) long.

How can this task be achieved with the project? Also a C example can help me, I would try to convert it into the framework.

Thanks for your responses.

Upvotes: 4

Views: 4219

Answers (1)

Marius
Marius

Reputation: 1679

FFmpeg.AutoGen

What I think you need to do:

  1. Decode audio file
  2. Extract audio samples from the desired start timestamp until desired end timestamp
  3. Encode the extracted samples
  4. 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

Upvotes: 8

Related Questions