2014-09-10 97 views
3

我試圖在某些片段中拆分音頻文件。將音頻文件拆分爲片段

事實是:我有一個字節數組,我想將wav文件分成幾塊(例如3個)。

當然,我知道我不能做這樣的事情。但有沒有人有一個想法如何做到這一點?

byte[] result = stream.ToArray(); 
byte[] testing = new byte[44]; 

for (int ix = 0; ix < testing.Length; ix++) 
{ 
    testing[ix] = result[ix]; 
} 

System.IO.File.WriteAllBytes("yourfilepath_" + System.Guid.NewGuid() + ".wav", testing); 

我想辦建立在C#這個解決辦法,但我聽說有一個叫紅襪lib和我可以用沉默的間隙這樣的分裂:

sox in.wav out.wav silence 1 0.5 1% 1 5.0 1% : newfile : restart 

但每次我運行此命令,只生成一個文件。 (音頻文件持續5秒,每個分割文件必須有1秒鐘)。

這樣做的最好方法是什麼?

非常感謝!

回答

3

編輯

隨着SOX:

string sox = @"C:\Program Files (x86)\sox-14-4-1\sox.exe"; 
string inputFile = @"D:\Brothers Vibe - Rainforest.mp3"; 
string outputDirectory = @"D:\splittest"; 
string outputPrefix = "split"; 

int[] segments = { 10, 15, 30 }; 

IEnumerable<string> enumerable = segments.Select(s => "trim 0 " + s.ToString(CultureInfo.InvariantCulture)); 
string @join = string.Join(" : newfile : ", enumerable); 
string cmdline = string.Format("\"{0}\" \"{1}%1n.wav" + "\" {2}", inputFile, 
    Path.Combine(outputDirectory, outputPrefix), @join); 

var processStartInfo = new ProcessStartInfo(sox, cmdline); 
Process start = System.Diagnostics.Process.Start(processStartInfo); 

如果SOX抱怨的libmad(支持MP3):複製的DLL旁邊,看到here

另外,您可以在使用FFMPEG同樣的方式:

ffmpeg -ss 0 -t 30 -i "Brothers Vibe - Rainforest.mp3" "Brothers Vibe - Rainforest.wav" 

see the docs的所有細節)


你可以用BASS.NET做到這一點很容易:

對於下面的代碼,你在傳遞:

  • 輸入文件名
  • 所需每段的持續時間
  • 輸出目錄
  • 前綴用於每個分段文件

的方法將檢查該文件是否是指定段足夠長的時間,如果是,則它會切斷該文件以WAV文件具有相同的採樣率,聲道,位深度。

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Windows.Forms; 
using Un4seen.Bass; 
using Un4seen.Bass.Misc; 

namespace WindowsFormsApplication2 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      if (!Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero)) 
       throw new InvalidOperationException("Couldn't initialize BASS"); 

      string fileName = @"D:\Brothers Vibe - Rainforest.mp3"; 
      var segments = new double[] {30, 15, 20}; 
      string[] splitAudio = SplitAudio(fileName, segments, "output", @"D:\split"); 
     } 

     private static string[] SplitAudio(string fileName, double[] segments, string prefix, string outputDirectory) 
     { 
      if (fileName == null) throw new ArgumentNullException("fileName"); 
      if (segments == null) throw new ArgumentNullException("segments"); 
      if (prefix == null) throw new ArgumentNullException("prefix"); 
      if (outputDirectory == null) throw new ArgumentNullException("outputDirectory"); 
      int i = Bass.BASS_StreamCreateFile(fileName, 0, 0, 
       BASSFlag.BASS_STREAM_PRESCAN | BASSFlag.BASS_STREAM_DECODE); 
      if (i == 0) 
       throw new InvalidOperationException("Couldn't create stream"); 

      double sum = segments.Sum(); 

      long length = Bass.BASS_ChannelGetLength(i); 
      double seconds = Bass.BASS_ChannelBytes2Seconds(i, length); 
      if (sum > seconds) 
       throw new ArgumentOutOfRangeException("segments", "Required segments exceed file duration"); 
      BASS_CHANNELINFO info = Bass.BASS_ChannelGetInfo(i); 

      if (!Directory.Exists(outputDirectory)) Directory.CreateDirectory(outputDirectory); 

      int index = 0; 
      var list = new List<string>(); 
      foreach (double segment in segments) 
      { 
       double d = segment; 
       long seconds2Bytes = Bass.BASS_ChannelSeconds2Bytes(i, d); 
       var buffer = new byte[seconds2Bytes]; 
       int getData = Bass.BASS_ChannelGetData(i, buffer, buffer.Length); 
       string name = string.Format("{0}_{1}.wav", prefix, index); 
       string combine = Path.Combine(outputDirectory, name); 
       int bitsPerSample = info.Is8bit ? 8 : info.Is32bit ? 32 : 16; 
       var waveWriter = new WaveWriter(combine, info.chans, info.freq, bitsPerSample, true); 
       waveWriter.WriteNoConvert(buffer, buffer.Length); 
       waveWriter.Close(); 
       list.Add(combine); 
       index++; 
      } 
      bool free = Bass.BASS_StreamFree(i); 

      return list.ToArray(); 
     } 
    } 
} 

TODO

提取不是最優化的,如果你所關心的內存使用情況,那麼函數應該加強搶段的部分並將其逐步寫入WaveWriter

注意

BASS。NET有一個嘮叨的屏幕,但你可以要求在他們的網站免費註冊序列。

請注意,安裝BASS.NET,然後確保從您的EXE旁邊的基礎包中複製bass.dll。此外,您可以使用幾乎任何音頻格式,查看其網站的格式插件以及如何加載它們(BASS_PluginLoad)。

+0

感謝Ayve,鏈接很有幫助=)...但是我必須讓它在工作中建立一些東西...不能使用免費BASS =/ – Crasher 2014-09-10 22:03:08

+0

請參閱我的使用SOX的編輯! – Aybe 2014-09-10 22:35:18

+0

謝謝Aybe!這真的很有幫助=)你知道ffmpeg是否允許我通過靜默差距來分割文件嗎? – Crasher 2014-09-11 12:39:36