How can i Control VLC media player through a Python scripte - python

so I had this idea of controlling a media player from a python script like VLC for example, but since I am new to Python I don't know how to achieve that,
so let me explain what I am looking for is
for example, I want to get and set a volume value of VLC from my Python script?
I am not asking for a whole code or something like that just some tips to follow and thanks in advance

Install python-vlc
pip install python-vlc
Just change the path,your good to go..
from vlc import Instance
import time
import os
class VLC:
def __init__(self):
self.Player = Instance('--loop')
def addPlaylist(self):
self.mediaList = self.Player.media_list_new()
path = r"C:\Users\dell5567\Desktop\engsong"
songs = os.listdir(path)
for s in songs:
self.mediaList.add_media(self.Player.media_new(os.path.join(path,s)))
self.listPlayer = self.Player.media_list_player_new()
self.listPlayer.set_media_list(self.mediaList)
def play(self):
self.listPlayer.play()
def next(self):
self.listPlayer.next()
def pause(self):
self.listPlayer.pause()
def previous(self):
self.listPlayer.previous()
def stop(self):
self.listPlayer.stop()
Create a object
player = VLC()
Add playlist
player.addPlaylist()
Play the song
player.play()
time.sleep(9)
Play the next song
player.next()
time.sleep(9)
Pause the song
player.pause()
time.sleep(9)
Resume the song
player.play()
time.sleep(9)
Previous song
player.previous()
time.sleep(9)
Stop the song
player.stop()

Controlling vlc from tcp socket connection is better than vlc-ctrl. I tried vlc-ctrl in my raspberry pi,i cannot reach my expectation. So i decided to control the vlc player from socket connection.
Steps:-
1) you need to run from command prompt or from shell 'vlc --intf rc --rc-host 127.0.0.1:44500'[starting vlc player] to enable vlc player for controlling it from tcp connection.... you can start vlc like this from python using subprocess.
2) for cntrolling from python here is my sample script:
class player():
def __init__(self):
self.is_initiated = False
self.SEEK_TIME = 20
self.MAX_VOL = 512
self.MIN_VOL = 0
self.DEFAULT_VOL = 256
self.VOL_STEP = 13
self.current_vol = self.DEFAULT_VOL
def toggle_play(self):
if not self.is_initiated:
self.is_initiated = True
self.thrededreq("loop on")
self.thrededreq("random on")
self.thrededreq("add /home/pi/Desktop/Music")#adding the music folder
print("Init Playing")
return
self.thrededreq("pause")
print("Toggle play")
def next(self):
if not self.is_initiated:
self.toggle_play()
return
self.thrededreq("next")
print("Next")
pass
def prev(self):
if not self.is_initiated:
self.toggle_play()
return
self.thrededreq("prev")
print("Previous")
pass
def volup(self):
self.current_vol = self.current_vol + self.VOL_STEP
self.thrededreq("volume " + str(self.current_vol))
print("Volume up")
pass
def voldown(self):
self.current_vol = self.current_vol - self.VOL_STEP
self.thrededreq("volume " + str(self.current_vol))
print("Volume Down")
pass
def seek(self, forward: bool):
length = self._timeinfo("get_length")
print(length)
cur = self._timeinfo("get_time")
print(cur)
if (forward):
seekable = cur + self.SEEK_TIME
else:
seekable = cur - self.SEEK_TIME
if seekable > length:
seekable = length - 5
if seekable < 0:
seekable = 0
self.thrededreq("seek " + str(seekable))
print("Seek: ",seekable," Cur: ",cur,"Len: ",length)
pass
def _timeinfo(self, msg):
length = self.req(msg, True).split("\r\n")
if (len(length) < 2):
return None
length = length[1].split(" ")
if (len(length) < 2):
return None
try:
num = int(length[1])
return num
except:
return None
def req(self, msg: str, full=False):
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
# Connect to server and send data
sock.settimeout(0.7)
sock.connect(('127.0.0.1', 44500))
response = ""
received = ""
sock.sendall(bytes(msg + '\n', "utf-8"))
# if True:
try:
while (True):
received = (sock.recv(1024)).decode()
response = response + received
if full:
b = response.count("\r\n")
if response.count("\r\n") > 1:
sock.close()
break
else:
if response.count("\r\n") > 0:
sock.close()
break
except:
response = response + received
pass
sock.close()
return response
except:
return None
pass
def thrededreq(self, msg):
Thread(target=self.req, args=(msg,)).start()
#'vlc --intf rc --rc-host 127.0.0.1:44500' you need to run the vlc player from command line to allo controlling it via TCP
Player=player()
player.toggle_play()
#player.next()
#player.prev()
if you want more command and controlling,use"SocketTest" and connect to the port of vlc and check out....
this one has more control option than vlc-ctrl.

