Skip to content

Instantly share code, notes, and snippets.

@ishitatsuyuki
Last active February 14, 2023 09:12
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save ishitatsuyuki/6ed6308be78dd8a2f58c9a9109fe050b to your computer and use it in GitHub Desktop.
Save ishitatsuyuki/6ed6308be78dd8a2f58c9a9109fe050b to your computer and use it in GitHub Desktop.
/* mpv integration with auto-editor (https://github.com/WyattBlue/auto-editor)
*
* The script will automatically attempt to load an analysis generated by
* `auto-editor <filename> --export_as_json`. Alternatively, press "E" during
* playback and the script will automatically invoke auto-editor for you.
* The invocation options can be customized at the top of the script.
*
* Changelog:
* == v2 (2022/02/01)
* The script can now invoke auto-editor automatically with a keybind.
*
* Limitations:
* 1. The video must have a constant frame-rate; variable frame rate sources,
* sources with frame skips will have issues.
* 2. Only skipping is supported in this version. (speed != 99999 is not
* supported)
*
* Copyright 2022 Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var AUTO_EDITOR_BIN = "auto-editor";
var AUTO_EDITOR_ARGS = [];
var timeObserver;
var cmdInProgress = false;
function runAutoEditor() {
if (cmdInProgress) {
mp.osd_message("auto-editor: An analysis is already in progress");
return;
}
var file = mp.get_property("path");
var cmd = {
name: "subprocess",
playback_only: false,
args: [AUTO_EDITOR_BIN, file, "--export_as_json"] + AUTO_EDITOR_ARGS,
};
mp.osd_message("auto-editor: Running analysis");
cmdInProgress = true;
mp.command_native_async(cmd, function (success, result, error) {
cmdInProgress = false;
if (success) {
load();
} else {
console.error(error);
}
});
}
function load() {
unload(); // Unload previous callbacks
var file = mp.get_property("path");
file = file.replace(/\.[^.]+$/, ".json");
var content;
try {
content = JSON.parse(mp.utils.read_file(file));
} catch (e) {
return;
}
mp.osd_message(
"auto-editor: Loaded " + content["timeline"]["chunks"].length + " segments"
);
function reducer(agg, val) {
agg[val[0]] = {
to: val[1],
speed: val[2],
};
return agg;
}
var segments = content["timeline"]["chunks"].reduce(reducer, {});
timeObserver = function (_name, time) {
if (mp.get_property_bool("seeking")) return;
var fps = mp.get_property_number("estimated-vf-fps");
var frame = Math.round(time * fps);
if (segments[frame] != null && segments[frame].speed === 99999) {
mp.set_property_number("time-pos", segments[frame].to / fps);
}
};
mp.observe_property("time-pos", "number", timeObserver);
}
function unload() {
if (timeObserver != null) {
mp.unobserve_property(timeObserver);
timeObserver = null;
}
}
mp.register_event("start-file", load);
mp.register_event("end-file", unload);
mp.add_key_binding("E", "run-auto-editor", runAutoEditor);
@barolo
Copy link

barolo commented Jan 31, 2022

So speed-up instead of skipping is planned, isn't it? That's the only thing that I'm missing.
It would be nice to have auto-editor analysis step built-in into the script, since it's fast enough (at least for me), and then just bind it all into a shortcut.
Thank you again for this.

@ishitatsuyuki
Copy link
Author

@barolo The script can now run auto-editor for you in v2. I'll implement speed-up at a later date.

@jamesWalker55
Copy link

I think auto-editor changed their output json format - the script fails to load with this error:

[autoeditor] TypeError: cannot convert undefined to object
[autoeditor]    at load (C:/Users/James/scoop/apps/mpv/current/portable_config/scripts/autoeditor.js:74)
[autoeditor]    at dispatch_event (@/defaults.js:52)
[autoeditor]    at mp_event_loop (@/defaults.js:760)
[autoeditor]    at run_script (native)
[autoeditor] Could not load javascript C:/Users/James/scoop/apps/mpv/current/portable_config/scripts/autoeditor.js

Looking at the json of my output files, "timeline" is an empty array, it seems the "chunks" array is moved to the root scope.

A quick fix is to replace all instances of content["timeline"]["chunks"] with content["chunks"], in lines 74 and 83.

@seigneurfuo
Copy link

@jamesWalker55 Thanks for the quick fix 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment