I'd like to do the exact same thing that is explained here :
How to continuously monitor rhythmbox for track change using python
but with Clementine instead of Rhythmbox.
Problem is, I couldn't find the equivalent of playingUriChanged to give to the connect_to_signal method.
The only thing I could find with qdbus that seemed relevant was
signal void org.freedesktop.MediaPlayer.TrackChange(QVariantMap)
but it takes a parameter.
I'm not familiar with DBus so any help is appreciated.
Thanks
It does not take a parameter, it returns parameter (hash map)
code extracted from this script:
def TrackChange(Track):
# use Track["URI"], Track["title"], Track["artist"] etc
def Connect(name):
global root, player, tracklist
# first we connect to the objects
root_o = bus.get_object(name, "/")
player_o = bus.get_object(name, "/Player")
tracklist_o = bus.get_object(name, "/TrackList")
# there is only 1 interface per object
root = dbus.Interface(root_o, "org.freedesktop.MediaPlayer")
tracklist = dbus.Interface(tracklist_o, "org.freedesktop.MediaPlayer")
player = dbus.Interface(player_o, "org.freedesktop.MediaPlayer")
# connect to the TrackChange signal
player_o.connect_to_signal("TrackChange", TrackChange, dbus_interface="org.freedesktop.MediaPlayer")
Related
I'm having trouble with the engine encapsulation of python-chess, I would like to use the Stockfish function top = stockfish.get_top_moves(5) but it seems like there is no way to do it using chess.engine.simpleEngine, do you have any advices?
I already tried getting all the result and then keeping just the top 5 move of the last evaluation using this piece of code:
self.engine.analysis(self.board, chess.engine.Limit(depth=18), multipv=5, root_moves = move_actions)
but it's tricky since the function is asyncronous and I'm integrating with other function that are not changeable I cannot make it asynchronous.
I'm going crazy trying to make it work, thanks to everybody.
The async object returned by that function is empty at first; you can wait until it is done by calling its .wait() method. Instead, if you don't want the async parts of engine.analysis, you can call engine.analyse which blocks until done and returns the result more directly. Both functions work to get the top 5 moves as you requested. Here is an example script:
import chess
import chess.engine
stockfish = chess.engine.SimpleEngine.popen_uci("<file path to engine>")
# Using engine.analysis
analysis_result = stockfish.analysis(chess.Board(), limit=chess.engine.Limit(depth=18), multipv=5)
analysis_result.wait() # This is the missing step
analysed_variations = analysis_result.multipv
# Or instead using engine.analyse
analysed_variations = stockfish.analyse(chess.Board(), limit=chess.engine.Limit(depth=18), multipv=5)
# Either way you now have a dict of results, with moves under "pv"
top_five_moves = [variation["pv"][0] for variation in analysed_variations]
I am trying to get one boolean attribute (A) to change another(B). The one to be controlled (B) already has a script job running it and so I can't create a set driven key, direct connection, or expression to control it, so I'm trying another script job, since running the script function by itself achieves the desired result. I just can't figure out how to tie that script to run to the attribute change (B) that I want to drive it by (A).
This is placed in a script node set to the open gui trigger (to load when maya opens as I understand it). Here's a screenshot.
What am I missing here?
import maya.cmds as cmds
def togglePicker(pickerAttr):
cmds.setAttr(pickerAttr, not 0)
nameSpace = cmds.ls(sl=True)[0].rpartition(':')[0]
if len(nameSpace) > 0:
pickerAttr = nameSpace + ':Main.picker'
myPickerAttr = nameSpace + ':MoverMain_Cntrl.Picker'
else:
pickerAttr = 'Main.picker'
myPickerAttr = 'MoverMain_Cntrl.Picker'
cmds.scriptJob(attributeChange=[myPickerAttr,togglePicker])
Your script node is executed every time when maya loads a scene, not when it is started, at least that's what the docs say. So every time you load a scene, a new scriptJob is created.
Your script should show an error message since the togglePicker() function is called without an argument, but it requires an argument. Even if it works, it will not work.. what you do at the moment is the following:
As soon as you turn on the MoverMain_Cntrl.Picker attribute, the togglePicker() function is called and turns it on, even if you turn it off. The pickerAttrvariable is not used. So you should have a look at your program logic.
You can solve the agrument problem by using the partial function like this:
import maya.cmds as cmds
from functools import partial
def togglePicker(pickerAttr):
cmds.setAttr(pickerAttr, not 0)
nameSpace = cmds.ls(sl=True)[0].rpartition(':')[0]
if len(nameSpace) > 0:
pickerAttr = nameSpace + ':Main.picker'
myPickerAttr = nameSpace + ':MoverMain_Cntrl.Picker'
else:
pickerAttr = 'Main.picker'
myPickerAttr = 'MoverMain_Cntrl.Picker'
cmds.scriptJob(attributeChange=[myPickerAttr,partial(togglePicker, pickerAttr)])
I got it to work! (previously I had switched to the script node to MEL so I could test the mel command mentioned in the comments that did work, but I forgot to switch back to python when I realized the selection issue I also mentioned in the comments).
So here's what worked, where I know I'll have to manually change the namespace name in case the scene file name changes:
import maya.cmds as cmds
def togglePicker():
cmds.setAttr(pickerAttr, not 0)
if cmds.namespace(exists='ExtremeBallRig_v008'):
pickerAttr = 'ExtremeBallRig_v008:Main.picker'
myPickerAttr = 'ExtremeBallRig_v008:MoverMain_Cntrl.Picker'
else:
pickerAttr = 'Main.picker'
myPickerAttr = 'MoverMain_Cntrl.Picker'
cmds.scriptJob(attributeChange=[myPickerAttr,togglePicker])
Whenever audio is playing in windows 10, whether it is from Spotify, Firefox, or a game. When you turn the volume, windows has a thing in the corner that says the song artist, title, and what app is playing like the photo below (sometimes it only says what app is playing sound if a game is playing the sound)
I want to somehow get that data with python. My end goal, is to mute an application if it is playing something I don't like, such as an advertisement.
Turns out this is possible without a workaround and by accessing this info directly using the Windows Runtime API (winrt).
All code shown uses Python 3 and the winrt library installed via pip
Collecting Media/'Now Playing' information
The following code allows for you to collect a dictionary of the media information available to Windows using the winrt wrapper for the Windows Runtime API. It does not rely on a window's title/application name changing as in the other answers here.
import asyncio
from winrt.windows.media.control import \
GlobalSystemMediaTransportControlsSessionManager as MediaManager
async def get_media_info():
sessions = await MediaManager.request_async()
# This source_app_user_model_id check and if statement is optional
# Use it if you want to only get a certain player/program's media
# (e.g. only chrome.exe's media not any other program's).
# To get the ID, use a breakpoint() to run sessions.get_current_session()
# while the media you want to get is playing.
# Then set TARGET_ID to the string this call returns.
current_session = sessions.get_current_session()
if current_session: # there needs to be a media session running
if current_session.source_app_user_model_id == TARGET_ID:
info = await current_session.try_get_media_properties_async()
# song_attr[0] != '_' ignores system attributes
info_dict = {song_attr: info.__getattribute__(song_attr) for song_attr in dir(info) if song_attr[0] != '_'}
# converts winrt vector to list
info_dict['genres'] = list(info_dict['genres'])
return info_dict
# It could be possible to select a program from a list of current
# available ones. I just haven't implemented this here for my use case.
# See references for more information.
raise Exception('TARGET_PROGRAM is not the current media session')
if __name__ == '__main__':
current_media_info = asyncio.run(get_media_info())
current_media_info will be a dictionary in the following format and information can then be accessed as required within the program:
{
'album_artist': str,
'album_title': str,
'album_track_count': int,
'artist': str,
'genres': list,
'playback_type': int,
'subtitle': str,
'thumbnail':
<_winrt_Windows_Storage_Streams.IRandomAccessStreamReference object at ?>,
'title': str,
'track_number': int,
}
Controlling Media
As the OP says that their end goal is to control media, this should be possible with the same libraries. See here for more information possibly (I didn't need this in my case):
Microsoft WinRT Docs - Windows.Media.Control - GlobalSystemMediaTransportControlsSession class
(e.g. await current_session.try_pause_async())
(Getting Media thumbnail)
It is in fact possible to also 'scrape' the album art/media thumbnail (displayed on the right in the OP's screenshot) of the media currently playing (although the OP didn't ask for this but someone might want to do it):
from winrt.windows.storage.streams import \
DataReader, Buffer, InputStreamOptions
async def read_stream_into_buffer(stream_ref, buffer):
readable_stream = await stream_ref.open_read_async()
readable_stream.read_async(buffer, buffer.capacity, InputStreamOptions.READ_AHEAD)
# create the current_media_info dict with the earlier code first
thumb_stream_ref = current_media_info['thumbnail']
# 5MB (5 million byte) buffer - thumbnail unlikely to be larger
thumb_read_buffer = Buffer(5000000)
# copies data from data stream reference into buffer created above
asyncio.run(read_stream_into_buffer(thumb_stream_ref, thumb_read_buffer))
# reads data (as bytes) from buffer
buffer_reader = DataReader.from_buffer(thumb_read_buffer)
byte_buffer = buffer_reader.read_bytes(thumb_read_buffer.length)
with open('media_thumb.jpg', 'wb+') as fobj:
fobj.write(bytearray(byte_buffer))
This will save a media_thumb.jpg to the current working directory (cwd) which can then be used elsewhere for whatever.
Docs & References:
Stackoverflow - The main 'inspiration' for this Python answer; originally in C#
Github xlang - Using Windows RT API with xlang and Python
Github xlang - Async usage for IAsync* interface methods
Microsoft WinRT Docs - Windows.Media.Control - TryGetMediaPropertiesAsync()
Microsoft WinRT Docs - Windows.Storage.Streams - IBuffer Interface
Potentially chose from multiple available media streams?
Please note that I haven't tested or tried this and is merely a pointer for anyone who may want to experiment:
Microsoft WinRT Docs - Windows.Media.Control - GetSessions()
(would be accessed with sessions.get_sessions() above)
As opposed to current use of
Microsoft WinRT Docs - Windows.Media.Control - GetCurrentSession()
(accessed with sessions.get_current_session() above)
I am getting the titles of the windows to get the song information. Usually, the application name is displayed in the title, but when it is playing a song, the song name is shown. Here is a function that returns a list of all the window titles.
from __future__ import print_function
import ctypes
def get_titles():
EnumWindows = ctypes.windll.user32.EnumWindows
EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
GetWindowText = ctypes.windll.user32.GetWindowTextW
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
IsWindowVisible = ctypes.windll.user32.IsWindowVisible
titles = []
def foreach_window(hwnd, lParam):
if IsWindowVisible(hwnd):
length = GetWindowTextLength(hwnd)
buff = ctypes.create_unicode_buffer(length + 1)
GetWindowText(hwnd, buff, length + 1)
titles.append(buff.value)
return True
EnumWindows(EnumWindowsProc(foreach_window), 0)
return titles
I don't have an example of how to do it in python, instead I can point you in the right direction. What you want is to use winrt python module https://github.com/microsoft/xlang/blob/master/src/package/pywinrt/projection/readme.md to access WinRT api https://learn.microsoft.com/en-us/uwp/api/windows.media?view=winrt-19041 . There is not a lot of documentation around winrt python module so you might have to dig around the win rt api documentation to figure out how. Good luck!
I'm using the Deezer NativeSDK Python wrapper available here : https://github.com/deezer/native-sdk-samples
I'm playing user's "Flow" radio deezer_app.load_content("dzradio:///user-12345".encode('utf-8')) . How can I recover the playing track information or at least the track id ?
Thank you
The information is available through the QUEUELIST_TRACK_SELECTED event.
The function Player.event_track_selected_dzapiinfo(event) will return the JSON of the current track selected.
I have updated the PythonSample of https://github.com/deezer/native-sdk-samples to illustrate it. (you can check myDeezerApp.py)
The corresponding SDK function wrappers have been added in (deezer_import.py)
libdeezer.dz_player_event_track_selected_dzapiinfo.argtypes = [c_void_p]
libdeezer.dz_player_event_track_selected_dzapiinfo.restype = c_char_p
I am working with Kynect + Python (without using Micosoft visual studio), on windows 7.
Does anybody know how to get frames from Kinect without using an event loop?
I am refering to this method of PyKinect/nui/init.py
def get_next_frame(self, milliseconds_to_wait = 0):
# TODO: Allow user to provide a NUI_IMAGE_FRAME ?
return self.runtime._nui.NuiImageStreamGetNextFrame(self._stream, milliseconds_to_wait)
The above function is what I need and it isn't implemented yet. I need it to get frames on demand (without using an event loop).
How can I do this?
I am using the following environment and versions:
Python 2.7.2
PyKinect 2.1b1
Kinect sensor (from XBOX v1)
Kinect SDK 1.8
Windows 7
You cannot get RGB or depth or skeleton frame "on demand". Kinect data are provided by events, so you have to use them to got data.
The only thing that you can do to workaround this event-based system, is to save your data in a global variable, and then read that variable whenever you need it.
For instance, let's say that you associate a function named depth_frame_ready to the event related to depth data:
from pykinect import nui
with nui.Runtime() as kinect:
kinect.depth_frame_ready += depth_frame_ready
kinect.depth_stream.open(nui.ImageStreamType.Depth, 2, nui.ImageResolution.Resolution320x240, nui.ImageType.Depth)
You can write the depth_frame_ready function to save data on a global variable (let's say depth_data). You will also need a synchronization mechanism to read and write that variable (a simple Lock to avoid simultaneously writing and reading):
import threading
import pygame
DEPTH_WINSIZE = 320,240
tmp_s = pygame.Surface(DEPTH_WINSIZE, 0, 16)
depth_data = None
depth_lock = threading.Lock()
def update_depth_data(new_depth_data):
global depth_data
depth_lock.acquire()
depth_data = new_depth_data
depth_lock.release()
#based on https://bitbucket.org/snippets/VitoGentile/Eoze
def depth_frame_ready(frame):
# Copy raw data in a temp surface
frame.image.copy_bits(tmp_s._pixels_address)
update_depth_data((pygame.surfarray.pixels2d(tmp_s) >> 3) & 4095)
Now, if you need to use depth data, you can refer to the global variable whenever you want.
global depth_data
if depth_data is not None:
#read your data
Remember to use depth_lock to synchronize the access, as done in the update_depth_data() function.