You can use python's module vlc-ctrl for this automation. And then use subprocess module module to execute its commands.
1) Install vlc-ctrl through pip
pip install vlc-ctrl
test.py: (To volume up)
import subprocess
subprocess.Popen(['vlc-ctrl', 'volume', '+10%'])
And run code with:
python test.py
More documentation for vlc-ctrl module here.

Related

Can't Pass Textual Inputs to Wesocket Client and store response

I am trying to send and receive web socket data using my Client.py file. I am also trying to load the prompts ("Username?") into the Feeler console and have input from InConsole stored in the username variable in the Client.py file. So far I have been unable to make this setup work.
What is the most efficient way for me to accomplish this task?
I have the following code in Feeler.py
...
def Message(output):
message = Client.main(output)
return message
class OutConsole(ScrollView):
prev = Text("")
async def eval(self, text_input):
pre_y = self.y
with console.capture() as capture:
try:
console.print(f"{text_input}")
except Exception:
console.print_exception(show_locals=True)
self.prev.append(Text.from_ansi(capture.get() + "\n"))
await self.update(self.prev)
self.y = pre_y
self.animate("y", self.window.virtual_size.height, duration=1, easing="linear")
class InConsole(TextInput):
def __init__(self, out):
super(InConsole, self).__init__()
self.out = out
async def on_key(self, event: events.Key) -> None:
if event.key == "enter":
await self.out.eval(self.value)
self.value = ""
class GridTest(App):
async def on_mount(self) -> None:
"""Make a simple grid arrangement."""
# Git code
output = OutConsole()
in_put = InConsole(out=output)
message = Message(output)
await output.eval(message)
...
I also Have this in Client.py
def main():
# Define the host IP and port for the server
HOST = socket.gethostname()
PORT = 5050
# Ask For initial username and password
return ("Username?")
username = input(">")
return ("Password?")
password = getpass.getpass(f"{username}> ")
The rest of my code can be found at https://github.com/DanielATucker/Brain/tree/Client for reference.
Thanks!

python calling different class methods by user input with terminating existing one

i'm trying to build personal assistant which is running by voice command.it is working perfectly with if: elif: blocks. but i want to create more elegance way and shorten code a bit.i try to create modular structure but i cant manage to terminate running function by calling middleman function with command=false parameter
i need some guiding please
main.py
from handler import middleman
while True:
message = input("> ")
if message != "":
middleman(message) #lets say command is "play1" than next command "play2"
Handler.py
from music import Class1
from music import Class2
def func1(context, command):
if command == True:
x = Class1(context)
x.run()
else:
x.stop() --> x not exist here gives error
def func2(context, command):
if command == True:
x = Class2(context)
x.run()
else:
x.stop()
def middleman(text):
command = True
if text == "stop":
command = False
function_name = globals()[text]
function_name(command)
music.py
import logging
import threading
import time
import pygame
class Player(threading.Thread):
def __init__(self, file_path, volume=1.0, start_time=0.0, master=None):
print("player started")
threading.Thread.__init__(self)
# 传入主窗口的指针,用于触发主窗口事件(若有)
self.master = master
self.file_path = file_path
# 音乐播放起点
self.start_time = start_time
# 用于控制音乐播放与停止
self.stop_state = False
# 用于控制音乐的暂停和恢复
self.pause_state = False
# 控制默认音量
self.volume = volume
# 初始化mixer
pygame.mixer.init() # 初始化音频
self.track = pygame.mixer.music
def set_volume(self, volume):
self.volume = volume
self.track.set_volume(self.volume)
def get_volume(self):
return self.volume
def run(self,stop):
print("stop word,stop")
try:
file = self.file_path
self.track.load(file) # 载入音乐文件
self.track.set_volume(self.volume) # 设置音量
self.track.play(start=self.start_time) # 开始播放
except Exception as e:
logging.warning(e)
if self.master:
self.master.event_generate("<<MusicError>>", when="tail")
while self.stop_state:
time.sleep(1)
# 若停止播放或播放结束,则结束这个线程
if self.stop_state:
self.track.stop() # 停止播放
return
elif not self.track.get_busy():
if self.master:
self.master.event_generate("<<CouldMusicStop>>", when="tail")
return
elif not self.stop_state and self.pause_state:
self.track.pause() # 暂停播放
elif not self.stop_state and not self.pause_state:
self.track.unpause() # 恢复播放
def stop(self):
self.stop_state=True
self.player = None

