`strokers_for_mpv` MPV plugin Funscript player for T-Code devices (OSR, SR6) and `strokers` Rust library

I wrote a simple Rust library for controlling T-Code devices. Support for other types of devices could be added in the future.

I wrote this because I wanted to write an MPV plugin for playing funscripted videos
directly to my OSR2+, which I’m also ‘introducing’ today.

strokers_for_mpv

This is now in a state where it’s minimally useful, but still not slapping a
version number on it just yet.

Features:

  • Linux support. Maybe the other platforms work, I don’t know :smiley: — very happy to hear if anyone else tries. (I suspect Windows should work, but I am hesitant to promise!)
  • Multi-axis (of course!)
  • Configurable speed limits for safety
  • Min/Max axis limits
  • Simple text-based (TOML) config file for setting the serial port information and default limits
  • You can add MPV keybindings to change the axis min/max limits on the fly

Known Limitations:

  • If you have funscript variants, there’s no way to choose those in the MPV plugin currently — it will only open video.funscript for video.mp4, not
    video_hardmode.funscript (& equivalent for other axes). I want to address this in the future, just not sure of the best way.
  • If you install the plugin, it will always (try to) connect to your stroker when you open MPV, even if you’re watching an innocent video without any funscript. However I will address this in the future and it’s also probably harmless.

The MPV plugin is available at: strokers/strokers_for_mpv at main - LaurenBoutin/strokers - Codeberg.org
(Rust compiler required to compile; not hard but if this is a problem let me know)

At this point I wrote this ‘just’ for me, I don’t know if anyone else will have any interest in it, so if it is interesting to you but there’s something missing, let me know!

3 Likes

I can’t believe no one talk about it. I have tried to find something similar for months. Good work!

Unfortunately, I can’t get it working. Compiling and installing are fine

After running RUST_BACKTRACE=full mpv --script=~/.config/mpv/scripts/libstrokers_for_mpv.so MOVFILE.mp4`,

I got this error:

2025-03-08T00:45:28.524416Z  INFO strokers_for_mpv: strokers plugin for MPV (libstrokers_for_mpv) is loaded!
thread '<unnamed>' panicked at /opt/cargo/registry/src/index.crates.io-6f17d22bba15001f/tracing-subscriber-0.3.18/src/util.rs:91:14:
failed to set global default subscriber: SetGlobalDefaultError("a global default trace dispatcher has already been set")
stack backtrace:
2025-03-08T00:45:28.524653Z ERROR strokers_for_mpv: On change, can't read time-pos/full as f64
   0:     0x7fe3dae221ea - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h5b6bd5631a6d1f6b
   1:     0x7fe3dae45353 - core::fmt::write::h7550c97b06c86515
   2:     0x7fe3dae1fbd3 - std::io::Write::write_fmt::h7b09c64fe0be9c84
   3:     0x7fe3dae22032 - std::sys::backtrace::BacktraceLock::print::h2395ccd2c84ba3aa
   4:     0x7fe3dae22fdc - std::panicking::default_hook::{{closure}}::he19d4c7230e07961
   5:     0x7fe3dae22e22 - std::panicking::default_hook::hf614597d3c67bbdb
   6:     0x7fe3dae235b7 - std::panicking::rust_panic_with_hook::h8942133a8b252070
   7:     0x7fe3dae2344a - std::panicking::begin_panic_handler::{{closure}}::hb5f5963570096b29
   8:     0x7fe3dae226c9 - std::sys::backtrace::__rust_end_short_backtrace::h6208cedc1922feda
   9:     0x7fe3dae230dc - rust_begin_unwind
  10:     0x7fe3dac7b410 - core::panicking::panic_fmt::h0c3082644d1bf418
  11:     0x7fe3dac7b7f6 - core::result::unwrap_failed::hd20b4aa073bda1e2
  12:     0x7fe3dacce23e - mpv_open_cplugin
  13:     0x5597a5af8fdb - <unknown>
  14:     0x5597a5aee80a - <unknown>
  15:     0x5597a5aee89d - <unknown>
  16:     0x7fe3ee094ac3 - <unknown>
  17:     0x7fe3ee126850 - <unknown>
  18:                0x0 - <unknown>
thread '<unnamed>' panicked at core/src/panicking.rs:221:5:
panic in a function that cannot unwind
stack backtrace:
   0:     0x7fe3dae221ea - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h5b6bd5631a6d1f6b
   1:     0x7fe3dae45353 - core::fmt::write::h7550c97b06c86515
   2:     0x7fe3dae1fbd3 - std::io::Write::write_fmt::h7b09c64fe0be9c84
   3:     0x7fe3dae22032 - std::sys::backtrace::BacktraceLock::print::h2395ccd2c84ba3aa
   4:     0x7fe3dae22fdc - std::panicking::default_hook::{{closure}}::he19d4c7230e07961
   5:     0x7fe3dae22e22 - std::panicking::default_hook::hf614597d3c67bbdb
   6:     0x7fe3dae235b7 - std::panicking::rust_panic_with_hook::h8942133a8b252070
   7:     0x7fe3dae23416 - std::panicking::begin_panic_handler::{{closure}}::hb5f5963570096b29
   8:     0x7fe3dae226c9 - std::sys::backtrace::__rust_end_short_backtrace::h6208cedc1922feda
   9:     0x7fe3dae230dc - rust_begin_unwind
  10:     0x7fe3dac7b44d - core::panicking::panic_nounwind_fmt::h357fc035dc231634
  11:     0x7fe3dac7b4e2 - core::panicking::panic_nounwind::hd0dad372654c389a
  12:     0x7fe3dac7b5a5 - core::panicking::panic_cannot_unwind::h65aefd062253eb19
  13:     0x7fe3dacce602 - mpv_open_cplugin
  14:     0x5597a5af8fdb - <unknown>
  15:     0x5597a5aee80a - <unknown>
  16:     0x5597a5aee89d - <unknown>
  17:     0x7fe3ee094ac3 - <unknown>
  18:     0x7fe3ee126850 - <unknown>
  19:                0x0 - <unknown>
thread caused non-unwinding panic. aborting.
Aborted

ls ~/.config/mpv/scripts/
libstrokers_for_mpv.d libstrokers_for_mpv.so

OS: Linux
cfg: use the same one in the site
serial_port: “/dev/ttyUSB0” (same as my XTPlayer)
hw: SR6

My XTPlayer works fine w/ serial Tcode0.3 in ttyUSB0.

If I remove the tracing_subscriber block in strokers/strokers_for_mpv/src/lib.rs at main - LaurenBoutin/strokers - Codeberg.org, I see the Illegal instruction error without any further information.

Any ideas?

I think your problem is that the plugin is being autoloaded by being in your scripts folder, plus you are loading it again by passing the --script= argument. This is causing the plugin library to be loaded once, but the plugin is being initialised twice?
Remove either the --script= argument, or move the .so somewhere else so it’s not autoloaded by default.

Illegal instruction is a weird one. What platform (particularly CPU) are you on?