Вставка WAV в определенный момент в аудиофайле с использованием Python - PullRequest
2 голосов
/ 13 марта 2010

Моя проблема заключается в следующем: у меня есть WAV-файл длиной 2 минуты, и я хочу вставить другой WAV-файл (длиной 7 секунд) в определенный момент в первом WAV-файле (скажем, 0:48), по сути, объединяя два WAV, используя Python.К сожалению, я не смог понять, как это сделать, и мне было интересно, есть ли какое-то очевидное решение, которое я пропустил, или это вообще возможно сделать с python.Возможно, есть библиотека, которая может предоставить решение?Спасибо всем заранее.

ОБНОВЛЕНИЕ на основе комментария ОП:

Я должен был уточнить, что я хотел, чтобы вставленный wav "перекрывал" оригинальный wav, чтобы оба воспроизводились,мои извенения.Есть ли способ добиться такого эффекта?

Ответы [ 5 ]

1 голос
/ 06 мая 2011

используйте пакет pydub (полное раскрытие - я написал)

from pydub import AudioSegment

sound1 = AudioSegment.from_wav('your_wave.mp3')
the_wave = AudioSegment.from_wav('the_7sec_wave.wav')

sound_with_wave = sound1.overlay(the_wave, position=48*1000)

sound_with_wave.export('overlaid.wav', format='wav')
1 голос
/ 09 апреля 2010

Свободно основанный на коде Джастина, вот другой код, который, вероятно, делает то, что вам нужно:

import wave, audioop

def merge_wav_at_offset(wav_in1, wav_in2, offset, wav_out):
    """Merge two wave files, with the second wave starting at offset seconds
    The two input wave files should have the same frame rate, channels, depth
    Also, offset should be non-negative and can be floating point."""
    wf1= wave.open(wav_in1, 'rb')
    wf2= wave.open(wav_in2, 'rb')
    wfo= wave.open(wav_out, 'wb')

    wfout.setparams(wf1.getparams())

    frame_rate = wf1.getframerate()
    sample_width= wf1.getsampwidth()
    if offset < 0:
        offset= 0
    prologue_frames= int(frame_rate*offset)
    merge_frames= wf2.getnframes()

    # prologue
    frames_to_read= prologue_frames
    while frames_to_read > 0:
        chunk_size= min(frame_rate, frames_to_read)
        wfo.writeframes(wf1.readframes(chunk_size))
        frames_to_read-= chunk_size

    # merging
    frames_to_read= merge_frames
    while frames_to_read > 0:
        chunk_size= min(frame_rate, frames_to_read)
        frames2= wf2.readframes(chunk_size)

        if frames2:
            frames1= wf1.readframes(chunk_size)
            if len(frames1) != len(frames2): # sanity check
                # obviously you should cater for this case too
                raise NotImplementedError, "offset+duration(wf2) > duration(wf1)"
            merged_frames= audioop.add(frames1, frames2, sample_width)
            wfo.writeframes(merged_frames)
        else: # early end of wf2 data; improbable but possible
            break

        frames_to_read-= chunk_size

    # epilogue
    while True:
        frames= wf1.readframes(frame_rate)
        if not frames: break
        wfo.writeframes(frames)

    for wave_file in wf1, wf2, wfo:
        wave_file.close()

Я просто написал код без тестирования, поэтому возможно, что у меня есть ошибка (даже синтаксические ошибки); Тем не менее, мой опыт работы с Python заключается в том, что часто код работает как есть ;-) Если вам нужно что-то еще, дайте мне знать.

1 голос
/ 13 марта 2010

Если они закодированы в PCM, вы можете использовать wave, в противном случае используйте что-то вроде pygst.

0 голосов
/ 13 апреля 2018

следующий способ объединить 2 буфера аудиосэмпла

при условии, что оба буфера / файла имеют одинаковый формат / одинаковое количество каналов / одинаковую частоту дискретизации, все 3 data - это буферы семпловых строк одинаковой длины (! Важно), sampleFormat - количество байтов для выборки, например: для 16-битной выборки это будет = 2:

import audioop

merged_data = audioop.add(firstWave_data, secondWave_data, sampleFormat)

В противном случае подготовьтесь к выполнению следующей подготовки буферов:

  1. преобразование моно / стерео
  2. преобразование формата
  3. преобразование передискретизации
0 голосов
/ 13 марта 2010

Вот код, который поможет вам в правильном направлении:

wf = wave.open('in1.wav','rb')
wf2 = wave.open('in2.wav','rb')
wfout = wave.open('out.wav','wb')

wfout.setparams(wf.getparams())

sr = wf.getframerate()
for x in xrange(48):
    wfout.writeframes(wf.readframes(sr)
wfout.writeframes(wf2.readframes(sr))
for x in xrange(72):
    wfout.writeframes(wf.readframes(sr))

Это должно делать то, что вы описали в своем вопросе (добавление 1-секундного клипа 48 секунд в 2-минутную песню), если волны имеют одинаковый формат (одинаковая частота дискретизации, одинаковое количество каналов и т. Д.). ). Вы, вероятно, можете читать / писать более крупные фрагменты, чем за секунду, но я сделал их как 1-секундные фрагменты, чтобы быть в безопасности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...