Run a GUI and play a alarm sound simultaneously in python using easygui and pyaudio

Hi I need to run my gui simultaneously with my alarm sound and stop the iterating alarm sound when i click ok button in the 2nd dialog box. To achieve this task i created 2 files which is the main file(gui using easygui) and the AudioFile class witch uses pyaudio to play and stop alarm sound.
main file:
from easygui import *
import sys
from AudioFile import *
predictions[0] = 1
a = AudioFile("alarm.wav")
if (predictions[0] == 1):
while 1:
#play alarm sound
a.play()
msgbox("Critical Situation Detected!")
msg ="Please choose an action?"
title = "Critical Situation Detected!"
choices = ["Ignore the Warning", "Contact Doctor", "Call Ambulance Service", "Call Hospital"]
#choice = choicebox(msg, title, choices)
choice = multchoicebox(msg, title, choices)
#stop alarm sound
a.close()
# note that we convert choice to string, in case
# the user cancelled the choice, and we got None.
msgbox("You chose: " + str(choice), "Action is in Progress")
msg = "Do you want to continue?"
title = "Please Confirm"
if ccbox(msg, title): # show a Continue/Cancel dialog
pass # user chose Continue
else:
sys.exit(0) # user chose Cancel
AudioFile:
import pyaudio
import wave
import sys
class AudioFile:
chunk = 1024
def __init__(self, file):
""" Init audio stream """
self.wf = wave.open(file, 'rb')
self.p = pyaudio.PyAudio()
self.stream = self.p.open(
format = self.p.get_format_from_width(self.wf.getsampwidth()),
channels = self.wf.getnchannels(),
rate = self.wf.getframerate(),
output = True
)
def play(self):
""" Play entire file """
data = self.wf.readframes(self.chunk)
while data != '':
self.stream.write(data)
data = self.wf.readframes(self.chunk)
def close(self):
""" Graceful shutdown """
self.stream.close()
self.p.terminate()
# Usage example for pyaudio
#a = AudioFile("alarm.wav")
#a.play()
#a.close()
When i run this two codes using main file i wanted to run the alarm sound first and in background the gui should appear in the window and when i select the choices from the second window and i press ok it should stop the alarm sound but instead of that first my application play the alarm sound after it is over it start the gui. how should i play my alarm sound in the background of the gui and close it after i press the second ok button?
Currently, when you run the AudioFile.play() method you will play the entire file before the msgbox("Critical Situation Detected!") command is executed.
The solution to this would be to run the alarm in a thread such that control remains in the while loop in your main file.
An example of what the threaded alarm might look like (minus the details) would be:
from threading import Thread,Event
from time import sleep
class AudioFile(Thread):
def __init__(self):
Thread.__init__(self)
self._stop = Event()
def run(self):
self._stop.clear()
# in this case we loop until the stop event is set
while not self._stop.is_set():
print "BEEP BEEP BEEP!"
sleep(0.2)
def stop(self):
self._stop.set()
In your main code you would then replace a.play and a.close by a.start and a.stop. For example:
x = AudioFile()
x.start()
sleep(4)
x.stop()
I came up with the solution based on #ebarr sample code.
main file:
predictions[0] = 1
a = AudioFile("alarm.wav")
if (predictions[0] == 1):
while 1:
a.start()
sleep(0.5)
msgbox("Critical Situation Detected!")
msg ="Please choose an action?"
title = "Critical Situation Detected!"
choices = ["Ignore the Warning", "Contact Doctor", "Call Ambulance Service", "Call Hospital"]
#choice = choicebox(msg, title, choices)
choice = multchoicebox(msg, title, choices)
a.stop()
# note that we convert choice to string, in case
# the user cancelled the choice, and we got None.
msgbox("You chose: " + str(choice), "Action is in Progress")
msg = "Do you want to continue?"
title = "Please Confirm"
if ccbox(msg, title): # show a Continue/Cancel dialog
pass # user chose Continue
else:
sys.exit(0) # user chose Cancel
AudioFile:
import pyaudio
import wave
import sys
from threading import Thread,Event
from time import sleep
class AudioFile(Thread):
chunk = 1024
def __init__(self, file):
""" Init audio stream """
Thread.__init__(self)
self.wf = wave.open(file, 'rb')
self.p = pyaudio.PyAudio()
self.stream = self.p.open(
format = self.p.get_format_from_width(self.wf.getsampwidth()),
channels = self.wf.getnchannels(),
rate = self.wf.getframerate(),
output = True
)
self._stop = Event()
def run(self):
self._stop.clear()
""" Play entire file """
while not self._stop.is_set():
data = self.wf.readframes(self.chunk)
self.stream.write(data)
def stop(self):
""" Graceful shutdown """
self._stop.set()
self.stream.close()
self.p.terminate()

