from pydub import AudioSegment
import os
# ffmpeg 환경 설정
ffmpeg_path = r'C:\ffmpeg-2024-04-10-git-0e4dfa4709-full_build\bin' # 실제 ffmpeg 설치 경로로 변경하세요.
os.environ['PATH'] += os.pathsep + ffmpeg_path
def add_collision_sounds_based_on_type(collision_times, collision_sound_path, output_path, audio_type, clip_length_ms=2500):
"""
주어진 시간에 맞춰 뮤직 또는 효과음을 삽입하여 무음 배경 오디오 파일을 생성하는 함수.
Args:
- collision_times (list[int]): 충돌이 일어나는 시간(밀리초) 리스트
- collision_sound_path (str): 충돌 시 재생할 오디오 파일 경로
- output_path (str): 결과 오디오 파일을 저장할 경로
- audio_type (str): 'music' 또는 'effect'를 지정하여 오디오 타입 선택
- clip_length_ms (int): 각 충돌에 삽입할 오디오 길이 (밀리초 단위, 'music' 타입에서만 필요)
Returns:
- None
"""
# 충돌 소리 파일 로드
collision_sound = AudioSegment.from_file(collision_sound_path).apply_gain(20)
# 1분 길이의 무음 오디오 생성
base_audio = AudioSegment.silent(duration=59000) # 약 1분 = 59000 밀리초
if audio_type == 'music':
# 충돌 시간 병합을 위한 처리
collision_times.sort()
merged_times = []
current_start = collision_times[0]
current_end = current_start + clip_length_ms
for time in collision_times[1:]:
if time <= current_end: # 현재 시간이 이전 시간과 겹치면 병합
current_end = max(current_end, time + clip_length_ms)
else:
merged_times.append((current_start, current_end))
current_start = time
current_end = time + clip_length_ms
merged_times.append((current_start, current_end)) # 마지막 구간 추가
# 병합된 시간에 따라 오디오 삽입
for start, end in merged_times:
duration = end - start
clip = collision_sound[:duration]
base_audio = base_audio.overlay(clip, position=start)
elif audio_type == 'effect':
# 각 충돌 시간에 동일한 효과음 동시 재생
for time in collision_times:
base_audio = base_audio.overlay(collision_sound, position=time)
# 결과 오디오 파일 저장
base_audio.export(output_path, format="mp3")
단계별 분석
충돌 시간 정렬:
collision_times.sort()
collision_times 리스트에 포함된 시간들을 오름차순으로 정렬합니다. 이렇게 하면 시간이 이전 것부터 차례대로 처리될 수 있으며, 병합 로직을 적용하기 더 쉬워집니다.
변수 초기화:
merged_times = []
current_start = collision_times[0]
current_end = current_start + clip_length_ms
merged_times: 병합된 시간 구간을 저장할 리스트입니다.
current_start: 첫 번째 충돌 시간을 시작 시간으로 설정합니다.
current_end: current_start에서 클립 길이(clip_length_ms)만큼 더한 값으로 초기 종료 시간을 설정합니다. 이는 첫 번째 오디오 클립의 재생이 끝나는 시간을 나타냅니다.
충돌 시간 순회 및 병합 로직:
python
Copy code
for time in collision_times[1:]:
if time <= current_end:
current_end = max(current_end, time + clip_length_ms)
else:
merged_times.append((current_start, current_end))
current_start = time
current_end = time + clip_length_ms
이 for 루프는 첫 번째 충돌 시간을 제외한 모든 시간을 순회합니다.
if time <= current_end: 현재 처리하는 시간이 현재 오디오 클립의 재생이 끝나는 시간보다 이르거나 같다면, 이 시간은 현재 오디오 클립과 겹치는 것입니다. 이 경우, current_end를 갱신하여 현재 클립의 끝나는 시간을 조정합니다.
else: 처리하는 시간이 현재 오디오 클립의 끝나는 시간보다 늦다면, 이전 클립과 겹치지 않으므로 현재 클립을 merged_times에 추가하고, 새 클립의 시작과 끝 시간을 설정합니다.
마지막 구간 추가:
merged_times.append((current_start, current_end))
for 루프가 끝나고 남은 마지막 오디오 클립 구간을 merged_times 리스트에 추가합니다. 이는 리스트의 마지막 충돌 시간이 처리된 후에 수행됩니다.
'개발 기록 > 자동 포스팅 프로그램' 카테고리의 다른 글
Configuration 정리 (0) | 2024.05.18 |
---|---|
uploader 코드 정리 (0) | 2024.05.17 |
배경음 관리 기법 해결 방안 모색 (0) | 2024.04.14 |
기믹 추가 내용 정리 (0) | 2024.04.09 |
기믹 추가 내용 정리 (0) | 2024.04.02 |