【问题标题】:How to join two wav files using python?如何使用 python 连接两个 wav 文件?
【发布时间】:2011-02-22 20:36:33
【问题描述】:

我正在使用python编程语言,我想在另一个wav文件的末尾加入一个wav文件? 我在论坛中有一个问题,建议如何合并两个 wav 文件,即在某个偏移量处添加一个 wav 文件的内容,但我想在彼此末尾加入两个 wav 文件...

而且我也有可能播放我自己的 wav 文件,使用 winsound 模块..我能够播放声音,但在播放任何 Windows 声音之前使用 time.sleep 一段时间,如果我想要的话,缺点是这样要播放更长的声音。sleep(N),N sec 也是,Windows 声音将在 N sec 播放 winsound nd 后重叠。..

任何人都可以帮忙吗?请建议如何解决这些问题...

提前致谢

【问题讨论】:

    标签: python audio wav


    【解决方案1】:

    Python 附带了 wave 模块,可以满足您的需求。当文件的详细信息(单声道或立体声、帧速率等)相同时,以下示例有效:

    import wave
    
    infiles = ["sound_1.wav", "sound_2.wav"]
    outfile = "sounds.wav"
    
    data= []
    for infile in infiles:
        w = wave.open(infile, 'rb')
        data.append( [w.getparams(), w.readframes(w.getnframes())] )
        w.close()
        
    output = wave.open(outfile, 'wb')
    output.setparams(data[0][0])
    for i in range(len(data)):
        output.writeframes(data[i][1])
    output.close()
    

    【讨论】:

      【解决方案2】:

      我用pysox

      wave 模块和许多其他模块似乎不支持 mu-law wavs。

      您安装的 pysox 请求 SoX 并更新您的 PATH 以包含它的安装目录。

      import sox    
      cbn=sox.Combiner()
      sounds=[]
      #PROCESS SOUND PATHS TO AN ARRAY
      if len(sounds)>=2:
          print(sounds)
          cbn.build(sounds,'outputfilepath.ext','concatenate')
      

      【讨论】:

        【解决方案3】:

        我会使用librosa.loadlibrosa.write_wav。 查看文档here

        import librosa
        import numpy as np
        import librosa.display
        
        example_audio = librosa.util.example_audio_file()
        x, sr = librosa.load(example_audio, duration=5)
        print('shape of x ==> ' + str(x.shape))
        y, sr = librosa.load(example_audio, duration=5)
        print('shape of y ==> ' + str(y.shape))
        z = np.append(x,y)
        print('shape of x+y = z ==> ' + str(z.shape))
        librosa.output.write_wav('joined_file.wav', z, sr)
        
        z_loaded, sr = librosa.load('joined_file.wav')
        print('shape of z loaded ==> ' + str(z_loaded.shape))
        

        输出:

        x 的形状 ==> (110250,)

        y 的形状 ==> (110250,)

        x+y 的形状 = z ==> (220500,)

        z 加载的形状 ==> (220500,)

        【讨论】:

        • @Ryan 更新了答案。您可能对这里的更多代码示例感兴趣:github.com/gndps/vocal-training/blob/master/… 虽然不是很容易阅读文档
        • 请注意librosa 附带numpyscipyscikit-learn,这对于那些只想合并 WAV 文件的人来说可能是矫枉过正
        【解决方案4】:

        Python 3 解决方案:
        我们可以使用标准库来做到这一点,如 tom10 和 eggbert 的回答所示。
        下面是一个较短的版本:

        1. 仅写入第一个波形文件的参数。我们可以测试 wav_out 文件长度,看看我们是否还没有写入它。如果我们没有只写一次波形参数。
        2. 然后在从 wav_in 读取帧时将帧写入 wav_out。

          with wave.open(outfile, 'wb') as wav_out:
              for wav_path in infiles:
                  with wave.open(wav_path, 'rb') as wav_in:
                      if not wav_out.getnframes():
                          wav_out.setparams(wav_in.getparams())
                      wav_out.writeframes(wav_in.readframes(wav_in.getnframes()))
          

        【讨论】:

        • 请注意,这支持合并超过2个文件,而@tom10's answer仅适用于2个文件
        【解决方案5】:

        只是以@tom10 的回答为基础:

        from contextlib import closing
        
        with closing(wave.open(outfile, 'wb')) as output:
        
            # find sample rate from first file
            with closing(wave.open(wav_files[0])) as w:
                output.setparams(w.getparams())
        
            # write each file to output
            for infile in wav_files:
                with closing(wave.open(infile)) as w:
                    output.writeframes(w.readframes(w.getnframes()))
        

        它不是存储所有数据然后一次将其写入末尾,而是逐位写入。它还使用 contextlib.close,因此您不必关闭文件。

        【讨论】:

        • 在 python3 中,看起来我们不需要 contextlib 包装器:“open() 函数可以在 with 语句中使用。当 with 块完成时,Wave_read.close() 或Wave_write.close() 方法被调用。” docs.python.org/3/library/wave.html
        【解决方案6】:

        我是pydub 的维护者,它旨在让这类事情变得简单。

        from pydub import AudioSegment
        
        sound1 = AudioSegment.from_wav("/path/to/file1.wav")
        sound2 = AudioSegment.from_wav("/path/to/file2.wav")
        
        combined_sounds = sound1 + sound2
        combined_sounds.export("/output/path.wav", format="wav")
        

        注意:pydub 是一个轻量级的 audioop 包装器。所以在幕后,它基本上是在做 Tom10 提到的事情

        【讨论】:

        • 这令人印象深刻!谢谢。
        • 但是如果你正在读取一个时间戳文件呢???你如何连接文件人
        • @Elvisjames 我认为你需要安装 ffprobe - pydub 绝对支持 python 3
        【解决方案7】:

        我使用 SOX [1] 库,然后像这样调用它

        >>> import subprocess
        >>> sound_output_path = /tmp
        >>> sox_filenames = ['file.wav', 'file1.wav']
        >>> subprocess.call(['sox'] + sox_filenames + ['%s/out.wav' % sound_output_path])
        

        [1]http://sox.sourceforge.net/

        【讨论】:

          【解决方案8】:

          你可以使用audiolab:

          import audiolab, scipy
          a, fs, enc = audiolab.wavread('file1.wav')
          b, fs, enc = audiolab.wavread('file2.wav')
          c = scipy.vstack((a,b))
          audiolab.wavwrite(c, 'file3.wav', fs, enc)
          

          【讨论】:

          • 我是否需要安装任何软件包才能使用 scipy...我使用的是 python2.6,如果需要,我可以下载兼容的版本吗...请给我链接。 .我试图frm scipy网站本身bt面临sme问题..如果没有安装步骤请建议..谢谢你的回答..你知道如何播放声音吗,我提到了我的prob wit playin,任何措施fr那个??
          • Python 2.6 没问题,Numpy/Scipy 网站也应该没问题。我可能会让其他人回答您的问题并提供进一步的建议。虽然我的回答确实有效,但可能还有更优雅、更直接的解决方案。
          • 我尝试从 scikits 安装 audiolab,它的大小约为 1.4 mb,并且安装成功,但是在运行你的代码时它说 import error: no module named audiolab..i didn't install the 44mb scipy包是问题,我是否还需要安装它或 audioalab 下载本身不正确
          • 我也安装了 Scipy,但仍然说导入错误..我正在使用两个都下载并稍后安装的窗口..仍然有可能是什么原因..
          • 这些天,我会使用librosalibrosa.github.io/librosa/generated/…
          猜你喜欢
          • 2012-11-03
          • 2016-03-23
          • 2020-11-03
          • 2015-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-25
          • 2021-04-17
          相关资源
          最近更新 更多