Python socket.connect in for loop

I am writing a program in Python and a part of it is scanning for active ports on a website. in the module scanports, while if I were to say scan ports 79 to 81, I know that it should return a list with 80 in it. I know this for sure because when I run scanport it shows port 80 is up. Sorry for not having any comments:
import subprocess, socket, urllib2, sys
class pymap:
def __init__(self):
pass
################################################################################
################################################################################
def host(self, host):
self.host = host
socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock = socket1
################################################################################
################################################################################
def getip(self):
if self.host == None:
print "Specify a host first."
else:
return socket.gethostbyname(self.host)
################################################################################
################################################################################
def scanports(self, start, end):
ports = []
self.sock.settimeout(0.000001)
for i in xrange(start, end+1): #49151
try:
self.sock.connect((self.host, i))
ports.append(i)
except:
pass
return i
################################################################################
################################################################################
def scanport(self, port1):
self.sock.settimeout(0.000001)
try:
self.sock.connect((self.host, port1))
return 1
except:
return 0
################################################################################
################################################################################
def traceroute(self):
if self.host == None:
print "Specify a host first."
else:
proc=subprocess.Popen(('tracert', self.host), shell=True, stdout=subprocess.PIPE)
output=proc.communicate()[0]
return output
################################################################################
################################################################################
def getsource(self, url):
page = urllib2.urlopen(url)
return page.read()
################################################################################
################################################################################
x = pymap()
x.host("www.google.com")
print x.scanports(70, 85)
print x.scanport(80)
EDIT:
I changed it, thanks James Henstridge for pointing out that I was using the iteration variable, otherwise it would be much harder. However, it still doesn't work:
def scanports(self, start, end):
ports = []
self.sock.settimeout(3)
for i in xrange(start, end+1): #49151
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((self.host, port1))
self.sock.close()
ports.append(i)
except:
pass
return ports
EDIT: I figured it out, it was a problem with ports.append, thanks for your help.
There are a few issues with your code:
Your scanports method is returning the loop iteration variable, so it will always return end no matter what ports it detects. Perhaps you meant to return the ports list instead?
You are reusing the same socket over and over. From the connect system call man page:
Generally, connection-based protocol sockets may successfully connect() only once
So if you want to test multiple connection attempts, create a new socket each time. You should also close those sockets after use.

Python Access to BaseRequestHandler

