Нахождение похожих сегментов среди множества аудиодорожек

Я пытаюсь реализовать программу, которая сможет сверить два (или больше) аудиофайла(ов) и показать все схожие сегменты (участки) между ними на Python.

Мне это нужно для поиска intro/outro/вставок в сериалах (обычно там совпадают звуковые дорожки в определенный момент времени). Пытался сделать много реализаций (все уходили в краш или не работали) или найти хоть какие-либо реализации, но все под старые версии или неактуальны.

Примерно, что я нашел из программ и библиотек, которые мне нужны, это chromaprint и https://pypi.org/project/pyacoustid/ (моей идеей на текущий момент является нахождение двух "отпечатков" треков через эти программы, а потом, в дальнейшем, уже сверка этих отпечатков, но не знаю, как реализовать это). Также нашел эту библиотеку (https://librosa.org/), но не нашел примеров реализации сверки двух сегментов на "похожесть".

Вопрос: Как можно сверить сегменты двух и более аудиодорожек на "схожесть" в процентном соотношении в python? (А в идеале - найти максимально схожие, и получить их время (секунды/миллисекунды) и процентное соотношение схожести)

Подойдет любой рабочий способ с любыми библиотеками.


Ответы (2 шт):

Автор решения: KT315

Вот простой пример сравнивания дорожек на библиотеки librosa

import librosa
import numpy as np

y1, sr1 = librosa.load('audiofile1.wav')
y2, sr2 = librosa.load('audiofile2.wav')

c1 = librosa.feature.chroma_stft(y=y1, sr=sr1)
c2 = librosa.feature.chroma_stft(y=y2, sr=sr2)

c1n = librosa.util.normalize(c1)
c2n = librosa.util.normalize(c2)

similarity = np.dot(c1n.T, c2n) / np.linalg.norm(c1n) / np.linalg.norm(c2n)
percentage_similarity = np.mean(similarity) * 100

print(f'Процент схожести: {percentage_similarity}%')

Чтобы сравнить больше файлов можно использовать циклы

Изменено: я не правильно понял вопрос вот другой код

import librosa
import numpy as np
from fastdtw import fastdtw

def extract_chroma_features(audio_file):
    y, sr = librosa.load(audio_file)
    return librosa.feature.chroma_stft(y=y, sr=sr)

def find_similar_segments(audio_file1, audio_file2, threshold):
    chroma1, chroma2 = map(extract_chroma_features, [audio_file1, audio_file2])
    min_len = min(chroma1.shape[1], chroma2.shape[1])
    return [i for i in range(min_len) if fastdtw(chroma1[:, i], chroma2[:, i])[0] < threshold]

audio_file1, audio_file2, threshold = "audiofile1.wav", "audiofile2.wav", 100
similar_segments = find_similar_segments(audio_file1, audio_file2, threshold)
print(f"The similar segments in {audio_file1} and {audio_file2} are: {similar_segments}")
→ Ссылка
Автор решения: adolf_two
import librosa
from fastdtw import fastdtw
import numpy as np

# Функция для извлечения признаков из аудиосигнала
def extract_features(audio_file):
    y, sr = librosa.load(audio_file)
    # Например, можно использовать MFCC (Mel-frequency cepstral coefficients)
    mfcc = librosa.feature.mfcc(y=y, sr=sr)
    return mfcc, sr  # Возвращаем также частоту дискретизации

# Функция для сравнения сегментов аудиодорожек
def compare_segments(segment1, segment2, sr, threshold):
    _, path = fastdtw(segment1.T, segment2.T)  # Используем fastdtw для быстрого динамического выравнивания времени
    time_indices = path[:, 0] / sr  # Временные сдвиги в секундах
    distance = path[-1, -1]  # Длина пути соответствует "расстоянию" между сегментами
    similarity = 1 / (1 + distance)  # Преобразуем расстояние в процент схожести
    if similarity > threshold:
        return similarity, time_indices, "Сегменты похожи"
    else:
        return similarity, time_indices, "Сегменты не похожи"

# Поиск схожих сегментов между двумя аудиофайлами
def find_similar_segments(audio_file1, audio_file2, threshold):
    chroma1, chroma2 = map(extract_features, [audio_file1, audio_file2])
    min_len = min(chroma1.shape[1], chroma2.shape[1])
    similar_segments = [i for i in range(min_len) if fastdtw(chroma1[:, i], chroma2[:, i])[0] < threshold]
    return similar_segments

# Пример использования функций
audio_file1, audio_file2, threshold = "audiofile1.wav", "audiofile2.wav", 0.9  # Порог схожести

# Извлечение признаков из аудиофайлов
segment1, sr1 = extract_features(audio_file1)
segment2, sr2 = extract_features(audio_file2)

# Сравнение сегментов
similarity, time_indices, message = compare_segments(segment1, segment2, sr1, threshold)
print(f"Процент схожести: {similarity * 100}%")
print(f"Временные сдвиги: {time_indices} секунд")
print(message)

# Находим схожие сегменты
similar_segments = find_similar_segments(audio_file1, audio_file2, threshold)
print(f"Результаты сравнение {audio_file1} и {audio_file2}:")
print(f"Процент схожести: {similarity * 100}%")
print(f"Временные сдвиги: {time_indices} секунд")
print(f"И схожесть сегментов:  {similar_segments}")

Не забудь:

pip install --force-reinstall librosa

pip install --upgrade setuptools

pip install fastdtw

pip install librosa

И:

audio_file1 = "путь/путь/путь/путь/audiofile1.wav"

audio_file2 = "путь/путь/путь/путь/audiofile1.wav"

→ Ссылка