human/test/test_render_queue.py
2024-10-21 01:37:45 +08:00

96 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)