mirror of
https://github.com/familyfriendlymikey/mpv-cut
synced 2024-07-01 12:08:58 +00:00
add cancel_cut binding, add bash utils with functions make_cuts and concat, remove make_cuts
binding
This commit is contained in:
parent
26ad54b42d
commit
6849b272a4
131
README.md
131
README.md
@ -50,6 +50,8 @@ That's all you have to do, next time you run mpv the script will be automaticall
|
|||||||
|
|
||||||
The resulting cut will be placed in the same directory as the source file.
|
The resulting cut will be placed in the same directory as the source file.
|
||||||
|
|
||||||
|
- You can press `C` to cancel a cut.
|
||||||
|
|
||||||
### Actions
|
### Actions
|
||||||
|
|
||||||
You can press `a` to cycle between three default actions:
|
You can press `a` to cycle between three default actions:
|
||||||
@ -80,9 +82,37 @@ the channel and `=` to increment the channel.
|
|||||||
|
|
||||||
You can configure a name for each channel as shown below.
|
You can configure a name for each channel as shown below.
|
||||||
|
|
||||||
### Making Cuts
|
### Utils
|
||||||
|
|
||||||
If you want to make all the cuts stored in a cut list, simply press `0`.
|
This plugin includes a `utils` script that you can source in your shell's
|
||||||
|
startup file. In my `~/.zshrc` I have this line:
|
||||||
|
|
||||||
|
```
|
||||||
|
source ~/.config/mpv/scripts/mpv-cut/utils
|
||||||
|
```
|
||||||
|
|
||||||
|
Now when you open new terminals, you'll have access to the functions inside of
|
||||||
|
the `utils` script, which are explained in this section.
|
||||||
|
|
||||||
|
#### Making Cuts
|
||||||
|
|
||||||
|
The `make_cuts` function takes a `.list` file and ffmpeg output options except
|
||||||
|
for an output filename. To make cuts without reencoding:
|
||||||
|
|
||||||
|
```
|
||||||
|
make_cuts some_video.mp4.list -c copy
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Concatenate, Merge, Join Cuts
|
||||||
|
|
||||||
|
The `concat` function takes a prefix and ffmpeg output options. Any file in the current directory
|
||||||
|
starting with the prefix will be included. For example, to concatenate all
|
||||||
|
files in the current directory whose filename starts with `CUT` without
|
||||||
|
reencoding:
|
||||||
|
|
||||||
|
```
|
||||||
|
concat CUT -c copy output.mp4
|
||||||
|
```
|
||||||
|
|
||||||
## Config
|
## Config
|
||||||
|
|
||||||
@ -94,29 +124,41 @@ You can include or omit any of the following:
|
|||||||
```lua
|
```lua
|
||||||
-- Key config
|
-- Key config
|
||||||
KEY_CUT = "c"
|
KEY_CUT = "c"
|
||||||
KEY_CYCLE_ACTION = "a"
|
|
||||||
KEY_BOOKMARK_ADD = "i"
|
|
||||||
KEY_CHANNEL_INC = "="
|
|
||||||
KEY_CHANNEL_DEC = "-"
|
|
||||||
KEY_MAKE_CUTS = "0"
|
|
||||||
|
|
||||||
-- The list of channel names, you can choose whatever you want.
|
-- The list of channel names, you can choose whatever you want.
|
||||||
CHANNEL_NAMES[1] = "FUNNY"
|
CHANNEL_NAMES[1] = "FUNNY"
|
||||||
CHANNEL_NAMES[2] = "COOL"
|
|
||||||
|
|
||||||
-- The default channel
|
-- The default channel
|
||||||
CHANNEL = 1
|
CHANNEL = 1
|
||||||
|
|
||||||
-- The default action
|
-- The default action
|
||||||
ACTION = "ENCODE"
|
ACTION = "COPY"
|
||||||
|
|
||||||
-- The action to use when making cuts from a cut list
|
|
||||||
MAKE_CUT = ACTIONS.COPY
|
|
||||||
|
|
||||||
-- Delete a default action
|
-- Delete a default action
|
||||||
ACTIONS.LIST = nil
|
ACTIONS.LIST = nil
|
||||||
|
```
|
||||||
|
|
||||||
-- Specify custom actions
|
### Custom Actions
|
||||||
|
|
||||||
|
In the config file you can also specify custom actions. Even if you don't know
|
||||||
|
Lua, it should be pretty straightforward to take the following example and tune
|
||||||
|
it to your needs. I think this is a very powerful abstraction. All of the
|
||||||
|
default actions are implemented the same way you'd implement custom actions.
|
||||||
|
|
||||||
|
You can essentially define an arbitrary callback to run whenever an action is
|
||||||
|
invoked (the second time you press `c` in mpv). The callback function gets
|
||||||
|
passed a table with the following properties:
|
||||||
|
|
||||||
|
```
|
||||||
|
inpath, indir, infile, infile_noext, ext
|
||||||
|
channel
|
||||||
|
start_time, end_time, duration
|
||||||
|
start_time_hms, end_time_hms, duration_hms
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is an example overwriting the default `ENCODE` action:
|
||||||
|
|
||||||
|
```lua
|
||||||
ACTIONS.ENCODE = function(d)
|
ACTIONS.ENCODE = function(d)
|
||||||
local args = {
|
local args = {
|
||||||
"ffmpeg",
|
"ffmpeg",
|
||||||
@ -136,12 +178,6 @@ ACTIONS.ENCODE = function(d)
|
|||||||
playback_only = false,
|
playback_only = false,
|
||||||
}, function() print("Done") end)
|
}, function() print("Done") end)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- The table that gets passed to an action will have the following properties:
|
|
||||||
-- inpath, indir, infile, infile_noext, ext
|
|
||||||
-- channel
|
|
||||||
-- start_time, end_time, duration
|
|
||||||
-- start_time_hms, end_time_hms, duration_hms
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Optimized MPV Input Config
|
## Optimized MPV Input Config
|
||||||
@ -152,16 +188,18 @@ quickly editing videos.
|
|||||||
```
|
```
|
||||||
RIGHT seek 2 exact
|
RIGHT seek 2 exact
|
||||||
LEFT seek -2 exact
|
LEFT seek -2 exact
|
||||||
|
UP seek 2 keyframes
|
||||||
|
DOWN seek -2 keyframes
|
||||||
|
|
||||||
] add speed 0.5
|
] add speed 0.5
|
||||||
[ add speed -0.5
|
[ add speed -0.5
|
||||||
} add speed 0.25
|
} add speed 0.25
|
||||||
{ add speed -0.25
|
{ add speed -0.25
|
||||||
|
\ set speed 1
|
||||||
|
|
||||||
SPACE cycle pause; set speed 1 # Reset speed whenever pausing.
|
BS script-binding osc/visibility
|
||||||
BS script-binding osc/visibility # Make progress bar stay visible.
|
|
||||||
UP seek 0.01 keyframes # Seek by keyframes only.
|
Alt+= add video-zoom 0.1
|
||||||
DOWN seek -0.01 keyframes # Seek by keyframes only.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You may also want to change your key repeat delay and rate by tweaking
|
You may also want to change your key repeat delay and rate by tweaking
|
||||||
@ -249,53 +287,6 @@ editors.
|
|||||||
- If the video's compression isn't efficient enough to upload to a messaging
|
- If the video's compression isn't efficient enough to upload to a messaging
|
||||||
platform or something, you may want to compress it more.
|
platform or something, you may want to compress it more.
|
||||||
|
|
||||||
### How Do I Concatenate Videos Manually With ffmpeg?
|
|
||||||
|
|
||||||
To concatenate videos with ffmpeg, you need to create a file with content like
|
|
||||||
this:
|
|
||||||
|
|
||||||
```
|
|
||||||
file cut_1.mp4
|
|
||||||
file cut_2.mp4
|
|
||||||
file cut_3.mp4
|
|
||||||
file cut_4.mp4
|
|
||||||
```
|
|
||||||
|
|
||||||
You can name the file whatever you want, here I named it `concat.txt`.
|
|
||||||
|
|
||||||
Then run the command:
|
|
||||||
|
|
||||||
```
|
|
||||||
ffmpeg -f concat -safe 0 -i concat.txt -c copy out.mp4
|
|
||||||
```
|
|
||||||
|
|
||||||
That's annoying though, so you can skip manually creating the file by using
|
|
||||||
bash. This command will concatenate all files in the current directory that
|
|
||||||
begin with "COPY_":
|
|
||||||
|
|
||||||
```
|
|
||||||
ffmpeg -f concat -safe 0 -i <(printf 'file %q\n' "$PWD"/COPY_*) -c copy lol.mp4
|
|
||||||
```
|
|
||||||
|
|
||||||
- You need to escape apostrophes which is why we are using `printf %q
|
|
||||||
"$string"`.
|
|
||||||
|
|
||||||
- Instead of actually creating a file we just use process substitution
|
|
||||||
`<(whatever)` to create a temporary file, which is why we need the `$PWD` in
|
|
||||||
there for the absolute path.
|
|
||||||
|
|
||||||
You can also do it in vim, among other things.
|
|
||||||
|
|
||||||
```
|
|
||||||
ls | vim -
|
|
||||||
:%s/'/\\'/g
|
|
||||||
:%norm Ifile
|
|
||||||
:wq concat.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
This substitution might not cover all cases, but whatever, if you're
|
|
||||||
concatenating a file named `[{}1;']["!.mp4` you can figure it out yourself.
|
|
||||||
|
|
||||||
### Can I Make Seeking And Reverse Playback Faster?
|
### Can I Make Seeking And Reverse Playback Faster?
|
||||||
|
|
||||||
Depending on the encoding of the video file being played, the following may be
|
Depending on the encoding of the video file being played, the following may be
|
||||||
|
33
main.lua
33
main.lua
@ -111,6 +111,7 @@ CHANNEL = 1
|
|||||||
CHANNEL_NAMES = {}
|
CHANNEL_NAMES = {}
|
||||||
|
|
||||||
KEY_CUT = "c"
|
KEY_CUT = "c"
|
||||||
|
KEY_CANCEL_CUT = "C"
|
||||||
KEY_CYCLE_ACTION = "a"
|
KEY_CYCLE_ACTION = "a"
|
||||||
KEY_BOOKMARK_ADD = "i"
|
KEY_BOOKMARK_ADD = "i"
|
||||||
KEY_CHANNEL_INC = "="
|
KEY_CHANNEL_INC = "="
|
||||||
@ -187,30 +188,6 @@ local function cycle_action()
|
|||||||
print_or_update_text_overlay("ACTION: " .. ACTION)
|
print_or_update_text_overlay("ACTION: " .. ACTION)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function make_cuts()
|
|
||||||
print("MAKING CUTS")
|
|
||||||
if not MAKE_CUT then print("MAKE_CUT function not found.") return end
|
|
||||||
local inpath = mp.get_property("path") .. ".list"
|
|
||||||
local file = io.open(inpath, "r")
|
|
||||||
if not file then print("Error reading cut list") return end
|
|
||||||
for line in file:lines() do
|
|
||||||
if line ~= "" then
|
|
||||||
local cut = {}
|
|
||||||
for token in string.gmatch(line, "[^" .. ":" .. "]+") do
|
|
||||||
table.insert(cut, token)
|
|
||||||
end
|
|
||||||
local d = get_data()
|
|
||||||
d.channel = cut[1]
|
|
||||||
local t = get_times(tonumber(cut[2]), tonumber(cut[3]))
|
|
||||||
for k, v in pairs(t) do d[k] = v end
|
|
||||||
mp.msg.info("MAKE_CUT")
|
|
||||||
mp.msg.info(table_to_str(d))
|
|
||||||
MAKE_CUT(d)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
io.close(file)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function cut(start_time, end_time)
|
local function cut(start_time, end_time)
|
||||||
local d = get_data()
|
local d = get_data()
|
||||||
local t = get_times(start_time, end_time)
|
local t = get_times(start_time, end_time)
|
||||||
@ -237,6 +214,12 @@ local function put_time()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function cancel_cut()
|
||||||
|
text_overlay_off()
|
||||||
|
START_TIME = nil
|
||||||
|
print("CANCELLED CUT")
|
||||||
|
end
|
||||||
|
|
||||||
local function get_bookmark_file_path()
|
local function get_bookmark_file_path()
|
||||||
local d = get_data()
|
local d = get_data()
|
||||||
mp.msg.info(table_to_str(d))
|
mp.msg.info(table_to_str(d))
|
||||||
@ -289,10 +272,10 @@ local function channel_dec()
|
|||||||
end
|
end
|
||||||
|
|
||||||
mp.add_key_binding(KEY_CUT, "cut", put_time)
|
mp.add_key_binding(KEY_CUT, "cut", put_time)
|
||||||
|
mp.add_key_binding(KEY_CANCEL_CUT, "cancel_cut", cancel_cut)
|
||||||
mp.add_key_binding(KEY_BOOKMARK_ADD, "bookmark_add", bookmark_add)
|
mp.add_key_binding(KEY_BOOKMARK_ADD, "bookmark_add", bookmark_add)
|
||||||
mp.add_key_binding(KEY_CHANNEL_INC, "channel_inc", channel_inc)
|
mp.add_key_binding(KEY_CHANNEL_INC, "channel_inc", channel_inc)
|
||||||
mp.add_key_binding(KEY_CHANNEL_DEC, "channel_dec", channel_dec)
|
mp.add_key_binding(KEY_CHANNEL_DEC, "channel_dec", channel_dec)
|
||||||
mp.add_key_binding(KEY_CYCLE_ACTION, "cycle_action", cycle_action)
|
mp.add_key_binding(KEY_CYCLE_ACTION, "cycle_action", cycle_action)
|
||||||
mp.add_key_binding(KEY_MAKE_CUTS, "make_cuts", make_cuts)
|
|
||||||
|
|
||||||
mp.register_event('file-loaded', bookmarks_load)
|
mp.register_event('file-loaded', bookmarks_load)
|
||||||
|
19
utils
Normal file
19
utils
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
|
||||||
|
concat() {
|
||||||
|
local prefix="$1"
|
||||||
|
shift
|
||||||
|
ffmpeg -f concat -safe 0 -i <(printf 'file %q\n' "$PWD"/"$prefix"*) "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
make_cuts() {
|
||||||
|
local list="$1"
|
||||||
|
local vid="${list%.*}"
|
||||||
|
local ext="${vid##*.}"
|
||||||
|
local vid_noext="${vid%.*}"
|
||||||
|
shift
|
||||||
|
while IFS=: read -r channel_name start_ts end_ts; do
|
||||||
|
if [[ -z "$end_ts" ]]; then continue; fi
|
||||||
|
ffmpeg -nostdin -ss "$start_ts" -to "$end_ts" -i "$vid" "$@" "CUT_${channel_name}_${vid}_${start_ts}_${end_ts}.${ext}"
|
||||||
|
done < "$list"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user