My code basically needs to start up a simple chat server with a client. Where the server and the client can talk back and forth to each other. I've gotten everything to be implemented correctly, but I can't figure out how to shut down the server whenever I'm done. (I know it's ss.shutdown()).
I'm wanting to end right now based on a keyword shared between the two (something like "bye"), but I don't know if I can somehow send a message to my SocketServer from BaseRequestHandler to shutdown() whenever it receives the message.
Eventually, my goal is to incorporate Tkinter to make a GUI, but I wanted to get everything else to work first, and this is my first time dealing with sockets in Python.
from sys import argv, stderr
from threading import Thread
import socket
import SocketServer
import threading
import sys
class ThreadedRecv(Thread):
def __init__(self,socket):
Thread.__init__(self)
self.__socket = socket
self.__message = ''
self.__done = False
def recv(self):
while self.__message.strip() != "bye" and not self.getStatus():
self.__message = self.__socket.recv(4096)
print 'received',self.__message
self.setStatus(True)
def run(self):
self.recv()
def setStatus(self,status):
self.__done = status
def getStatus(self):
return self.__done
class ThreadedSend(Thread):
def __init__(self,socket):
Thread.__init__(self)
self.__socket = socket
self.__message = ''
self.__done = False
def send(self):
while self.__message != "bye" and not self.getStatus():
self.__message = raw_input()
self.__socket.send(self.__message)
self.setStatus(True)
def run(self):
self.send()
def setStatus(self,status):
self.__done = status
def getStatus(self):
return self.__done
class HostException(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class EchoServer(SocketServer.BaseRequestHandler):
def setup(self):
print self.client_address, 'is connected!'
self.request.send('Hello ' + str(self.client_address) + '\n')
self.__done = False
def handle(self):
sender = ThreadedSend(self.request)
recver = ThreadedRecv(self.request)
sender.start()
recver.start()
while 1:
if recver.getStatus():
sender.setStatus(True)
break
if sender.getStatus():
recver.setStatus(True)
break
def finish(self):
print self.client_address, 'disconnected'
self.request.send('bye client %s\n' % str(self.client_address))
self.setDone(True)
def setDone(self,done):
self.__done = done
def getDone(self):
return self.__done
def setup(arg1, arg2, arg3):
server = False
defaultPort,defaultHost = 2358,"localhost"
hosts = []
port = defaultPort
serverNames = ["TRUE","SERVER","S","YES"]
arg1 = arg1.upper()
arg2 = arg2.upper()
arg3 = arg3.upper()
if arg1 in serverNames or arg2 in serverNames or arg3 in serverNames:
server = True
try:
port = int(arg1)
if arg2 != '':
hosts.append(arg2)
except ValueError:
if arg1 != '':
hosts.append(arg1)
try:
port = int(arg2)
if arg3 != '':
hosts.append(arg3)
except ValueError:
if arg2 != '':
hosts.append(arg2)
try:
port = int(arg3)
except ValueError:
if arg3 != '':
hosts.append(arg3)
port = defaultPort
for sn in serverNames:
if sn in hosts:
hosts.remove(sn)
try:
if len(hosts) != 1:
raise HostException("Either more than one or no host "+ \
"declared. Setting host to localhost.")
except HostException as error:
print error.value, "Setting hosts to default"
return (server,defaultHost,port)
return (server,hosts[0].lower(),port)
def main():
bufsize = 4096
while len(argv[1:4]) < 3:
argv.append('')
settings = setup(*argv[1:4])
connections = (settings[1],settings[2])
print connections
if not settings[0]:
try:
mySocket = socket.socket(socket.AF_INET,\
socket.SOCK_STREAM)
except socket.error, msg:
stderr.write("[ERROR] %s\n" % msg[1])
sys.exit(1)
try:
mySocket.connect(connections)
except socket.error, msg:
stderr.write("[ERROR] %s\n" % msg[1])
sys.exit(2)
message = ""
print "Enter a message to send to the server. "+\
"Enter \"bye\" to quit."
sender = ThreadedSend(mySocket)
recver = ThreadedRecv(mySocket)
sender.start()
recver.start()
while 1:
if sender.getStatus():
recver.setStatus(True)
break
if recver.getStatus():
sender.setStatus(True)
break
else:
xserverhandler = EchoServer
serversocket = SocketServer.ThreadedTCPServer(\
connections,xserverhandler)
server_thread = Thread(target = serversocket.serve_forever)
server_thread.setDaemon(True)
server_thread.start()
# I would like to shut down this server whenever
# I get done talking to it.
"""while 1:
if xserverhandler.getDone():
print 'This is now true!'
serversocket.shutdown()
break"""
if __name__ == '__main__':
main()
Yeah, I know setup() is a terrible function right now with the try's and catches, but it works for now, so I was going to fix it later.
My question is basically: How can I get the server to actually end based on a message that it receives? If possible, is there a way to access the Request Handler after it's started?
Please fix your code so it works, and include some way to use it. You need to add
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
since SocketServer doesn't actually include that class (at least not in my version of 2.6 nor 2.7). Instead, it's an example from the SocketServer definition.
Please include an example of how to start/use the code. In this case to start the server you need to do:
ss.py SERVER localhost 8001
and the client as
ss.py localhost 8001
If you do that then you can't do server_thread.setDaemon(True) because there are no other threads running, which means the server will exit immediately.
Once that's done the solution is to add a call (or two) to self.server.shutdown() insdie of your EchoServer.handle method, like:
while 1:
if recver.getStatus():
sender.setStatus(True)
self.server.shutdown()
break
However, I can't get that to work, and I think it's because I inherited things wrong, or guessed wrong in what you did.
What you should do is search for someone else who has done a chat server in Python. Using Google I found http://www.slideshare.net/didip/socket-programming-in-python and there are certainly others.
Also, if you are going to mix GUI and threaded programming then you should look into examples based on that. There are a number of hits when I searched for "tkinter chat". Also, you might want to look into twisted, which has solved a lot of these problems already.
What problems? Well, for example, you likely want an SO_REUSEADDR socket option.
Request handler object is created for each new request. So you have to store "done" flag in server, not handler. Something like the following:
class EchoServer(SocketServer.BaseRequestHandler):
...
def setDone(self):
self.server.setDone() # or even better directly self.server.shutdown()

Categories

Resources