Opening a thread in General as this is an interesting grid player in its beginnings. The programmer seems to accept feature requests. Its fast and It can use Stash.
That is a very interesting video player. VLC is great and just plays everything, but it just looks and feels so outdated. This seems like a modern and visual more pleasing VLC like player. Definitely going to give this a try. Thank you for linking it here.
Yeah and it just started. @Yoooi maybe consider connecting MFP to it?
I like how it keeps saying it’s free, then buried down the bottom of the FAQ it’s says free up to 200 videos.

Yeah not the greatest way, I agree, but not a problem for paid script lovers, right? If its good its worth it. I bought it as really promising.
So we can gather some feature requests. For now I asked for stuff to handle a download like “some chick megapack” with 500 files to choose from.
- quick scrape to set library image
- preview better than Stash sprites
- loading directory that is not in library to edit and choose what to delete. Temporary library
- file operations like rename and delete and move file
Sure, but it needs some sort of api that reports playback information.
And in case of grid playback I think you would have to be able to set some sort of “main” video as you can’t really sync with multiple videos. So the api would probably need to send playback information for all videos and some selection index.
Hi everyone, I’m the developer of VidVana. I’ve had a Handy since 2020 and have been part of this community for a while. I originally built VidVana for my own collection because I got tired of the VLC/folder browsing cycle and wanted something purpose-built for large local collections.
Thanks to roa for starting this thread and testing the app.
@stustustustu fair point on the pricing. Pro is $24.95 one-time, not a subscription. Every download gets 30 days of full Pro access automatically. No signup, no credit card. After that it drops to the free tier (200 video cap, 2x2 grid). You’re right that this should be clearer upfront and not buried in the FAQ. I’ll fix that on the site.
On the feature requests:
Quick thumbnail selection
Coming in v0.9.3 (targeting about two weeks). You’ll be able to grab any frame and set it as the library thumbnail directly in fullscreen. One click, done.
Browse folders without full import
Generating thumbnails for hundreds of videos takes time no matter how you build it. What works today: add the folder to your library, browse visually, and remove what you don’t want. Removing a video never touches your actual file on disk. VidVana is strictly read-only on your filesystem by design. Your files are always safe.
File safety
VidVana will never rename, move, or delete your real files. That’s intentional. Your filesystem stays untouched.
Display names
You can already rename titles inside the app (pencil icon on any title) without changing the actual filename.
Folder import flow
The folder tree exists so you can exclude subfolders before import. If you want everything, Select All + Add to Library. Two clicks.
@Yoooi that’s interesting. A playback API that reports position, play/pause, and active video would be feasible. You’re right that grid mode would need a “main” tile concept for sync - double-clicking a tile already goes fullscreen on that video, so that could be the trigger. I’d like to explore this. No ETA yet but it’s on the radar.
If I’m off on any of this or misunderstanding what you need, let me know. I’m building this based on real feedback so I’d rather be corrected now than build the wrong thing.
What are you mainly using VidVana for right now, and what slows you down the most? That’s what I’ll prioritize next.
That’s very doable. VidVana already tracks an “active tile” internally (whichever video you last clicked or is in fullscreen), so the selection index maps cleanly.
I could expose a local WebSocket that sends playback state for all tiles – file path, current time, duration, playing/paused – plus which tile index is active. Happy to match an existing format if there’s one you’d prefer on your end (I see OFS uses a similar JSON event pattern).
Let me know what works best and I’ll get it into the next release.
one problem ive had with vidvana is if you use it for a portrait video it cuts off the top and bottom of the video instead of zooming out, it would be good to have the option to have it either way as the zooming in is quite a good tool
Hey cyberbob123. That option already exists. Look for the cover/contain toggle in the bottom toolbar (it’s an icon that switches between filling the tile vs fitting the whole video). “Contain” mode will show the full portrait video without cropping. I’m fixing some edge cases with it in the next update too. It’s avaialble in both grid view and full screen.
I don’t think there is a need to match any formats. Given that no other player does grid playback it would be better to make a custom format anyway. Whatever you feel like fits the app the best given your roadmap and internal structure. If the api could ever be used for stuff other than funscript sync then it would be better to start with that in mind.
The information needed for a video is (at least for MFP):
- full file path
- current time, no rounding, as ms integer, or as seconds float
- duration, no rounding, as ms integer, or as seconds float
- state, playing/paused (stopped if tile is empty?)
- playback rate, as % float (if you can change playback rate in VidVana)
Optional (but every other player except Whirligig does support it): allow remote controlling the videos from clients:
- change video
- set position
- set play/pause state
- set playback rate
Obviously this would also need to handle grid index to be controlled.
The other players usually push the full state to the client, for example via tcp usually every 1 second (DeoVR, HereSphere, Whirligig).
Some other players just have a rest api or similar and make the client fetch the data when they want it (VLC, MPC-HC, Plex)
And there is MPV which allows you to subscribe to events and property changes and then it pushes small json events each time they happen. This gives the client very precise info about the actual state of the video, especially with streamed videos. MPV has probably the most granular and detailed api from all players MFP supports, but it can be difficult to implement all of the state changes. It is also very chatty:
mpv events
Sending "{ "command": ["observe_property_string", 1, "pause"] }"
Sending "{ "command": ["observe_property_string", 2, "duration"] }"
Sending "{ "command": ["observe_property_string", 3, "time-pos"] }"
Sending "{ "command": ["observe_property_string", 4, "speed"] }"
Sending "{ "command": ["observe_property_string", 5, "paused-for-cache"] }"
Sending "{ "command": ["get_property", "playlist"], "request_id": 1000 }"
Received "{"request_id":0,"error":"success"}"
Received "{"event":"property-change","id":1,"name":"pause","data":"yes"}"
Received "{"request_id":0,"error":"success"}"
Received "{"event":"property-change","id":2,"name":"duration"}"
Received "{"request_id":0,"error":"success"}"
Received "{"event":"property-change","id":3,"name":"time-pos"}"
Received "{"request_id":0,"error":"success"}"
Received "{"event":"property-change","id":4,"name":"speed","data":"1.000000"}"
Received "{"request_id":0,"error":"success"}"
Received "{"data":[],"request_id":1000,"error":"success"}"
Received "{"event":"video-reconfig"}"
Received "{"event":"idle"}"
Received "{"event":"property-change","id":5,"name":"paused-for-cache"}"
Received "{"event":"start-file","playlist_entry_id":1}"
Sending "{ "command": ["get_property", "playlist"], "request_id": 1000 }"
Received "{"data":[{"filename":"A:\\Video\\13793562_720p.mp4","current":true,"playing":true,"id":1}],"request_id":1000,"error":"success"}"
Received "{"event":"audio-reconfig"}"
Received "{"event":"audio-reconfig"}"
Received "{"event":"file-loaded"}"
Received "{"event":"property-change","id":2,"name":"duration","data":"506.589417"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"0.000000"}"
Received "{"event":"property-change","id":5,"name":"paused-for-cache","data":"no"}"
Received "{"event":"audio-reconfig"}"
Received "{"event":"video-reconfig"}"
Received "{"event":"video-reconfig"}"
Received "{"event":"playback-restart"}"
Sending "{ "command": ["set_property", "time-pos", "1.1050"] }"
Received "{"request_id":0,"error":"success"}"
Received "{"event":"seek"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"1.105000"}"
Received "{"event":"playback-restart"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"1.101100"}"
Received "{"event":"property-change","id":1,"name":"pause","data":"no"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"1.117783"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"1.134467"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"1.151150"}"
...
Received "{"event":"property-change","id":3,"name":"time-pos","data":"3.937267"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"3.953950"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"3.970633"}"
Received "{"event":"property-change","id":1,"name":"pause","data":"yes"}"
Received "{"event":"property-change","id":1,"name":"pause","data":"no"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"3.987317"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"4.004000"}"
...
Received "{"event":"property-change","id":3,"name":"time-pos","data":"5.205200"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"5.221883"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"5.238567"}"
Received "{"event":"seek"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"53.101616"}"
Received "{"event":"playback-restart"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"53.119733"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"53.136417"}"
Received "{"event":"property-change","id":3,"name":"time-pos","data":"53.153100"}"
...
Perfect. That’s really clear. I’ll go with a WebSocket that pushes full state on change (with a fallback interval for idle tiles). All the data points you listed are already tracked internally so exposing them is straightforward.
Remote control is doable too. Seek, play/pause, playback rate, and tile selection via the same socket. I’ll include that from the start so it’s not an afterthought.
I’ll ping you here when I have a test build ready. Might have a few questions once I’m deep in it but this gives me everything I need to start.
Yea that works, also instead of pushing the full state of all tiles in one message you could push each tile separately, with a tile index in the message. The same message format could then be used for controlling the tile from the client.
This is basically how DeoVR and HereSphere does it, they send a json every second:
{
"path": ...,
"currentTime": ...,
"playbackSpeed": ...,
"playerState": ...,
"duration": ...
}
and if you want to control the video from the client you send the same message, with ignored fields as null or just missing from json, so for example for seek you send:
{
"path": null,
"currentTime": 123.456,
"playbackSpeed": null,
"playerState": null,
"duration": null
}
You mentioned sending on changes but I’ll just note that both DeoVR and HereSphere have an issue where if you pause a video there can be up to 1 second of delay before the client sees it.
So it would be best to force send a message when the video state changes, or when the video is loaded/unloaded/changed to prevent delays in stopping the device.
The time updates don’t have to be send every frame like in mpv, 1 second should work fine tho I do it every 200-500ms for the REST api clients depending on the amount of requests needed.
On websocket connection probably have to send all tile states at once so that the client can be up to date.
That’s a cleaner approach. Per-tile messages with the index, same format for both directions. I like it.
Good call on the immediate push for state changes. I’ll do interval at 250ms for time updates, plus force-push on play/pause/load/unload/seek so there’s no delay on the device side. And yeah, full state dump on connection so the client starts current.
I think that covers everything I need. I’ll reach out if anything comes up during implementation.
If I may inerrupt the adults talking. What the little user would like is switch scripts. So if I click on a tile in the grid switch the script. Optionally as it can disturb mark the active scripted tile with a dot.
Thats actually quite sad as that was exactly the time consuming reason I downloaded Vidvana besides using it as a player. Maybe you want to reconsider as most players can at least get rid of the file instead of sending you elsewhere.
Question or feature, is it possible to use Vidvana as general player for the OS?
Already asked this but asking for the community 2D playback of VR with movable view by mousedrag would be nice.
Same with single image dispaly of VR in the library images would be nice.
The script switching on tile click is exactly how the MFP integration will work. Clicking a tile makes it the active sync target. I’ll add a visual indicator for which tile is active too. That’s going into the next update.
On file operations, I hear you. The read-only approach is deliberate as a safety default, but your idea about a settings toggle makes sense. An opt-in setting that enables file deletion, off by default, with a confirmation dialog so nothing gets wiped by accident. That’s a reasonable middle ground I can work with for a future update.
Default OS player, noted. That’s on my list. Need to handle file associations properly per platform but it’s doable.
VR playback with mouse drag and VR thumbnails, both good ideas. VR support is further out since it needs a different rendering pipeline, but it’s on the roadmap.
Overall way to many nagging unnecessary clicks.
dont ask:
dont ask
dont ask
fucking dont ask
LOL Are you kidding me? Would you for fucks sake just play the damn grid after I press this?
This is how it feels.

Also need to exit the grid by ESC not menu only. Ah OK just found the popups. Still please let us use the ESC key its so made for getting out.
Please, pretty please consider a delete movie button in grid and really delete the movie as in Heresphere, Stash and any other player.
Update Stash at start reload library when finished.
Can you control stash like scan/identify/autotag with the saved settings? Would be nice if this could be done out of vidvana automatically.



