I am trying to record a live stream in vlc. It is easy if I use the GUI, just clicking on Convert/Save in the Media option, and after that choosing the stream address in the Network tab. I wanted to do the same thing in a C/C++/Python program. In case of a C program, I used Visual Studio but on writing #include<vlc/vlc.h> it says the file cannot be included. Then I downloaded the source from git but still it is not working. What to do?
You can save a stream using commandline arguments:
vlc scheme://host/stream.xyz --sout file/muxer:stream.xyz
and thus, call it using some kind of exec() (or its windows equivalent).
Then, the following answer: https://stackoverflow.com/a/19484168/1290438 shows how to open a stream in VLC in python:
import vlc
i = vlc.Instance('--verbose 2'.split())
p = i.media_player_new()
p.set_mrl('rtp://#224.1.1.1')
p.play()
So I guess, at worst, you can give the --sout argument to vlc.Instance, or at best there's a method on the instance to set up stream output.
In my humble opinion, using C/C++ for such a simple task is like killing a fly using a bazooka…
Related
How can I send keystrokes and mouse movements to a specific running program through its PID. I've used both pywinauto and pynput, and they work great, but I want to send keys to a program that is not in focus. I found this question: How to I send keystroke to Linux process in Python by PID? but it never explains what filePath is a path to.
If you could help solve for this example, that would be great! I want to send the "d" key to an open Minecraft tab for 10 seconds, and then send the "a" key for the next 10 seconds and stop. I would need this to be able to run in the background, so it could not send the keys to the computer as a whole, but only to the Minecraft tab. I am on Windows 10 by the way.
Any help would be appreciated!
Pretty sure you won't be able to, at least not easily let me explain a little bit how all of this works.
Lets start with the hardware and os, the OS has certain functions to read the input you give the computer. This input goes into a "pipe", the OS is reading input, and putting into the pipe, on the other side of the pipe there may be an application running, or it may not. The OS typically manages this (which app to put on the pipe listening) by defining which app/window is active. Apps access this pipe with the API given by the OS, they read the input and decide on it.
The libraries you cited above, change the values of the keyboard and mouse, in other words, they make the OS read other values, not the real ones, then the OS puts them in the "pipe", and are read by the app that is listening on the pipe (the one active). Some apps have their own API's for this, but I would guess Minecraft doesn't. If they don't have an API, what can you do? well, as I said, nothing easy, first of all "hacking" the app, in other words change it to listen to some other input/output rather than the one given by the OS, (this would be you making your own API). The other one would be you changing the OS, which would also be extremely hard, but maybe a tiny bitty easier. It also depends on your OS, I think Microsoft does offer input injection api's
So, simple options, first, run a VM with a GUI and use pywinauto, pyautogui, etc. The other option would be if you can run it in the browser, do so, and use something like Selenium to automate the input.
Quick note, why does selenium works and the browser can read input in the background? Easy, it's not, it just executes the code it would execute if it would have read the input! javascript, cool isn't
With ahk you can do this with Python+AutoHotkey
pip install ahk
pip install "ahk[binary]"
from ahk import AHK
from ahk.window import Window
ahk = AHK()
win = Window.from_pid(ahk, pid='20366')
win.send('abc') # send keys directly to the window
Note that some programs may simply ignore inputs when they are not in focus. However, you can test this works in general even when not in focus by testing with a program like notepad
Full disclosure: I author the ahk library.
I would like to stream the audio of a youtube video in python, youtube-dl allows me to download a video (audio in my case), but that process can take some time. My objective is to be able to stream the audio 'dynamically', like I would by going on a youtube video. I would like to start playing the audio and still download the rest of it at the same time.
I know that the youtube-dl command line program allows to stream videos to media players, like VLC for example:
youtube-dl -o - -- "[videoID]" | vlc -. I could create a subprocess and execute that command, but I would prefer to use a cleaner way, if possible.
I would expect to have some sort of data that I can transmit to an audio device later on. I don't need to store the audio in a file, but it's not a big deal if there is a temporary file.
This is unfortunately not possible. Youtube-DL does not expose an API that makes this straightforward. This is where Youtube-DL opens the file (or stdout) for writing. It's not exactly written to allow for easy switching of the output stream.
It's probably easier to just subprocess it and pipe its output if you really want this functionality.
In VLC I can do "Media -> Open Network Stream" and under "Please enter a network URL" I can put udp://#239.129.8.16:1234.
And this is opening local UDP video stream.
VLC is not related to my question, I have put it just for clarification.
How can I connect to "udp://#239.129.8.16:1234" network stream in Python, get image from it (screenshot) and save it in file?
I think neither network programming nor Python is the focus of your question here. At the core, you need to feed a video decoder with the binary data stream, make the video decoder collect a sufficient amount of data for decoding a single frame, let the decoder save this, and abort the operation.
I am quite sure that the command line tool avconv from the libav project can do everything you need. All you need to do is dig into the rather complex documentation and find the right command line parameters for your application scenario. From a quick glance, it looks you will need for instance
‘-vframes number (output)’
Set the number of video frames to record. This is an alias for -frames:v.
Also, you should definitely search the docs for this sentence:
If you want to extract just a limited number of frames, you can use
the above command in combination with the -vframes or -t option
It also looks like avconv can directly read from a UDP stream.
Note that VLC, the example you gave, uses libav at the core. Also note that if you really need to execute all this "from Python", then spawn avconv from within Python using the subprocess module.
I'm working on a script that should check on certain system events (like opening of a file, or changing of a registry key) and start further actions depending on that. But I haven't found a clean way to get the information into my script.
I'm looking for a way to get the output of Sysinternals Process Monitor into another program. This should happen without user interaction in close to real time; so saving into a CSV/XML and than using this doesn't work.
I've checked on using the backing file, but this is in the Process Monitor PML format, which i haven't found to be documented anywhere.
Does anybody know a way how I can get the output of Process Monitor into my script?
Or an other (not too messy) way to get a real time list of opened files, registry keys etc into a python program?
Thanks!
If you want to parse stdout or a file, and your ok with a 32 bit only solution, try Dr Strace or ntstrace.
YOu could also look into ospy or another ProcMon alternative. ospy is open source, so at the very least you could look at the source code for capturing events.
Here is a list of alternates to ProcMon.
Background: I have a python program that imports and uses the readline module to build a homemade command line interface. I have a second python program (built around bottle, a web micro-framework) that acts as a front-end for that CLI. The second python program opens a pipe-like interface to the first, essentially passing user input and CLI output back and forth between the two.
Problem: In the outer wrapper program (the web interface), whenever the end-user presses the TAB key (or any other key that I bind the readline completer function), that key is inserted into the CLI's stdin without firing the readline completer function. I need this to trigger readline's command completion function instead, as normally occurs during an interactive CLI session.
Possible Solution #1: Is there some way to send the TAB key to a subprocess' stdin, so that a batch usage works the same as an interactive usage?
Possible Solution #2: Or, if there was some way to trigger the entire completion process manually (including matches generation and display), I could insert and scan for a special text sequence, like "<TAB_KEY_HERE>", firing the possible completion matches display function manually. (I wrote the completer function, which generates the possible matches, so all I really need is access to readline's function to display the possible matches.)
Possible Solution #3: I guess, if I cannot access readline's matches-display function, the last option is to rewrite readline's built-in display-completion function, so I can call it directly. :(
Is there a better solution? Any suggestions on following the paths presented by any of the above solutions? I am stuck on #1 and #2, and I'm trying to avoid #3.
Thanks!
Solution #1 proved to be a workable approach. The key was to not connect the web socket directly to the CLI app. Apparently, readline was falling back into some simpler mode, which filtered out all TAB's, since it was not connected to a real PTY/TTY. (I may not be remembering this exactly right. Many cobwebs have formed.) Instead, a PTY/TTY pair needed to be opened and inserted in between the CLI app and web-sockets app, which tricked the CLI app into thinking it was connected to a real keyboard-based terminal, like so:
import pty
masterPTY, slaveTTY = pty.openpty()
appHandle = subprocess.Popen(
['/bin/python', 'myapp.py'],
shell=False,
stdin=slaveTTY,
stdout=slaveTTY,
stderr=slaveTTY,
)
...
while True
# read output from CLI app
output = os.read(masterPTY, 1024)
...
# write output to CLI app
while input_data:
chars_written = os.write(masterPTY, input_data)
input_data = input_data[chars_written:]
...
appHandle.terminate()
os.close(masterPTY)
os.close(slaveTTY)
HTH someone else. :)
See this answer to a related question for more background:
https://stackoverflow.com/a/14565848/538418