如何在另一个方法仍在运行Python时调用该方法

2024-04-19 22:25:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个python程序,它从给定的YouTube视频url中提取声音并播放。我创建了play_vid方法来播放声音,创建了pause_vid方法来暂停声音。问题是,当声音仍在play_vid方法中播放时,我尝试调用pause_vid方法,但调用被忽略,play_vid方法继续运行。例如:

vid = Video("youtubelink")
vid.play_vid()
time.sleep(5)
# The sound keeps playing/this method call is being ignored
vid.pause_vid()

调用pause_vid方法时,如何终止play_vid方法?我已经研究了一段时间,没能找到解决这个问题的办法。完整程序:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time, os, vlc, requests
from mutagen.mp3 import MP3


class InvalidUrl(Exception):
    def __init__(self, message="Invalid video url!"):
        super().__init__(message)


class Video:
    def __init__(self, url):
        self.url = url
        self.paused = False
        self.player = ""
        self.is_valid()
        self.time_sleep = 0

    def play_vid(self):
        driver = webdriver.Chrome("C:\chromedriver.exe")
        driver.get("https://ytmp3.cc/en14/")
        element = driver.find_element_by_id("input")
        element.send_keys(self.url)
        button = driver.find_element_by_id("submit")
        button.click()
        wait = WebDriverWait(driver, 10)
        button2 = wait.until(EC.visibility_of_element_located((By.XPATH, '//*[@id="buttons"]/a[1]')))
        button2.click()
        vid_name = driver.find_element_by_xpath('//*[@id="title"]').text
        vid_name = vid_name.replace("| ", "")
        file_name = os.path.expanduser(r"~\Downloads\{}.mp3".format(vid_name))

        while not os.path.exists(file_name):
            time.sleep(1)

        driver.close()
        self.player = vlc.MediaPlayer()
        media = vlc.Media(file_name)
        self.player.set_media(media)
        self.player.play()
        audio = MP3(file_name)
        audio_info = audio.info
        length_in_secs = int(audio_info.length)

        while self.time_sleep != length_in_secs:
            if self.paused is True:
                return

            time.sleep(1)
            self.time_sleep += 1

    def pause_vid(self):
        self.paused = True

    def is_valid(self):
        r = requests.get(self.url)

        if "Video unavailable" in r.text:
            raise InvalidUrl

非常感谢Mark M让我知道我忘了在pause_vid方法中添加self.player.set_pause(1)。他还建议我删除while循环,因此我在主程序中使用time.sleep来决定视频将播放多长时间,而不是while循环。更新代码:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time, os, vlc, requests
from mutagen.mp3 import MP3


class InvalidYouTubeUrl(Exception):
    def __init__(self, message="Invalid YouTube url!"):
        super().__init__(message)


class Video:
    def __init__(self, url):
        self.url = url
        self.player = None
        self.is_valid()
        self.vid_len = None

    def play_vid(self):
        driver = webdriver.Chrome("C:\chromedriver.exe")
        driver.get("https://ytmp3.cc/en14/")
        element = driver.find_element_by_id("input")
        element.send_keys(self.url)
        button = driver.find_element_by_id("submit")
        button.click()
        wait = WebDriverWait(driver, 10)
        button2 = wait.until(EC.visibility_of_element_located((By.XPATH, '//*[@id="buttons"]/a[1]')))
        button2.click()
        vid_name = driver.find_element_by_xpath('//*[@id="title"]').text
        vid_name = vid_name.replace("| ", "")
        file_name = os.path.expanduser(r"~\Downloads\{}.mp3".format(vid_name))

        while not os.path.exists(file_name):
            time.sleep(1)

        driver.close()
        self.player = vlc.MediaPlayer()
        media = vlc.Media(file_name)
        self.player.set_media(media)
        self.player.play()
        audio = MP3(file_name)
        audio_info = audio.info
        self.vid_len = int(audio_info.length)

    def pause_vid(self):
        self.player.set_pause(1)

    def is_valid(self):
        r = requests.get(self.url)

        if "Video unavailable" in r.text:
            raise InvalidYouTubeUrl

我还找到了在主程序中播放整个声音的方法:

import pyytmp3, time

vid = pyytmp3.Video("youtubelink")
vid.play_vid()
time.sleep(vid.vid_len)

我基本上只是把节目推迟了视频的长度


Tags: 方法namefromimportselfurlplaytime
1条回答
网友
1楼 · 发布于 2024-04-19 22:25:28

问题有两个方面:

  1. 您实际上并没有暂停音频播放,因此MediaPlayer将继续播放其余部分。根据MediaPlayer文档,它有一个函数pause()甚至stop()。从pause\u vid方法调用此选项
  2. 您需要从另一个线程调用vid.pause_vid()方法,因为play_vid()方法将一直运行到完成。您可以创建一个背景线程来播放视频。这里有一些很好的例子https://pymotw.com/3/threading/经过再三考虑,我认为MediaPlayer.play()方法已经在后台运行,这是由于文档中的措辞:

Play. @return: 0 if playback started (and was already started), or -1 on error.

相关问题 更多 >