Нахождение похожих сегментов среди множества аудиодорожек
Я пытаюсь реализовать программу, которая сможет сверить два (или больше) аудиофайла(ов) и показать все схожие сегменты (участки) между ними на Python.
Мне это нужно для поиска intro/outro/вставок в сериалах (обычно там совпадают звуковые дорожки в определенный момент времени). Пытался сделать много реализаций (все уходили в краш или не работали) или найти хоть какие-либо реализации, но все под старые версии или неактуальны.
Примерно, что я нашел из программ и библиотек, которые мне нужны, это chromaprint и https://pypi.org/project/pyacoustid/ (моей идеей на текущий момент является нахождение двух "отпечатков" треков через эти программы, а потом, в дальнейшем, уже сверка этих отпечатков, но не знаю, как реализовать это). Также нашел эту библиотеку (https://librosa.org/), но не нашел примеров реализации сверки двух сегментов на "похожесть".
Вопрос: Как можно сверить сегменты двух и более аудиодорожек на "схожесть" в процентном соотношении в python? (А в идеале - найти максимально схожие, и получить их время (секунды/миллисекунды) и процентное соотношение схожести)
Подойдет любой рабочий способ с любыми библиотеками.
Ответы (2 шт):
Вот простой пример сравнивания дорожек на библиотеки 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}")
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"