【问题标题】:FFmpeg.AutoGen example of how to split audio fileFFmpeg.AutoGen 如何分割音频文件的例子
【发布时间】:2018-08-04 09:44:51
【问题描述】:

我想从这里使用 FFmpeg.AutoGen 项目:https://github.com/Ruslan-B/FFmpeg.AutoGen

我不熟悉 ffmpeg API,所以我想获得一个如何将音频文件拆分为小文件的示例,例如音频文件大约 2 小时长(可以是 mp3、ogg、wav、等),我想把它分成几个 x 分钟的小文件。拆分应该在主音频文件上进行,时间戳从和到,例如从 = 00:25:00(意思是 25 分钟)到 = 00:31:12(意思是 31 分 12 秒)并且输出应该是主音频文件的部分,结果是 00:06:12(意思是 6 分 12 秒)长。

如何通过该项目完成这项任务?还有一个 C 示例可以帮助我,我会尝试将其转换为框架。

感谢您的回复。

【问题讨论】:

    标签: c# c audio ffmpeg autogen


    【解决方案1】:

    FFmpeg.AutoGen

    我认为你需要做的事情:

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

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


    我认为使用 FFmpeg.AutoGen 的工作量对于您的用例来说太高了,因此我提出了 2 个替代方案:通过命令行使用 NAudio 或 FFmpeg

    NAudio

    此代码读取 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 通过命令行

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

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

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

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

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

    Source on superuser

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多