diff --git a/.gitignore b/.gitignore index 81f7b7e..1bf9628 100644 --- a/.gitignore +++ b/.gitignore @@ -104,6 +104,7 @@ ENV/ .idea/ # Exclude Visual Studio solution files +.vs *.sdf *.VC.opendb *.VC.db diff --git a/README.md b/README.md index 79eace4..c7c40f1 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,30 @@ Run the tests from the commandline: $ python3 test_gnomecast.py ``` +Running on Windows +------------------ + +Follow the PyGObject installation guide for Windows from https://pygobject.readthedocs.io/en/latest/getting_started.html or below: + +Covered in the guide above: + +1. Install Msys2 and run `mingw64.exe` from the installation folder to install Mingw64 Python and its dependencies. **Note**: The Mingw64 terminal will only be used for installing the prerequisites and not for actually running the program. +1. Run the following commands: + 1. Run `pacman -Suy` once and it will prompt to exit and run it again. Close terminal, re-open and run `pacman -Suy` once more. + 1. Execute `pacman -S mingw-w64-x86_64-gtk3 mingw-w64-x86_64-python3 mingw-w64-x86_64-python3-gobject` + +Not included in link but needed in order to be able to start Gnomecast: + +1. Execute following: `pacman -S mingw-w64-x86_64-python3-pip mingw-w64-x86_64-python3-lxml` to get `pip` and `lxml` needed for one of the dependencies. +1. Install Python package dependencies: `pip install bottle pychromecast pycaption paste` + +After this, for running Gnomecast you will need to **start the Mingw64 Python installation from a regular Windows commandline**, not from the Mingw64 or MSYS terminal (*I believe it has to do with the way paths are handled between UNIX and Windows, but not sure*). +So just run the Mingw64 Python installation from Windows, for example, `D:\msys64\mingw64\bin\python.exe gnomecast.py` +Also, make sure you have ffmpeg available on your regular Windows environment! + +Make sure to properly set up the Mingw64 Python environment correctly in Visual Studio as well, if wishing to use it for debugging purposes. + + My File Won't Play! ------------------- diff --git a/gnomecast.py b/gnomecast.py index 3bbd7f2..a0d7e67 100644 --- a/gnomecast.py +++ b/gnomecast.py @@ -1,5 +1,6 @@ -import contextlib, os, re, signal, socket, subprocess, sys, tempfile, threading, time, traceback, urllib +import contextlib, os, re, signal, socket, subprocess, sys, tempfile, threading, time, traceback, urllib, platform +onWindows = platform.system() == 'Windows' DEPS_MET = True try: @@ -147,8 +148,8 @@ def __init__(self, fn, callback=None, _ffmpeg_output=None): self.ready = False def parse(): self.thumbnail_fn = None - thumbnail_fn = tempfile.mkstemp(suffix='.jpg', prefix='gnomecast_pid%i_thumbnail_' % os.getpid())[1] - os.remove(thumbnail_fn) + with tempfile.NamedTemporaryFile(suffix='.jpg', prefix='gnomecast_pid%i_thumbnail_' % os.getpid()) as f: + thumbnail_fn = f.name self._ffmpeg_output = _ffmpeg_output if _ffmpeg_output else subprocess.check_output( ['ffmpeg', '-i', fn, '-f', 'ffmetadata', '-', '-f', 'mjpeg', '-vframes', '1', '-ss', '27', '-vf', 'scale=600:-1', thumbnail_fn], stderr=subprocess.STDOUT @@ -220,9 +221,9 @@ def load_subtitles(self): cmd = ['ffmpeg', '-y', '-i', self.fn, '-vn', '-an',] files = [] for stream in self.subtitles: - srt_fn = tempfile.mkstemp(suffix='.srt', prefix='gnomecast_pid%i_subtitles_' % os.getpid())[1] - files.append(srt_fn) - cmd += ['-map', stream.index, '-codec', 'srt', srt_fn] + with tempfile.NamedTemporaryFile(suffix='.srt', prefix='gnomecast_pid%i_subtitles_' % os.getpid()) as subf: + files.append(subf.name) + cmd += ['-map', stream.index, '-codec', 'srt', subf.name] print(cmd) try: @@ -283,8 +284,8 @@ def __init__(self, cast, fmd, video_stream, audio_stream, done_callback, error_c if self.transcode: self.done = False dir = '/var/tmp' if os.path.isdir('/var/tmp') else None - self.trans_fn = tempfile.mkstemp(suffix='.mp4', prefix='gnomecast_pid%i_transcode_' % os.getpid(), dir=dir)[1] - os.remove(self.trans_fn) + with tempfile.NamedTemporaryFile(suffix='.mp4', prefix='gnomecast_pid%i_transcode_' % os.getpid(), dir=dir) as f: + self.trans_fn = f.name device_info = HARDWARE.get((self.cast.device.manufacturer, self.cast.device.model_name)) ac3 = device_info.ac3 if device_info else None @@ -439,7 +440,10 @@ def check_ffmpeg(self): ffmpeg_available = True print('check_ffmpeg') try: - print(subprocess.check_output(['which', 'ffmpeg'])) + if onWindows: + print(subprocess.check_output(['where', 'ffmpeg'])) + else: + print(subprocess.check_output(['which', 'ffmpeg'])) except Exception as e: print(e, e.output) ffmpeg_available = False @@ -473,7 +477,8 @@ def video(id, ext): print('ranges', ranges) offset, end = ranges[0] self.transcoder.wait_for_byte(offset) - response = bottle.static_file(self.transcoder.fn, root='/') + folderpath, filename = os.path.split(self.transcoder.fn) + response = bottle.static_file(filename, root=folderpath) if 'Last-Modified' in response.headers: del response.headers['Last-Modified'] response.headers['Access-Control-Allow-Origin'] = '*' @@ -757,8 +762,10 @@ def f(scale, s): self.update_button_visible() win.resize(1,1) - - GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self.quit) + + # Not working on Windows + if not onWindows: + GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self.quit) def add_extra_subtitle_options(self): @@ -970,11 +977,12 @@ def on_file_clicked(self, widget): if os.path.isdir(downloads_dir): dialog.set_current_folder(downloads_dir) - filter_py = Gtk.FileFilter() - filter_py.set_name("Videos") - filter_py.add_mime_type("video/*") - filter_py.add_mime_type("audio/*") - dialog.add_filter(filter_py) + if not onWindows: + filter_py = Gtk.FileFilter() + filter_py.set_name("Videos") + filter_py.add_mime_type("video/*") + filter_py.add_mime_type("audio/*") + dialog.add_filter(filter_py) response = dialog.run() if response == Gtk.ResponseType.OK: @@ -1566,7 +1574,9 @@ def delete_old_transcodes(): def main(): - delete_old_transcodes() + # Might not be needed on Windows since using NamedTemporaryFile? + if not onWindows: + delete_old_transcodes() caster = Gnomecast() arg_parse(sys.argv[1:], {'s':'subtitles', 'd':'device'}, caster.run, USAGE) diff --git a/gnomecast.pyproj b/gnomecast.pyproj index 5cc3476..d7a7ae0 100644 --- a/gnomecast.pyproj +++ b/gnomecast.pyproj @@ -11,14 +11,14 @@ . {888888a0-9f3d-457c-b088-3a5042f75d52} Standard Python launcher - {9a7a9026-48c1-4688-9d5d-e5699d47d074} - 3.4 + Global|VisualStudio|Mingw64 Python 3.8 + True + False 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets @@ -38,8 +38,7 @@ - + - - + \ No newline at end of file