diff --git a/docs/html/.buildinfo b/docs/html/.buildinfo index 0406037..eb9e22f 100644 --- a/docs/html/.buildinfo +++ b/docs/html/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 8083ae105364b70c5322521fb0238a67 +config: e1a4d8a52e5165c4be5c44f8bc7ae4d8 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/html/_modules/acsuite.html b/docs/html/_modules/acsuite.html index 9917c67..6ff1eb3 100644 --- a/docs/html/_modules/acsuite.html +++ b/docs/html/_modules/acsuite.html @@ -8,7 +8,7 @@ -
"""Frame-based cutting/trimming/splicing of audio with VapourSynth and FFmpeg."""
__all__ = ['eztrim']
__author__ = 'Dave <orangechannel@pm.me>'
-__date__ = '3 August 2020'
+__date__ = '10 August 2020'
__credits__ = """AzraelNewtype, for the original audiocutter.py.
Ricardo Constantino (wiiaboo), for vfr.py from which this was inspired.
doop, for explaining the use of None for empty slicing
+Vardë, for fixing FFmpeg's >4GB WAV file issues
"""
-__version__ = '5.1.0'
+__version__ = '5.2.0'
import collections
import fractions
@@ -183,6 +184,7 @@ Source code for acsuite
*,
ffmpeg_path: Optional[Path] = None,
quiet: bool = False,
+ timecodes_file: Optional[Path] = None,
debug: bool = False
) -> Optional[Dict[str, Union[int, List[int], List[str]]]]:
"""
@@ -226,6 +228,8 @@ Source code for acsuite
If ``ffmpeg`` exists in your `PATH`, it will automatically be detected and used.
:param quiet: Suppresses most console output from FFmpeg
+ :param timecodes_file: Timecodes v2 file (generated by vspipe, ffms2, etc.) for variable-frame-rate clips.
+ Not needed for CFR clips.
:param debug: Used for testing purposes
"""
if debug:
@@ -250,7 +254,7 @@ Source code for acsuite
'.sbc',
'.thd',
'.tta',
- '.wav',
+ '.wav', 'w64',
'.wma',
}
if audio_file_ext not in ffmpeg_valid_encoder_extensions:
@@ -258,7 +262,7 @@ Source code for acsuite
audio_file_ext = '.wav'
codec_args = []
else:
- codec_args = ['-c:a', 'copy']
+ codec_args = ['-c:a', 'copy', '-rf64', 'auto']
if outfile is None:
outfile = audio_file_name + '_cut' + audio_file_ext
@@ -274,13 +278,16 @@ Source code for acsuite
ffmpeg_path = which('ffmpeg')
else:
if not os.path.isfile(ffmpeg_path):
- raise FileNotFoundError(f"ffmpeg executable at {ffmpeg_path} not found")
+ raise FileNotFoundError(f"eztrim: ffmpeg executable at {ffmpeg_path} not found")
try:
args = ['ffmpeg', '-version']
if subprocess.run(args, stdout=subprocess.PIPE, text=True).stdout.split()[0] != 'ffmpeg':
- raise ValueError("ffmpeg executable not working properly")
+ raise ValueError("eztrim: ffmpeg executable not working properly")
except FileNotFoundError:
- raise FileNotFoundError("ffmpeg executable not found in PATH") from None
+ raise FileNotFoundError("eztrim: ffmpeg executable not found in PATH") from None
+
+ if timecodes_file is not None and not os.path.isfile(timecodes_file):
+ raise FileNotFoundError(f"eztrim: {timecodes_file} not found")
# error checking ------------------------------------------------------------------------
if not isinstance(trims, (list, tuple)):
@@ -309,7 +316,7 @@ Source code for acsuite
# --------------------------------------------
num_frames = clip.num_frames
- ts = functools.partial(f2ts, src_clip=clip)
+ ts = functools.partial(f2ts, timecodes_file=timecodes_file, src_clip=clip)
if isinstance(trims, tuple):
start, end = _negative_to_positive(num_frames, *trims)
@@ -358,10 +365,11 @@ Source code for acsuite
os.remove(file)
-def f2ts(f: int, /, *, precision: int = 3, src_clip: vs.VideoNode) -> str:
+def f2ts(f: int, /, *, precision: int = 3, timecodes_file: Optional[Path] = None, src_clip: vs.VideoNode) -> str:
"""Converts frame number to a timestamp based on framerate.
Can handle variable-frame-rate clips as well, using similar methods to that of vspipe --timecodes.
+ For VFR clips, will use a timecodes v2 file if given, else will fallback to the slower frames() method.
Meant to be called as a functools.partial with 'src_clip' specified before-hand.
"""
if precision not in [0, 3, 6, 9]:
@@ -370,7 +378,11 @@ Source code for acsuite
t = round(10 ** 9 * f * src_clip.fps ** -1)
s = t / 10 ** 9
else:
- s = clip_to_timecodes(src_clip)[f]
+ if timecodes_file is not None:
+ timecodes = [float(x)/1000 for x in open(timecodes_file, 'r').read().splitlines()[1:]]
+ s = timecodes[f]
+ else:
+ s = clip_to_timecodes(src_clip)[f]
m = s // 60
s %= 60
@@ -392,9 +404,14 @@ Source code for acsuite
"""Cached function to return a list of timecodes for vfr clips."""
timecodes = collections.deque([0.0], maxlen=src_clip.num_frames + 1)
curr_time = fractions.Fraction()
+ init_percentage = 0
for frame in src_clip.frames():
curr_time += fractions.Fraction(frame.props['_DurationNum'], frame.props['_DurationDen'])
timecodes.append(float(curr_time))
+ percentage_done = round(100 * len(timecodes) / src_clip.num_frames)
+ if percentage_done % 10 == 0 and percentage_done != init_percentage:
+ print(rf"Finding timecodes for variable-framerate clip: {percentage_done}% done")
+ init_percentage = percentage_done
return timecodes
diff --git a/docs/html/_modules/index.html b/docs/html/_modules/index.html
index 3dc0a26..d7aaff1 100644
--- a/docs/html/_modules/index.html
+++ b/docs/html/_modules/index.html
@@ -8,7 +8,7 @@
- Overview: module code — acsuite 5.1.0 documentation
+ Overview: module code — acsuite 5.2.0 documentation
@@ -59,7 +59,7 @@
- 5.1.0
+ 5.2.0
diff --git a/docs/html/_static/documentation_options.js b/docs/html/_static/documentation_options.js
index 59a603d..52ee168 100644
--- a/docs/html/_static/documentation_options.js
+++ b/docs/html/_static/documentation_options.js
@@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
- VERSION: '5.1.0',
+ VERSION: '5.2.0',
LANGUAGE: 'en',
COLLAPSE_INDEX: false,
BUILDER: 'html',
diff --git a/docs/html/genindex.html b/docs/html/genindex.html
index 47c1fa4..e487ff4 100644
--- a/docs/html/genindex.html
+++ b/docs/html/genindex.html
@@ -8,7 +8,7 @@
- Index — acsuite 5.1.0 documentation
+ Index — acsuite 5.2.0 documentation
@@ -59,7 +59,7 @@
- 5.1.0
+ 5.2.0
diff --git a/docs/html/index.html b/docs/html/index.html
index 240f785..2533a42 100644
--- a/docs/html/index.html
+++ b/docs/html/index.html
@@ -8,7 +8,7 @@
- acsuite documentation — acsuite 5.1.0 documentation
+ acsuite documentation — acsuite 5.2.0 documentation
@@ -59,7 +59,7 @@
- 5.1.0
+ 5.2.0
@@ -157,7 +157,7 @@ acsuite documentationFrame-based cutting/trimming/splicing of audio with VapourSynth and FFmpeg.
-
-
acsuite.
eztrim
(clip, trims, audio_file, outfile=None, *, ffmpeg_path=None, quiet=False, debug=False)[source]¶
+acsuite.
eztrim
(clip, trims, audio_file, outfile=None, *, ffmpeg_path=None, quiet=False, timecodes_file=None, debug=False)[source]¶
Simple trimming function that follows VapourSynth/Python slicing syntax.
End frame is NOT inclusive.
For a 100 frame long VapourSynth clip:
@@ -202,6 +202,8 @@ acsuite documentationffmpeg_path (Union
[bytes
, PathLike
, Path
, str
, None
]) – Set this if ffmpeg
is not in your PATH.
If ffmpeg
exists in your PATH, it will automatically be detected and used.
quiet (bool
) – Suppresses most console output from FFmpeg
+timecodes_file (Union
[bytes
, PathLike
, Path
, str
, None
]) – Timecodes v2 file (generated by vspipe, ffms2, etc.) for variable-frame-rate clips.
+Not needed for CFR clips.
debug (bool
) – Used for testing purposes
diff --git a/docs/html/objects.inv b/docs/html/objects.inv
index ef22073..c37a9de 100644
Binary files a/docs/html/objects.inv and b/docs/html/objects.inv differ
diff --git a/docs/html/py-modindex.html b/docs/html/py-modindex.html
index 639a519..dd54fd3 100644
--- a/docs/html/py-modindex.html
+++ b/docs/html/py-modindex.html
@@ -8,7 +8,7 @@
- Python Module Index — acsuite 5.1.0 documentation
+ Python Module Index — acsuite 5.2.0 documentation
@@ -66,7 +66,7 @@
- 5.1.0
+ 5.2.0
diff --git a/docs/html/search.html b/docs/html/search.html
index 8ec4a9c..ac09686 100644
--- a/docs/html/search.html
+++ b/docs/html/search.html
@@ -8,7 +8,7 @@
- Search — acsuite 5.1.0 documentation
+ Search — acsuite 5.2.0 documentation
@@ -60,7 +60,7 @@
- 5.1.0
+ 5.2.0
diff --git a/docs/html/searchindex.js b/docs/html/searchindex.js
index bf71f54..76c3f11 100644
--- a/docs/html/searchindex.js
+++ b/docs/html/searchindex.js
@@ -1 +1 @@
-Search.setIndex({docnames:["index"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["index.rst"],objects:{"":{acsuite:[0,0,0,"-"]},acsuite:{eztrim:[0,1,1,""]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:function"},terms:{"byte":0,"default":0,"function":0,"int":0,"long":0,"return":0,"true":[],For:0,NOT:0,The:0,These:0,Used:0,_cut:[],abl:[],almost:0,also:[],attemp:[],audio:0,audio_fil:0,audio_file_cut:0,automat:0,base:0,bdmv:[],blank:0,bool:0,can:0,clip:0,codec:[],consol:0,contain:[],core:0,cut:0,debug:0,detect:0,determin:0,dict:0,dictionari:[],directli:0,directoi:[],either:0,empti:0,encod:0,end:0,enter:0,execut:[],exist:0,ext:0,extens:0,eztrim:0,fals:0,ffmpeg:0,ffmpeg_path:0,ffms2:0,file:0,filenam:0,flac:[],follow:0,found:[],frame:0,framer:0,from:0,full:0,given:0,inclus:0,index:0,input:0,insert:0,instead:[],left:0,legaci:0,like:0,list:0,locat:0,losslessli:0,mastroka:[],mka:[],mkv:0,mkvmerg:[],mkvmerge_path:[],mkvtoolnix:[],most:0,must:0,need:0,neg:0,none:0,normal:0,num_fram:0,object:0,one:0,onli:[],option:0,otherwis:[],out:0,outfil:0,output:0,overwritten:0,page:[],paramet:0,path:0,pathlik:0,pcm:[],place:0,portabl:[],purpos:0,python:0,quiet:0,reason:0,recogn:0,recommend:0,refer:0,remux:[],repres:0,script:[],search:[],set:0,simpl:0,simpli:[],singl:0,skip:[],slice:0,sourc:0,specifi:[],splice:0,src:0,str:0,string:0,suppress:0,syntax:0,test:0,thi:0,timecod:0,track:[],trim:0,tupl:0,type:0,union:0,use:[],used:0,uses:[],valid:0,valu:[],vapoursynth:0,videonod:0,want:[],wav:0,write:[],you:0,your:0},titles:["acsuite documentation"],titleterms:{acsuit:0,document:0,footer:[]}})
\ No newline at end of file
+Search.setIndex({docnames:["index"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["index.rst"],objects:{"":{acsuite:[0,0,0,"-"]},acsuite:{eztrim:[0,1,1,""]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:function"},terms:{"byte":0,"default":0,"function":0,"int":0,"long":0,"return":0,"true":[],For:0,NOT:0,Not:0,The:0,These:0,Used:0,_cut:[],abl:[],almost:0,also:[],attemp:[],audio:0,audio_fil:0,audio_file_cut:0,automat:0,base:0,bdmv:[],blank:0,bool:0,can:0,cfr:0,clip:0,codec:[],consol:0,contain:[],core:0,cut:0,debug:0,detect:0,determin:0,dict:0,dictionari:[],directli:0,directoi:[],either:0,empti:0,encod:0,end:0,enter:0,etc:0,execut:[],exist:0,ext:0,extens:0,eztrim:0,fals:0,ffmpeg:0,ffmpeg_path:0,ffms2:0,file:0,filenam:0,flac:[],follow:0,found:[],frame:0,framer:0,from:0,full:0,gener:0,given:0,inclus:0,index:0,input:0,insert:0,instead:[],left:0,legaci:0,like:0,list:0,locat:0,losslessli:0,mastroka:[],mka:[],mkv:0,mkvmerg:[],mkvmerge_path:[],mkvtoolnix:[],most:0,must:0,need:0,neg:0,none:0,normal:0,num_fram:0,object:0,one:0,onli:[],option:0,otherwis:[],out:0,outfil:0,output:0,overwritten:0,page:[],paramet:0,path:0,pathlik:0,pcm:[],place:0,portabl:[],purpos:0,python:0,quiet:0,rate:0,reason:0,recogn:0,recommend:0,refer:0,remux:[],repres:0,script:[],search:[],set:0,simpl:0,simpli:[],singl:0,skip:[],slice:0,sourc:0,specifi:[],splice:0,src:0,str:0,string:0,suppress:0,syntax:0,test:0,thi:0,timecod:0,timecodes_fil:0,track:[],trim:0,tupl:0,type:0,union:0,use:[],used:0,uses:[],valid:0,valu:[],vapoursynth:0,variabl:0,videonod:0,vspipe:0,want:[],wav:0,write:[],you:0,your:0},titles:["acsuite documentation"],titleterms:{acsuit:0,document:0,footer:[]}})
\ No newline at end of file