human/test/test_render_queue.py

96 lines
3.2 KiB
Python
Raw Normal View History

2024-10-20 17:37:45 +00:00
import pygame
import time
from pydub import AudioSegment
from collections import deque
class AudioVisualSync:
def __init__(self, audio_file, image_files):
# 初始化 pygame
pygame.init()
# 加载音频
self.audio = AudioSegment.from_file(audio_file)
self.audio_length = len(self.audio) / 1000.0 # 音频总时长(秒)
# 切分音频为 20 毫秒的片段
self.audio_segments = []
segment_duration = 20 # 每个片段 20 毫秒
for start in range(0, len(self.audio), segment_duration):
end = min(start + segment_duration, len(self.audio))
segment = self.audio[start:end]
self.audio_segments.append(segment)
# 加载图像并创建图像队列
self.image_queue = deque()
frame_duration = 0.020 # 每帧 20 毫秒0.020 秒)
for index in range(len(self.audio_segments)):
timestamp = index * frame_duration # 计算每帧的时间戳
img_index = index % len(image_files) # 循环使用图像
frame = pygame.image.load(image_files[img_index])
self.image_queue.append((timestamp, frame))
self.current_frame = None
# 创建窗口
self.screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Audio Visual Sync")
# 播放音频
self.play_audio()
def play_audio(self):
pygame.mixer.init()
pygame.mixer.music.load(audio_file)
pygame.mixer.music.play()
# 开始同步
self.run()
def run(self):
clock = pygame.time.Clock()
while pygame.mixer.music.get_busy(): # 当音乐正在播放时
audio_position = pygame.mixer.music.get_pos() / 1000.0 # 当前音频播放时间(秒)
self.update_image(audio_position)
# 处理 pygame 事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return
# 更新显示
pygame.display.flip()
clock.tick(60) # 控制帧率为 60 FPS
# 音频播放完毕后关闭窗口
pygame.quit()
def update_image(self, audio_position):
# 查找应该显示的图像
while self.image_queue:
timestamp, frame = self.image_queue[0] # 获取队列中的第一个元素
time_difference = audio_position - timestamp
if time_difference >= 0: # 当前音频时间已到该帧
self.current_frame = frame
self.image_queue.popleft() # 移除已显示的帧
else:
break # 当前音频时间未到该帧,退出循环
# 如果当前帧不为空,则更新显示
if self.current_frame is not None:
# 清屏并绘制当前图像
self.screen.fill((0, 0, 0)) # 填充黑色背景
self.screen.blit(self.current_frame, (0, 0))
# 使用示例
if __name__ == "__main__":
audio_file = "your_audio_file.mp3" # 替换为你的音频文件
image_files = ["image1.png", "image2.png", "image3.png"] # 替换为你的图像文件
sync_controller = AudioVisualSync(audio_file, image_files)