3

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.

4

1 回答 1

7

FFmpeg.AutoGen

我认为你需要做的:

  1. 解码音频文件
  2. 从所需的开始时间戳中提取音频样本,直到所需的结束时间戳
  3. 对提取的样本进行编码
  4. 写入新的音频文件

以下是 C 中的一些资源,它们可能会帮助您将它们放在一起:


我认为FFmpeg.AutoGen对于您的用例来说,使用的努力太高了,因此我提出了两种选择:使用NAudioFFmpeg通过命令行

南音频

此代码读取 MP3,提取定义的段并将其写入 WAV 文件。它基于博客文章Concatenating Segments of an Audio File with NAudio并且可以很容易地进行调整。

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 通过命令行

您可以通过类直接从您的 C# 代码调用 ffmpeg System.Diagnostics.Process(参见例如这个 SO question),而不是使用 FFmpeg.AutoGen。

然后,您可以使用以下命令行自动将音频文件拆分为从 00:00:00 开始的相同长度的段

ffmpeg -i in.m4a -f segment -segment_time 300 -c copy out%03d.m4a

或者您可以使用参数更改开始时间-ss(替换<start-time>为秒数)。您需要对每个段重复此操作。

ffmpeg -ss <start-time> -i in.m4a -c copy -t 300 out.m4a

超级用户的来源

于 2018-02-24T13:43:37.170 回答