diff options
author | Wojciech Siewierski <wojciech.siewierski@onet.pl> | 2019-09-08 20:11:13 +0200 |
---|---|---|
committer | Wojciech Siewierski <wojciech.siewierski@onet.pl> | 2019-09-08 20:11:13 +0200 |
commit | f3fdb6b9c97902c36b56c3e32160ed0f5855f25d (patch) | |
tree | c6419546ebb626d475aa37795bac7a8a2fd84898 | |
parent | 71bcac6c9a7e3823644094cb39685da9fe24dc01 (diff) |
Backport the mpv-based image previewsmpv-previews-backport
See: #872
Most credits to Joseph Rice.
-rw-r--r-- | ranger/container/settings.py | 2 | ||||
-rw-r--r-- | ranger/core/fm.py | 4 | ||||
-rw-r--r-- | ranger/ext/img_display.py | 77 |
3 files changed, 81 insertions, 2 deletions
diff --git a/ranger/container/settings.py b/ranger/container/settings.py index 82901ac0..4e4a74a8 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -110,7 +110,7 @@ ALLOWED_VALUES = { 'one_indexed': [False, True], 'preview_images_method': ['w3m', 'iterm2', 'terminology', 'urxvt', 'urxvt-full', 'kitty', - 'ueberzug'], + 'ueberzug', 'mpv'], 'vcs_backend_bzr': ['disabled', 'local', 'enabled'], 'vcs_backend_git': ['enabled', 'disabled', 'local'], 'vcs_backend_hg': ['disabled', 'local', 'enabled'], diff --git a/ranger/core/fm.py b/ranger/core/fm.py index 43001e8b..12eaa525 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -26,7 +26,7 @@ from ranger.ext.img_display import (W3MImageDisplayer, ITerm2ImageDisplayer, TerminologyImageDisplayer, URXVTImageDisplayer, URXVTImageFSDisplayer, KittyImageDisplayer, UeberzugImageDisplayer, - ImageDisplayer) + MPVImageDisplayer, ImageDisplayer) from ranger.core.metadata import MetadataManager from ranger.ext.rifle import Rifle from ranger.container.directory import Directory @@ -242,6 +242,8 @@ class FM(Actions, # pylint: disable=too-many-instance-attributes return KittyImageDisplayer() elif self.settings.preview_images_method == "ueberzug": return UeberzugImageDisplayer() + elif self.settings.preview_images_method == "mpv": + return MPVImageDisplayer() return ImageDisplayer() def _get_thisfile(self): diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py index 2cce5c7a..4c653477 100644 --- a/ranger/ext/img_display.py +++ b/ranger/ext/img_display.py @@ -731,3 +731,80 @@ class UeberzugImageDisplayer(ImageDisplayer): self.process.communicate() finally: timer_kill.cancel() + + +class MPVImageDisplayer(ImageDisplayer, FileManagerAware): + """Implementation of ImageDisplayer using mpv, a general media viewer. + Opens media in a separate X window. + + mpv need to be installed for this to work. + """ + + def check(self): + if os.environ.get('DISPLAY', None): + return shutil.which('mpv') + + def _send_command(self, path, sock): + import socket + + message = '{"command": ["raw","loadfile",%s]}\n' % json.dumps(path) + s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + s.connect(str(sock)) + # info('-> ' + message) + s.send(message.encode()) + message = s.recv(1024).decode() + # info('<- ' + message) + s.close() + + def _launch_mpv(self, path, sock): + + proc = Popen([ + * os.environ.get("MPV", "mpv").split(), + "--no-terminal", + # "--force-window", + "--input-ipc-server=" + str(sock), + "--image-display-duration=inf", + "--loop-file=inf", + "--no-osc", + "--no-input-default-bindings", + # "--no-input-cursor", + "--keep-open", + "--idle", + + # actually fix the window resizing problem + "--geometry=600x400", # fixed aspect ratio + "--no-keepaspect-window", + + # attempts to fix window resizing problem + # "--geometry=600x400", # fixed aspect ratio + # "--geometry=600", # fixes width + # "--geometry", # nope, breaks + # "--fixed-vo", + # "--force-window-position", # nope + # "--video-unscaled=yes", # nope + "--", + path, + ]) + + import atexit + @atexit.register + def cleanup(): + def _ignore_errors(func, *args, **kwargs): + try: + func(*args, **kwargs) + except: + pass + + _ignore_errors(proc.terminate) + _ignore_errors(lambda: os.unlink(sock)) + + def draw(self, path, start_x, start_y, width, height): + + path = os.path.abspath(path) + sock = os.path.join(self.fm.datapath("image-slave.sock")) + + try: + self._send_command(path, sock) + except (ConnectionRefusedError, FileNotFoundError): + # info('LAUNCHING ' + path) + self._launch_mpv(path, sock) |