rabite0 / hunter

The fastest file manager in the galaxy!
Do What The F*ck You Want To Public License
1.31k stars 64 forks source link

Add previews for images, video and "prelisten" for audio files #14

Closed rabite0 closed 5 years ago

rabite0 commented 5 years ago

Add ImageView and VideoView widgets.

Implement ImageView based on Sixel graphics and VideoView by integrating mpv playback.

s-d-m commented 5 years ago

Not sure using sixel is the best solution here.

On one side Sixel graphics stays in the terminal, on other side the terminals that properly support it run under an X server and thus you could directly show the proper image like ranger does.

My experience with lsix was that the time it takes to convert the image to sixel is significantly bigger than the time it takes to open the file with sxiv

rabite0 commented 5 years ago

Well, I might end up going down the same path as ranger with multiple ways to do image previews, but for me personally at least, I need something that works in tmux, or it's useless to me. Sixel works in tmux as well, I don't know if those other options work with tmux. If they do, maybe that's preferable.

If it's slow that's not too much of a problem since it's not going to affect responsiveness in hunter, but if it's TOO slow it's going to be annoying and pointless anyway. Like more than 200ms or something around that. It's probably not that slow, hopefully.. A quick check shows conversion is around that ballpark. Not great, but acceptable.

Although even that is too much if I want video previews, but that's a long shot anyway, and I'm probably going to fudge this with an mpv overlay or something like that, if I implement it at all. Although I'd really love to see it working somehow. If worst comes to worst, frame skipping is a thing, too. It's not a video player, it doesn't have to be smooth. Maybe the sound thing is over-overkill as well ;)

Will definitely evaluate the options again before I write any code.

s-d-m commented 5 years ago

I can confirm that the real image previews used in ranger works on tmux. That's what I use too.

About sixel, I just downloaded that image and then ran

time convert /tmp/5412550.png sixel:-

it printed time: 0.112 real 0.107 user 0.024 system (117%)

in comparison, I could open the file in sxiv, and immediately close the window by pressing q in about 0.068 seconds.

Almost twice as fast as displaying the image with sixel. Up to you to decide. I'm happy both ways as then I will be able to drop ranger completely I think.

s-d-m commented 5 years ago

Interestingly, convert /tmp/5412550.png sixel:- doesn't work under tmux :-(

rabite0 commented 5 years ago

Great, thanks for clarifying. Sixel support in terminals doesn't appear to be that common either, unfortunately. Probably not going to use that, or not exclusively at least.

A quick googling suggested that terminfo needs to be patched for it to work under tmux. I might have seen a patch/fork/branch of tmux itself somewhere, too, not sure any more. Didn't look too much into it, just checked if it's possible.

It's all pretty hacky anyway and terminal programming in general is black magic. There's still a nasty bug in hunter around terminal resetting that I need to look into how to fix.

rabite0 commented 5 years ago

Almost done, images, videos and audio files work. There's seeking, muting, a progress bar, icons for play/pause/mute, etc. I went a bit crazy with this.

I settled for a Unicode half-block approach, for compatibility reasons. I'll probably add something more high-fidelity later, but as a preview tool it's good enough, if only barely :).

It would be nice to see pdf files and other stuff in high-quality, though, so I'm still itching to add sixel support. termplay supports playing video through sixel and it's plenty fast. It being slow is probably an implementation issue. If only tmux supported it :3... It seems like someone's working on this, we'll see.

s-d-m commented 5 years ago

Can't wait to try it! I tried compiling both master and the img-ext branches but both failed to compile on my machine. For the master branch,the error was error: couldn't read src/media_preview.rs: No such file or directory (os error 2) and for img-ext,the Cargo.toml file has a dependency to async_value as a path to ../async_value which I haven't of course.

Can you post a screenshot of how it looks?

rabite0 commented 5 years ago

Does it still fail to build? I don't have media_preview.rs either (renamed to preview-gen.rs). The dependency issue is fixed, too. It's all merged into master now.

image

rabite0 commented 5 years ago

Scratch that, I forgot to rename it in Cargo.toml as well. It's a separate binary, because gstreamer takes up a lot of memory once initialized. Just tested building it, working now.

Also, make sure preview-gen is somewhere in your $PATH. If you install with cargo install --path ., this will happen automatically.

s-d-m commented 5 years ago

works for me now! And even midi file are playing from within hunter! <3

Concerning images, I wonder if it would be possible to do it like ranger does. It uses w3m to display images such that you can see the real thing. Otherwise, if it would be possible to launch an external program without losing the focus, it would then become "easy" to support any file, simply launching a fast viewer program (sxiv for images, zathura for pdf, mpv for videos ...) and killing it when the user move to the next file would also do the trick.

In any case, impressive work so far!

rabite0 commented 5 years ago

Yeah, it supports everything that's supported by GStreamer. gif animations are somewhat broken though and I'm not sure if it's possible to improve those easily, but I hope it just needs setting the correct fps.

w3m would probably work for high-quality previews, although I couldn't make it show images when I tested it a few weeks ago. Will try that again some time. Would be a nice, easy option, since w3m does the heavy lifting. For video it might be too slow though, but it's hard to say without testing. But even then, it's impossible to synchronize different frames when they're all drawn by a new process.

I though about your idea as well. Initially I wanted to use a mpv overlay for previews, since it does images, video and everything, but it would break as soon as you moved the terminal around, or switched tmux windows.

