D
D
ddgryaz2020-10-15 20:12:41
Python
ddgryaz, 2020-10-15 20:12:41

How to re-work with pyglet after using multithreading? How to terminate/clean up running threads?

There is such a piece of code, I use it to display text on the screen at the same time and play the .mp3 file I need. In variable introductions = string

import time
import threading
import pyglet
from colorama import init
from colorama import Fore, Back, Style

def WelcomePrintMashin():
    for introductions in introduction:
        time.sleep(0.05)
        print(Fore.CYAN + introductions, end="", flush=True)
def WelcomMusic():
    WelcomeSong = pyglet.media.load('music/welcom11.mp3')
    WelcomeSong.play()
    pyglet.app.run()

def play1():
    while time.time() <= start_time:
        pass
    threading.Thread(target=WelcomMusic()).start()
def play2():
    while time.time() <= start_time:
        pass
    threading.Thread(target=WelcomePrintMashin()).start()
start_time=time.time()+1
threading.Thread(target=play1).start()
threading.Thread(target=play2).start()


Next, I needed to play the mp3 file again, I create:

VorotaOpenSong = pyglet.media.load('music/vorota_open.mp3')
VorotaOpenSong.play()
pyglet.app.run()


And I get this error:

Traceback (most recent call last):
  File "D:\PythonProject\CreateYouLife\main.py", line 114, in <module>
    pyglet.app.run()
  File "D:\PythonProject\CreateYouLife\venv\lib\site-packages\pyglet\app\__init__.py", line 107, in run
    event_loop.run()
  File "D:\PythonProject\CreateYouLife\venv\lib\site-packages\pyglet\app\base.py", line 162, in run
    platform_event_loop.start()
  File "D:\PythonProject\CreateYouLife\venv\lib\site-packages\pyglet\app\win32.py", line 89, in start
    raise RuntimeError('EventLoop.run() must be called from the same ' +
RuntimeError: EventLoop.run() must be called from the same thread that imports pyglet.app


Do I understand correctly that pyglet must be run from the same thread that was called earlier? Question: how to make it work? I don't quite understand how to terminate the previous threads forcibly or how to rewrite the condition so that the threads terminate and clean up themselves (if that helps me with this problem) The moment I call VorotaOpenSong.play() I don't need to work with multiple threads, I just you need to return to the mode when the program was running in one thread. I read the documentation on threading, unfortunately I could not find the answer to my question. Thank you!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
ddgryaz, 2020-10-16
@ddgryaz

I found a solution to my question, and it was hidden at the very beginning. I am incredibly and viciously surprised that everything turned out to be so simple. After all, initially I was looking for how to build such a structure so that both the text is printed and the sound is played back, I read about pyglet, pygame, GStreamer and a bunch of different options. As a result, threading was added to pyglet - multithreading. Everything became much more complicated, continuing to look for a solution to my question, and as it turned out to be an incredible simplification, I stumbled upon playsound.
Eventually

instead of the code you see in the question

import time
import threading
import pyglet
from colorama import init
from colorama import Fore, Back, Style

def WelcomePrintMashin():
    for introductions in introduction:
        time.sleep(0.05)
        print(Fore.CYAN + introductions, end="", flush=True)
def WelcomMusic():
    WelcomeSong = pyglet.media.load('music/welcom11.mp3')
    WelcomeSong.play()
    pyglet.app.run()

def play1():
    while time.time() <= start_time:
        pass
    threading.Thread(target=WelcomMusic()).start()
def play2():
    while time.time() <= start_time:
        pass
    threading.Thread(target=WelcomePrintMashin()).start()
start_time=time.time()+1
threading.Thread(target=play1).start()
threading.Thread(target=play2).start()</spoiler>

i used playsound:
from playsound import *
import time

def MusicPrintMashin():
    playsound('D:/PythonProject/welcom.mp3', block=False)
    for introductions in introduction:
        time.sleep(0.05)
        print(introductions, end="", flush=True)

It takes one argument - the path to the audio file you want to play. This can be a local file or a URL.
There is an optional second argument to block, which is set to True by default. If set to False, the function will run asynchronously.
This is what I needed! In general, I have not yet decided what to do, be glad that I figured out how to solve my problem, or smile to be angry that I spent a lot of time to deal with multithreading - threading.
I hope it will be useful to someone!

A
agent_2203, 2020-10-15
@agent_2203

I didn’t work with pyglet, but apparently the essence here is the same as in asyncio, you need to hold the main event, for example, in asyncio it can be changed and set from another thread
asyncio.set_event_loop(asyncio.new_event_loop())

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question