familyfriendlymikey / mpv-cut Goto Github PK
View Code? Open in Web Editor NEWAn mpv plugin for cutting videos incredibly quickly.
An mpv plugin for cutting videos incredibly quickly.
Was testing the script with default values and i noticed that it needs to read the whole file in order do copy/encode, this makes it extremely slow for large files.
Some tests on 7.25GB file Using -c copy
12s cut took 45s on normal hard drive
Same cut on encode.lua & webm.lua makes the cut instant without reading the whole file.
I'm on Windows 10
I have videos with multiple audios (with my voice, chat party etc.)
Unfortunately, it always keeps the 1st audio by default. I personally don't want to keep all of them but if we could choose which audio we want to keep, this script would be perfect!
Celluloid version: 0.26, Snap
Steps to reproduce
main.lua
using the GUIExpected behaviour: messages show
Actual behaviour: nothing happens
File is not created after selecting a time range. Neither COPY
nor ENCODE
works.
Logged error:
[mpv_cut] node:fs:221
[mpv_cut] let mode = stats[1];
[mpv_cut] ^
[mpv_cut]
[mpv_cut] TypeError: Cannot read properties of undefined (reading '1')
[mpv_cut] at isFileType (node:fs:221:19)
[mpv_cut] at readFileSync (node:fs:470:16)
[mpv_cut] at parse_stdin (C:\Users\WDAGUtilityAccount\AppData\Roaming\mpv\scripts\mpv-cut\make_cuts:37:13)
[mpv_cut] at main (C:\Users\WDAGUtilityAccount\AppData\Roaming\mpv\scripts\mpv-cut\make_cuts:65:17)
[mpv_cut] at Object.<anonymous> (C:\Users\WDAGUtilityAccount\AppData\Roaming\mpv\scripts\mpv-cut\make_cuts:147:1)
[mpv_cut] at Module._compile (node:internal/modules/cjs/loader:1120:14)
[mpv_cut] at Module._extensions..js (node:internal/modules/cjs/loader:1174:10)
[mpv_cut] at Module.load (node:internal/modules/cjs/loader:998:32)
[mpv_cut] at Module._load (node:internal/modules/cjs/loader:839:12)
[mpv_cut] at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
[mpv_cut]
[mpv_cut] Node.js v18.7.0
OS: Windows 11 Enterprise Insider Preview 22H2 (build 25158.1000) [tried on actual Windows machine and Windows Sandbox VM - the same error]
Node.js: v18.7.0
FFmpeg: Latest Auto-Build (2022-08-09 12:37) ffmpeg-N-107736-g9e029dc265-win64-gpl.zip
Output of mpv -V
:
mpv 0.34.0-395-g9add44b11a Copyright © 2000-2022 mpv/MPlayer/mplayer2 projects
built on Sun Aug 07 12:25:20 2022
FFmpeg library versions:
libavutil 57.32.101
libavcodec 59.41.101
libavformat 59.29.100
libswscale 6.8.102
libavfilter 8.46.101
libswresample 4.8.100
FFmpeg version: git-2022-08-06-d93e29154
Decided to open another thread for this one. When you cut the video lossless it gives me only the 1st audio and subtitle. It supposed to bring every audio and subtitle when u cut a video. This is the error that shows on MPV
It doesn't work no matter if the video is .MKV, .MP4 etc. I'm not entirely sure what is the issue
I encoded a video a 18 sec vid and the timestamps are bugged. the cuts are precise and it works but for editing purposes it a mess
This is one example, nothing on the console either about any errors
Adding -sn to the code does fixes the timestamps issue but it doesn't keep the subs
If anyone can point me to the right direction on how to fix it would be appreciated.
[mpv_cut] COPY
[mpv_cut] ["duration_hms"] = 00-00-43-043
[mpv_cut] ["indir"] = https://example.com/
[mpv_cut] ["channel"] = 1
[mpv_cut] ["infile_noext"] = video
[mpv_cut] ["start_time"] = 3095.6755
[mpv_cut] ["start_time_hms"] = 00-51-35-675
[mpv_cut] ["inpath"] = https://example.com/video.mp4
[mpv_cut] ["end_time_hms"] = 00-52-18-718
[mpv_cut] ["ext"] = .mp4
[mpv_cut] ["duration"] = 43.043
[mpv_cut] ["end_time"] = 3138.7185
[mpv_cut] ["infile"] = video.mp4
[mpv_cut]
[mpv_cut] [tls @ 0x61036da53b40] A TLS fatal alert has been received.
[mpv_cut] [in#0 @ 0x61036da92100] Error opening input: Input/output error
[mpv_cut] Error opening input file https://example.com/video.mp4.
[mpv_cut] Error opening input files: Input/output error
[mpv_cut] Done
Script only cuts default audio
ok idk why it is not working. In fact I also bricked by mpv a little. Let me know what I need to run to let yall know what the problem is
[debug] Command-line config: ['-vU', 'https://youtu.be/3hWpkXXXJhI']
[debug] Encodings: locale UTF-8, fs utf-8, pref UTF-8, out utf-8, error utf-8, screen utf-8
[debug] yt-dlp version [email protected] from yt-dlp/yt-dlp [f10589e34] (zip)
[debug] Python 3.10.12 (CPython x86_64 64bit) - Linux-6.5.0-28-generic-x86_64-with-glibc2.35 (OpenSSL 3.0.2 15 Mar 2022, glibc 2.35)
[debug] exe versions: ffmpeg 4.4.2 (setts), ffprobe 4.4.2, rtmpdump 2.4
[debug] Optional libraries: Cryptodome-3.11.0, brotli-1.0.9, certifi-2020.06.20, mutagen-1.45.1, pyxattr-0.7.2, requests-2.25.1, secretstorage-3.3.1, sqlite3-3.37.2, urllib3-1.26.5, websockets-9.1
[debug] Proxy map: {}
[debug] Request Handlers: urllib
[debug] Loaded 1798 extractors
[debug] Fetching release info: https://api.github.com/repos/yt-dlp/yt-dlp/releases/latest
[debug] Downloading _update_spec from https://github.com/yt-dlp/yt-dlp/releases/latest/download/_update_spec
[debug] Downloading SHA2-256SUMS from https://github.com/yt-dlp/yt-dlp/releases/download/2024.04.09/SHA2-256SUMS
Current version: [email protected] from yt-dlp/yt-dlp
Latest version: [email protected] from yt-dlp/yt-dlp
Current Build Hash: 1965bf8dcf181a8e6adb99c0ec4cdaaae5e2d01ba1f5198f68535305d5ae94b2
Updating to [email protected] from yt-dlp/yt-dlp ...
ERROR: Unable to write to /usr/local/bin/yt-dlp; try running as administrator
[youtube] Extracting URL: https://youtu.be/3hWpkXXXJhI
[youtube] 3hWpkXXXJhI: Downloading webpage
[youtube] 3hWpkXXXJhI: Downloading ios player API JSON
[youtube] 3hWpkXXXJhI: Downloading android player API JSON
WARNING: [youtube] YouTube said: ERROR - Precondition check failed.
WARNING: [youtube] HTTP Error 400: Bad Request. Retrying (1/3)...
[youtube] 3hWpkXXXJhI: Downloading android player API JSON
WARNING: [youtube] YouTube said: ERROR - Precondition check failed.
WARNING: [youtube] HTTP Error 400: Bad Request. Retrying (2/3)...
[youtube] 3hWpkXXXJhI: Downloading android player API JSON
WARNING: [youtube] YouTube said: ERROR - Precondition check failed.
WARNING: [youtube] HTTP Error 400: Bad Request. Retrying (3/3)...
[youtube] 3hWpkXXXJhI: Downloading android player API JSON
WARNING: [youtube] YouTube said: ERROR - Precondition check failed.
WARNING: [youtube] Unable to download API page: HTTP Error 400: Bad Request (caused by <HTTPError 400: Bad Request>); please report this issue on https://github.com/yt-dlp/yt-dlp/issues?q= , filling out the appropriate issue template. Confirm you are on the latest version using yt-dlp -U
[debug] Loading youtube-nsig.8fc6998a from cache
[debug] [youtube] Decrypted nsig aETKNObiQpZpvJPi => IXAH77Bj2c9JGg
[debug] Loading youtube-nsig.8fc6998a from cache
[debug] [youtube] Decrypted nsig S21kgYuqxUppFSFH => jW-RaZS31CRA6A
[youtube] 3hWpkXXXJhI: Downloading m3u8 information
[debug] Sort order given by extractor: quality, res, fps, hdr:12, source, vcodec:vp9.2, channels, acodec, lang, proto
[debug] Formats sorted by: hasvid, ie_pref, quality, res, fps, hdr:12(7), source, vcodec:vp9.2(10), channels, acodec, lang, proto, size, br, asr, vext, aext, hasaud, id
[debug] Default format spec: bestvideo*+bestaudio/best
[info] 3hWpkXXXJhI: Downloading 1 format(s): 605+251
[debug] Invoking hlsnative downloader on "https://manifest.googlevideo.com/api/manifest/hls_playlist/expire/1714636777/ei/ifMyZs-1MtmEkucP4Jmk6AY/ip/24.169.6.163/id/de15a99175d72612/itag/605/source/youtube/requiressl/yes/ratebypass/yes/pfa/1/wft/1/sgovp/clen%3D622880%3Bdur%3D25.125%3Bgir%3Dyes%3Bitag%3D243%3Blmt%3D1674533834671149/rqh/1/hls_chunk_host/rr1---sn-ab5sznzl.googlevideo.com/xpc/EgVo2aDSNQ%3D%3D/mh/Qq/mm/31,26/mn/sn-ab5sznzl,sn-vgqsknek/ms/au,onr/mv/m/mvi/1/pl/17/initcwndbps/1351250/vprv/1/playlist_type/DVR/dover/13/txp/6216224/mt/1714614780/fvip/2/short_key/1/keepalive/yes/sparams/expire,ei,ip,id,itag,source,requiressl,ratebypass,pfa,wft,sgovp,rqh,xpc,vprv,playlist_type/sig/AJfQdSswRgIhANFck6XNYAtPJVEuPgagFlr4wa_I-PlFBfPi25Xw0I5zAiEAva5AIvPLHwgXkgsX8qrntqWZo7hTRxmnx2IlOSjV77s%3D/lsparams/hls_chunk_host,mh,mm,mn,ms,mv,mvi,pl,initcwndbps/lsig/AHWaYeowRgIhAJdZoc-20q-nDayOWQ_Da6rgDIi2dVtCJlO_3O2oKi4OAiEAtRi_TbtDVZtdllqUcRg9HLvD4hYlPMQdkw7HnJtUg4M%3D/playlist/index.m3u8"
[hlsnative] Downloading m3u8 manifest
[hlsnative] Total fragments: 5
[download] Destination: How They Rob Men in Chicago - 1900 - Wallace McCutcheon COLORIZED [3hWpkXXXJhI].f605.mp4
[download] 100% of 612.99KiB in 00:00:01 at 512.13KiB/s
[debug] Invoking http downloader on "https://rr1---sn-ab5sznzl.googlevideo.com/videoplayback?expire=1714636777&ei=ifMyZsm0C_mSkucP_5G3sAY&ip=24.169.6.163&id=o-ABskzxxusgja9b9lm5yixcbxoI_rWvd0mGc-umgAKQTd&itag=251&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&mh=Qq&mm=31%2C26&mn=sn-ab5sznzl%2Csn-vgqsrnek&ms=au%2Conr&mv=m&mvi=1&pl=17&initcwndbps=1161250&bui=AWRWj2SQnR0kb506Ckogm5mzOS3ZkZPU_15LJvZwR28Gv4TDez0Qh_CYN7zxM_FTVecq1icV8Avm1w_c&spc=UWF9f9ET8R6GHT45IYT08TmdIo9ntMq_DQD74_SLUzKBvUFr6da1RJ5xHiFM&vprv=1&svpuc=1&mime=audio%2Fwebm&ns=L3a39hfZ6tHTeY_hMvc1PhQQ&gir=yes&clen=11650&dur=25.121&lmt=1625838689573507&mt=1714615012&fvip=1&keepalive=yes&c=WEB&sefc=1&txp=6211224&n=jW-RaZS31CRA6A&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cbui%2Cspc%2Cvprv%2Csvpuc%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AJfQdSswRgIhALqQIg-vhd912NaOk__UEhCg5ii4Oa17OdeEX27e77UmAiEAu8GNVAt6kooDb_SilU_ouKm6p8sm5EaW86TPL7uW-_E%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AHWaYeowRQIgbU9YlUlol51W0dYLQn4YErkJ6JOIhFoIqp7UpEGQUcsCIQCImxG_ugsRtxxidHGMRKOeGsfFEBe9hSSt1D6u28g-dA%3D%3D"
[download] Destination: How They Rob Men in Chicago - 1900 - Wallace McCutcheon COLORIZED [3hWpkXXXJhI].f251.webm
[download] 100% of 11.38KiB in 00:00:00 at 81.89KiB/s
[Merger] Merging formats into "How They Rob Men in Chicago - 1900 - Wallace McCutcheon COLORIZED [3hWpkXXXJhI].webm"
[debug] ffmpeg command line: ffmpeg -y -loglevel repeat+info -i 'file:How They Rob Men in Chicago - 1900 - Wallace McCutcheon COLORIZED [3hWpkXXXJhI].f605.mp4' -i 'file:How They Rob Men in Chicago - 1900 - Wallace McCutcheon COLORIZED [3hWpkXXXJhI].f251.webm' -c copy -map 0:v:0 -map 1:a:0 -movflags +faststart 'file:How They Rob Men in Chicago - 1900 - Wallace McCutcheon COLORIZED [3hWpkXXXJhI].temp.webm'
Deleting original file How They Rob Men in Chicago - 1900 - Wallace McCutcheon COLORIZED [3hWpkXXXJhI].f251.webm (pass -k to keep)
Deleting original file How They Rob Men in Chicago - 1900 - Wallace McCutcheon COLORIZED [3hWpkXXXJhI].f605.mp4 (pass -k to keep)
This is set as soon as mpv is running, in line 133
mp.set_property_native("chapter-list", {})
Without it, mpv chapters work as they should normally.
I assume there's a certain behaviour needed for the script to function properly?
Hi,
I've just found your script which perfectly solves my use-case of splitting a video into (potential multiple) smaller ones. Unfortunately, my initial test ended in an error.
Debian bookworm. mpv 0.35.1. FFmpeg version: 5.1.3-1.
I've set up your tool using the git command from the README.
mpv video.mp4
i
0
to start the cutting process(es) -> "Error reading cut list" is shown in the mpv overlay as well as on stdoutSince I freshly installed the script and I don't have other mpv scripts set up (yet), I assume this is a bug and not an error on my side.
Do you have any suggestion for me? Should I check something for analyzing the situation?
user@host ~2cut % [mpv_cut] MPV-CUT LOADED.
(+) Video --vid=1 (*) (h264 720x576 25.000fps)
(+) Audio --aid=1 (*) (aac 2ch 48000Hz)
[mpv_cut] ["infile_noext"] = video
[mpv_cut] ["inpath"] = video.mp4
[mpv_cut] ["ext"] = .mp4
[mpv_cut] ["indir"] = .
[mpv_cut] ["channel"] = 1
[mpv_cut] ["infile"] = video.mp4
[mpv_cut]
AO: [pipewire] 48000Hz stereo 2ch floatp
VO: [gpu] 720x576 yuv420p
[mpv_cut] ["infile_noext"] = video
[mpv_cut] ["inpath"] = video.mp4
[mpv_cut] ["ext"] = .mp4
[mpv_cut] ["indir"] = .
[mpv_cut] ["channel"] = 1
[mpv_cut] ["infile"] = video.mp4
[mpv_cut]
[mpv_cut] ["infile_noext"] = video
[mpv_cut] ["inpath"] = video.mp4
[mpv_cut] ["ext"] = .mp4
[mpv_cut] ["indir"] = .
[mpv_cut] ["channel"] = 1
[mpv_cut] ["infile"] = video.mp4
[mpv_cut]
[mpv_cut] Δ 6, 1
[mpv_cut] ["infile_noext"] = video
[mpv_cut] ["inpath"] = video.mp4
[mpv_cut] ["ext"] = .mp4
[mpv_cut] ["indir"] = .
[mpv_cut] ["channel"] = 1
[mpv_cut] ["infile"] = video.mp4
[mpv_cut]
[mpv_cut] ["infile_noext"] = video
[mpv_cut] ["inpath"] = video.mp4
[mpv_cut] ["ext"] = .mp4
[mpv_cut] ["indir"] = .
[mpv_cut] ["channel"] = 1
[mpv_cut] ["infile"] = video.mp4
[mpv_cut]
[mpv_cut] Δ 6, 1
[mpv_cut] ["infile_noext"] = video
[mpv_cut] ["inpath"] = video.mp4
[mpv_cut] ["ext"] = .mp4
[mpv_cut] ["indir"] = .
[mpv_cut] ["channel"] = 1
[mpv_cut] ["infile"] = video.mp4
[mpv_cut]
[mpv_cut] ["infile_noext"] = video
[mpv_cut] ["inpath"] = video.mp4
[mpv_cut] ["ext"] = .mp4
[mpv_cut] ["indir"] = .
[mpv_cut] ["channel"] = 1
[mpv_cut] ["infile"] = video.mp4
[mpv_cut]
[mpv_cut] Δ 7, 1
[mpv_cut] MAKING CUTS
[mpv_cut] Error reading cut list
Exiting... (Quit)
[1] + 3569179 done mpv video.mp4
user@host ~2cut % cat 1_video.mp4.book
22.88
75.72
234.04
user@host ~2cut %
Is it possible to autoload bookmarks when you open a video?
As I understand there is a function in main.lua
called bookmarks_load()
but I don't know how to call it at every new file automatically. Thanks.
I think it is normal that i cant cut 4:2:2 10 bit from my gh5 but if someone could help me to do it with mpv-cut it would be incredible. Thanks !
On choosing any of the cutting modes, the subtitles in a video lose all styling and become basic subtitles. Is there a way to retain the styling while making the cut?
I'm using Linux. When I try cutting using either c
or the cut list and 0
, no cut files appear. I tried toggling to global directory mode and they don't show up there, either.
I don't see any errors at all in the mpv logs, it just says "Making cuts" and then "Done."
I tried following the code, I suppose it's intended to call that make_cuts.imba file? I don't know if that ever happens, or if it fails in any way.
Any clue what I could try to debug?
Hi,
I'd like to change the placement of the text, e.g., that gets printed via local function text_overlay_on()
and similar.
Reason: in my setup (I don't know if this is specific to me or default behavior), when pressing o
in mpv, I get something like "00:09:00 / 01:29:28 (7%)" at the top of the on-screen display of mpv, indicating the current playback position.
mpv-cut is also using the very same display position to write its OSD text. Therefore, I can't read both, the current playback position as well as mpv-cut information because of this issue.
I tried to find out how to change the position in lua via Internet search but failed so far. Maybe you can add an option to the source code that users might place mpv-cut information to a different position like "bottom" in my case, which separates my usual OSD information from the OSD information of mpv-cut.
Thank you!
This would help package your script in Linux distributions.
Let me explain: I have the majority of my shows on a samba share where I can't write and I'd like to be able to tell this script that when I make a cut on a file in a certain folder (where the samba share is) I want it to put in another directory (like ~/Videos/Cuts or something), but when I do a cut on a file that isn't in that location it just places it normally.
Would that be possible to implement?
In response to a github user who messaged me elsewhere about reintroducing the hardsubs feature:
I think I may have a great idea regarding this, sort of similar to what you mentioned. I'm assuming you're familiar with the fact that the script generates a "cut list" text file, which you can feed to the included Python script make_cuts
to make the cuts. It was already somewhat of a pain to jump in a terminal, navigate to the correct directory, and run make_cuts
. But what if we were to forego the cut list and make_cuts files entirely, and instead have mpv-cut generate a Python file, such as LIST_CHANNEL_NAME_Source_Video_File_Name.mkv.py
, which would act as both the cut list for backup purposes and as the make_cuts script:
filename = "LIST_CHANNEL_NAME_Source_Video_File_Name.mkv"
timestamps = [
(105.67, 108),
(156, 187),
(256, 270.12432)
]
hardsubs = True
import ffmpeg
...
To be clear, this would mean that the "hardsubs" option wouldn't actually generate a video file with hardsubs. Instead, by default mpv-cut would generate a cut list which would now be a self-contained python file that gets placed in the same directory as the source video, which you would simply double click to execute once you're done watching your video, and enabling the "hardsubs" option would generate a script where hardsubs = True
.
This has several pros:
files = [
{
filename: "LIST_CHANNEL_NAME_Source_Video_File_Name.mkv",
timestamps = [
(105.67, 108),
(156, 187),
(256, 270.12432)
]
}
]
hardsubs = True
import ffmpeg
...
and instead of dealing with just one file, we loop through the filenames
list. This way, the user can easily combine multiple cut lists together by pasting additional file objects into the files dict (I have some ideas to make this even more convenient but maybe later).
Furthermore, if the user wants to change the behavior of the generated script or supply some flags to ffmpeg without having to edit the script, we could allow easy passing of args by doing something like:
files = [
...
]
import sys
if len(sys.argv) > 2:
args = sys.argv[2:]
else:
# this else block would contain the options the user chose
# inside of mpv, for example having hardsubs toggled on
args = ["hardsubs"]
import ffmpeg
...
This way, we could potentially add even more functionality, such as a concat option or a framerate option (not inside of mpv-cut, but as commandline args to the generated cut list script).
The drawbacks, which IMO are completely negligible, are that
global
option, the cut list and cut will be placed at the global dir, so double clicking the cut list Python file won't work. If someone does want that functionality, we could store the absolute path to the source file and check if it exists, and if not use the current directory.Let me know if you disagree with anything. I know for some people one extra step can be a dealbreaker, but compared to the reduced complexity in mpv/increased modularity and flexibility this provides, I think this seems like a great workflow. There are some technicalities to deal with but this shouldn't be too hard. I'm open to discussion though.
If you do like this idea, I'd be down to implement it if you figure out the Python ffmpeg wrapper queries for hardsubs, assuming they exist.
Can you add option to have human readable time format ("HH:MM:SS:mmm") in filenames, please. The problem is to send excerpts to other people so they could identify position in the original file by themselves.
mpv_cut is installed correctly. stdout shows
[mpv_cut] MPV-CUT LOADED
Pressing a
, g
, and l
does work and does toggle between modes. Pressing 0
however, gives the error "Failed to load cut list". Pressing c
does nothing.
The script sometimes works when the -v option is specified, and it does make the cuts. But when it doesn't, no error shows up in the verbose output.
Winver is 21H2 (OS Build 19044.2486)
Here's the MediaInfo for both files. Left is encode and right is copy.
Both files are cut at the exact frame. The issue is that the metadata for the encode is 13:33
even though MediaInfo suggests that the video should only be 48 seconds long. This error is not present for the copy file, where all duration fields have marginal error.
how can I output to my dir folder
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.