1
import cv2
import os
from playsound import playsound as ps
import pygame
import time
import asyncio

video_path = os.path.join('videos_in', 'video.mp4')
sidewalk_path = os.path.join('voices', 'audio1.mp3')
driveway_path = os.path.join('voices', 'audio2.mp3')
cap = cv2.VideoCapture(video_path)
# Get FPS of original video
original_fps = int(cap.get(cv2.CAP_PROP_FPS))

pygame.init()
pygame.mixer.init()

async def sidewalk_sound():
    sc(sidewalk_path)

async def driveway_sound():
    sc(driveway_path)

async def playgo(tasks):
    for task in tasks:
        await asyncio.create_task(task)

class SoundClass:
    def __call__(self, path):
        sd = pygame.mixer.Sound(path)
        sd.play()
        return None

sc = SoundClass()
piv = 1

while True:
    task = []
    ret, frame = cap.read()
    if piv:
        task.append(driveway_sound())
        task.append(sidewalk_sound())
        piv = 0
    asyncio.run(playgo(task))
    cv2.imshow('video', frame)

    delay = int(1000 / original_fps)
    if cv2.waitKey(delay) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

The above plays a video and a sound using asyncio asynchronously. However, currently both sounds are played at the same time, so is there a way to make the sounds play one after the other as the video continues to play?

I think I can use asyncio.queue(), but I'm not used to it. I'd appreciate your help.

W D
  • 204
  • 1
  • 10

1 Answers1

0

Try the asyncio.run_until_complete method.

Example:

import asyncio

async def play_audio_1():
   print('audio 1')
   code_here('some_audio.mp3')
async def play_audio_2():
   print('audio 2')
   code_here('more_audio.mp3')

loop = asyncio.get_event_loop()
loop.run_until_complete(play_audio_1())
loop.run_until_complete(play_audio_2())
loop.close()

Outputs:

audio 1
[some_audio.mp3 is played]
audio 2
[more_audio.mp3 is played]

More information (stackoverflow.com)

W D
  • 204
  • 1
  • 10
Vu Nguyen
  • 52
  • 5