LINUX.ORG.RU

Убить процесс загрузки стрима в vlc.py

 , ,


0

1

Создаю плеер таким образом:

self.vlcInstance = vlc.Instance("--no-xlib --verbose 2")
self.player = self.vlcInstance.media_player_new()
self.player.set_mrl(<линк на стрим>)
self.player.play()
К примеру я запустил стрим, и тут же нажал на другой, то есть пошел процесс получения линка (до 5 сек.). Нужно дать понять vlc что бы он не запускал 2й канал, так как сколько бы я не запустил стримов, столько он их будет воспроизводить одновременно.
Вот поток в плеере (pyqt5):
class Play(QtCore.QThread):	
	sig = QtCore.pyqtSignal(int, int)

	def __init__(self, parent=None, *data):
		super(Play, self).__init__(parent)	

		self.parent = parent
		self.id = data[0]		

		self.parent.is_stop = False

		self.sig.connect(self.parent.updateProgress)
		self.playback = Streamer()
		self.start()

	def run(self):						
		uri = helpers.search.get_youtube_streams(self.id)
		self.playback.play(uri['audio'])

	def stop(self):
		self.playback.stop()
		self.exit()	
		return
Ну и сам враппер для плеера:
import vlc
import requests
from PyQt5 import QtCore

class Streamer():

	def __init__(self, *data):
		self.vlcInstance = vlc.Instance("--no-xlib --verbose 2")
		self.player = self.vlcInstance.media_player_new()


	def stop(self):
		self.player.stop()
		return

	def pause(self):
		pass

	def get_position(self):
		return self.player.get_position()

	def play(self, uri):		
		r = requests.get(uri)
		if r.status_code == 200:			
			print('play')
			
			self.player.set_mrl(uri)
			self.player.play()
		else:
			return
Завершение потока с помощью .exit() не решает проблему.

Если тебе надо, чтобы при запущенном стриме новые не запускались, то сделай булевый параметр, типа замка. А если надо, чтобы новые стримы становились в очередь, то делай очередь. Или ивент луп забабахай вообще.

Virtuos86 ★★★★★
()
Ответ на: комментарий от noname_user

И что, этот код не работает?

def stop(self):
	self.player.stop()
	return
Кстати, зачем ты пишешь пустые return в конце методов? return в явном виде нужен только для возвращения результата из функции, или для выхода из функции в произвольном месте.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

Нет, если поток будет в ожидании получения ссылки, то vlc по идее ее еще не получал и не может быть остановлен, а получит он ее тогда, когда api ее вернет, так вот я решил это с помощью эвентов самого vlc:

import vlc
import requests
from PyQt5 import QtCore

class Streamer():
	global flag
	flag = 0


	def __init__(self, *data):
		self.vlcInstance = vlc.Instance("--no-xlib --verbose 2")
		self.player = self.vlcInstance.media_player_new()
		event_manager = self.player.event_manager() # Attach event to player (next 3 lines)
		event=vlc.EventType()
		event_manager.event_attach(event.MediaPlayerStopped, self.end_reached)

	def end_reached(self):
		global flag
		flag = 1
		print("End reached!")

	def stop(self):
		self.player.stop()
		return

	def pause(self):
		pass

	def get_position(self):
		return self.player.get_position()

	def play(self, uri):
		print('play')
		m=self.vlcInstance.media_new(uri)
		
		self.player.set_media(m)
		m.release()
		self.player.play()
		while flag == 1: # Wait until the end of the first media has been reached...
			self.quit()
			return
И с помощью .terminate() того потока, который получал линк стрима и запускал плеер.
З.Ы. код с коленки, не обращайте внимание, только что набросал его

noname_user ★★★
() автор топика
Последнее исправление: noname_user (всего исправлений: 1)
Ответ на: комментарий от noname_user
while flag == 1: # Wait until the end of the first media has been reached...
		self.quit()
		return

Здесь точно есть смысл? По идее, этот код больше одного раза не будет выполнен, зачем цикл?

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

но ведь эвент поставит значение флагу = 1 в неизвестное для потока время, а именно когда юзер это сделает, именно поэтому флаг нужно чекать постоянно, если я понял суть вопроса

noname_user ★★★
() автор топика
Ответ на: комментарий от noname_user

По дефолту flag == 0. Цикл проверит условие flag == 1 первый раз, убедится, что оно не выполняется, и всё — завершит своё выполнение. То есть код цикла в принципе не отработает никогда в данном виде.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86
while True:
			# Wait until the end of the first media has been reached...
			if flag == 1:
				self.quit()
				break
			time.sleep(1)

И еще. Если flag — глобальная переменная, то первый же вызов end_reached выставит его в положение 1. После чего код

while flag == 1: # Wait until the end of the first media has been reached...
		self.quit()
		return
моментально сработает уже для второго стрима и всех последующих, естественно.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86
	def play(self, uri):
		print('play')
		m=self.vlcInstance.media_new(uri)
		
		self.player.set_media(m)
		m.release()
		self.player.play()
		while True:
			# Wait until the end of the first media has been reached...
			if flag == 1:
				self.quit()
				flag == 0
				break
			time.sleep(1)

Мне, правда, смутно что-то не нравится. Например, «flag» это не самое информативное имя, ну и глобальной переменной делать его не обязательно.

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от Virtuos86

По поводу глобального, писал уже, что на конденке набросал и нужно было уходить. Поповоду цикла, оно, действие в цикле выполнится ровно 1 раз для каждого стрима, почему ? Потому что эвент манагер у vlc ловит событие stop и тушит скрипт, а именно завершает поток свой

noname_user ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.