Python - ฉันจะเล่นเสียงเดียวกันหลาย ๆ ครั้งโดยไม่รบกวนกันได้อย่างไร

ฉันจำเป็นต้องสร้างโปรแกรมที่จะเล่นไฟล์เสียง และเมื่อผ่านไปครึ่งทางของไฟล์เสียง ไฟล์นั้นก็จะเล่นอีกครั้ง แต่จะไม่ตัดส่วนที่ยังเล่นไม่เสร็จออกไป ดังนั้นไฟล์เดียวกันจะเล่นสองไฟล์ ครั้งพร้อมกันโดยมีเวลาเริ่มต้นต่างกัน

ฉันได้ลองใช้ไลบรารีหลายแห่งเช่น pygame, winsound และ pyglet แต่เท่าที่ฉันสามารถบอกได้ว่าไม่มีไลบรารีใดที่อนุญาตสิ่งนี้

แก้ไข: ฉันลองใช้ pygame อีกครั้ง แต่มันฟังดูไม่ถูกต้อง ฉันคิดว่าเป็นเพราะความล่าช้ากับ pygame

import pygame
import time
import threading

pygame.mixer.pre_init(frequency=44100)
pygame.mixer.init()

sound1 = pygame.mixer.Sound("Assets\\Blip.wav")
sound2 = pygame.mixer.Sound("Assets\\Blip.wav")
print(sound1.get_length())
half = 0.141/2

def play(ch,sound):
    pygame.mixer.Channel(ch).play(sound,loops=-1)

time.sleep(5)
t1 = threading.Thread(target=play,args=(0,sound1,))
t1.start()
time.sleep(half)
play(1,sound2,)

person Twingemios    schedule 06.12.2019    source แหล่งที่มา
comment
เพราะเสียง pygame ใช้เธรดดังนั้นฉันจึงสามารถได้ยินเสียงสองเสียงโดยไม่ต้องใช้ Thread บางทีมันอาจจะฟังดูดีกว่าถ้าคุณไม่ใช้ Thread หรือบางทีมันอาจจะฟังดูไม่ดีเลยเพราะคุณคาดหวังบางสิ่งที่ไม่สามารถทำได้ด้วยวิธีนี้ BTW: ทดสอบบน Linux Mint 19.2, Python 3.7.5, PyGame 1.9.6   -  person furas    schedule 07.12.2019


คำตอบ (1)


simpleaudio รองรับการเล่นเสียงพร้อมกัน เราใช้ pydub เพื่อให้เข้าถึงความยาวของส่วนของเสียงได้ง่าย (แม้ว่าคุณจะสามารถได้รับความเหมือนกันจากเสียงธรรมดาๆ แม้จะต้องใช้ความพยายามบ้างก็ตาม ). และ pydub ยังสามารถเล่นเสียงธรรมดา ๆ ได้ (ซึ่งทำให้เราเล่นพร้อมกันได้) โดยใช้ pydub.playback._play_with_simpleaudio() ซึ่งทำให้โค้ดง่ายขึ้น

นี่คือตัวอย่างการทำงาน ฉันนำไฟล์เสียงที่แตกต่างกันสองไฟล์เพื่อตรวจสอบ/แสดงให้เห็นว่าส่วนเสียงที่ 2 เริ่มต้นหลังจากไฟล์แรกเสร็จสิ้นไปครึ่งทางแล้ว

#!/usr/local/bin/python3

from pydub import AudioSegment
from pydub.playback import _play_with_simpleaudio

import threading
import time

def play(sound):
    play_obj = _play_with_simpleaudio(sound)

sound1 = AudioSegment.from_wav("Audio_1.wav")
sound2 = AudioSegment.from_wav("Audio_2.wav")

half = sound1.duration_seconds /2
t1 = threading.Thread(target=play,args=(sound1,))
t1.start()
time.sleep(half)
play(sound2)
time.sleep(1)
person Anil_M    schedule 08.12.2019
comment
ฉันลองสิ่งนี้แล้ว แต่ทั้งสองเสียงไม่ทับซ้อนกัน แต่ดูเหมือนว่าจะทับซ้อนกัน - person Twingemios; 09.12.2019
comment
ในกรณีของฉัน เสียงสองเสียงซ้อนทับกัน ฉันได้ยินเสียงที่แตกต่างกันสองเสียงเล่นหลังจากเสียงแรกผ่านไปได้ครึ่งทางแล้ว แม้จะมีไฟล์ wav เดียวกัน แต่ฉันก็ยังได้ยินเสียงอันที่สองดังขึ้นในขณะที่อันแรกเล่น time.sleep จะควบคุมระยะเวลาการเล่นไฟล์ที่สอง ที่สามารถเปลี่ยนเป็น sound2.duration_seconds เพื่อให้ไฟล์ที่ 2 เล่นได้เต็มที่ ถ้าไม่ คุณสามารถอธิบายรายละเอียดเพิ่มเติมเกี่ยวกับความต้องการของคุณได้หรือไม่? - person Anil_M; 09.12.2019