Jipok commented 5 years ago

I am not aware of the whole situation, but Kitty has its own protocol for displaying images, it looks better than using w3m. https://sw.kovidgoyal.net/kitty/graphics-protocol.html

rabite0 commented 5 years ago

True, it's very fancy, too, with all the things you can do with it, but unfortunately it only works on kitty, and it doesn't work with tmux at all. :( I'm not really interesting into going that route, to be honest. Same with urxvt's background image hack. I think ranger can use that to draw images, too. I might do it eventually, but it's not very appetizing.

To be honest, SIXEL support isn't that widespread either, but it seems to get better and someone is working on getting it working on tmux, which would make it very usable for me. In my mind, SIXEL is THE proper standard to support to get images in a terminal, but yeah, without tmux support it's a no go, too.

w3m is tempting, because it works in tmux and it works in every terminal, which means I don't have to write a different backend for every terminal. For things like images, pdfs and such, it would be sufficient.

SolitudeSF commented 5 years ago

just expose api to make media preview pluggable or scriptable by user. then users of kitty/iterm/terminology whatever could use their preferred preview method.

also, maybe offtopic, but i cant build hunter, even tho i provide --features='', because of missing gstreamer.

rabite0 commented 5 years ago

Hm.... that could work I guess. In a way that's already possible since media files are converted in a separate process and images/frames are written to stdout and read by hunter.

The protocol is pretty simple. It reads the image line-by-line. A blank line means the image/frame is done, after that it prints a line for the current position in seconds and a line for the duration, also in seconds. After that the next frame is written.

The only problem would be if the data it receives is compatible with the way it draws to the screen.

also, maybe offtopic, but i cant build hunter, even tho i provide --features='', because of missing gstreamer.

Oops, I'll take a look.

rabite0 commented 5 years ago

You're right. The correct flag seems to actually be "--no-default-flag".

rabite0 commented 5 years ago

Pushed a fix for this, should build now.

rsignavong commented 5 years ago

Hello, The installation fails on MacOs. I got the following error

Caused by:
  process didn't exit successfully: `/var/folders/13/43_j3_gd0tvd1xjp53zw6r2w0000gn/T/cargo-installYGbZFF/release/build/gstreamer-sys-20917f76ad5b4260/build-script-build` (exit code: 1)
--- stderr
`"pkg-config" "--libs" "--cflags" "gstreamer-1.0 >= 1.8"` did not exit successfully: exit code: 1
--- stderr
Package gstreamer-1.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `gstreamer-1.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'gstreamer-1.0' found

I tried to locate libffi.pc that was found and set the environment variable

$ locate /libffi.pc
/Applications/Xcode.app/Contents/Developer/usr/share/xcs/xcsd/node_modules/nodobjc/node_modules/ffi/deps/libffi/libffi.pc.in
/usr/local/Cellar/libffi/3.2.1/lib/pkgconfig/libffi.pc
$ export PKG_CONFIG_PATH=/usr/local/Cellar/libffi/3.2.1/lib/pkgconfig

But it still doesn't work.

What should I do?

rabite0 commented 5 years ago

Oh, crap, I totally forgot about macOS again. Well, the error message says that you don't have gstreamer installed, or at least it can't be found by the build script. Do you have access to macports, or something like that? You could try installing gstreamer from there and point PKG_CONFIG_PATH to wherever that ends up when you install gstreamer. Without gstreamer video and audio previews won't work unfortunately. Another option is disabling video previews. You can do that by adding "--no-default-features --features img" to cargo install. That way you still get previews for images at least. If you have gstreamer installed (including the source/dev-headers) and it still won't work this would suggest a bug in the Rust wrapper for gstreamer.

Here you can directly download gstreamer, including the development package: https://gstreamer.freedesktop.org/download/

I don't know if that includes the necessary files for pkgconfig. Another option is Homebrew: https://brew.sh/

rabite0 commented 5 years ago

I pushed an update today that should greatly improve customizable media previews. You can now set media_previewer in ~/.config/hunter/conf.

It gets called with: xsize, ysize, xpos, ypos, preview-type (image/video/audio), autoplay(true/false), muted(true/false)

size/position refers to the size/position in cells that the image should have to fit into the preview pane. In case of image previews, the previewer is supposed to simply print out the escape codes necessary to draw the image. Video/audio is a bit more complicated, I'll write some explanation for that up later.

It would be great if someone tested this and lets me know if there are bugs or something missing to make it work.

rabite0 commented 5 years ago

Okay, this is it, initial support for SIXEL and kitty graphics has landed. There are still a few things to iron out and stuff like PDF previews is still not there, but images/videos show up nicely in high quality now, no problem.

With SIXEL the frame-rate is capped at 10fps currently, since it's too slow otherwise (both encoder and xterm are slow), but it has the edge in terms of scaling quality. kitty is super-fast and has no problem with smooth high frame rate video content. On my system it's even tear-free.

To enable it use the "-s" flag, or put "sixel=on" in the config. It currently auto-detects kitty and switches to kitty's protocol automatically. This is probably going to change soon, though.

graphics

rabite0 commented 5 years ago

With the latest update (better, faster, pdf previewing, etc) I consider this feature-complete. I might add support for urxvt/iterm and maybe a w3m-fallback, too at some point. Really, the terminal specific stuff is like 10 lines out of a 1000 hundred line file, so basically nothing.