diff --git a/docs/conf.py b/docs/conf.py index 8360e7b..7004603 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ author = 'Dave ' # The full version, including alpha/beta/rc tags -version = release = '5.0.0' +version = release = '5.0.1' # -- General configuration --------------------------------------------------- diff --git a/docs/html/.buildinfo b/docs/html/.buildinfo index ce62632..6ea88c2 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: 093fab84becb6081857e479a12643e80 +config: c487bba78c1919333c9d086c4c451323 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/html/_modules/acsuite.html b/docs/html/_modules/acsuite.html index b277141..1d00ca6 100644 --- a/docs/html/_modules/acsuite.html +++ b/docs/html/_modules/acsuite.html @@ -8,7 +8,7 @@ - acsuite — acsuite 5.0.0 documentation + acsuite — acsuite 5.0.1 documentation @@ -59,7 +59,7 @@
- 5.0.0 + 5.0.1
@@ -146,18 +146,17 @@

Source code for acsuite

-"""Frame-based cutting/trimming/splicing of audio with VapourSynth."""
+"""Frame-based cutting/trimming/splicing of audio with VapourSynth and FFmpeg."""
 __all__ = ['eztrim']
 __author__ = 'Dave <orangechannel@pm.me>'
-__date__ = '26 July 2020'
+__date__ = '29 July 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
 """
-__version__ = '5.0.0'
+__version__ = '5.0.1'
 
 import fractions
-import mimetypes
 import os
 import pathlib
 import subprocess
@@ -213,6 +212,8 @@ 

Source code for acsuite

             ``src[15]`` must be entered as ``trims=(15, 16)``.
     :param audio_file:    A string or path-like object refering to the source audio file's location
                           (i.e. '/path/to/audio_file.ext').
+                          If the extension is not recognized as a valid audio file extension for FFmpeg's encoders,
+                          the audio will be re-encoded to WAV losslessly.
     :param outfile:       Either a filename 'out.ext' or a full path '/path/to/out.ext'
                           that will be used for the trimmed audio file.
                           The extension will be automatically inserted for you,
@@ -230,17 +231,41 @@ 

Source code for acsuite

     else:
         if not os.path.isfile(audio_file):
             raise FileNotFoundError(f"eztrim: {audio_file} not found")
-        if not mimetypes.types_map[os.path.splitext(audio_file)[-1]].startswith('audio/'):
-            raise ValueError(f"{audio_file} does not seem to be an audio file; "
-                             f"try to extract the audio track first if it is in a container")
+
+        audio_file_name, audio_file_ext = os.path.splitext(audio_file)
+        ffmpeg_valid_encoder_extensions = {
+            '.aac', '.m4a', '.adts',
+            '.ac3',
+            '.alac', '.caf',
+            '.dca', '.dts',
+            '.eac3',
+            '.flac',
+            '.gsm',
+            '.mlp',
+            '.mp2', '.mp3', '.mpga',
+            '.opus', '.spx', '.ogg', '.oga'
+            '.pcm', '.raw',
+            '.sbc',
+            '.thd',
+            '.tta',
+            '.wav',
+            '.wma'
+        }
+        if audio_file_ext not in ffmpeg_valid_encoder_extensions:
+            warn(f"{audio_file_ext} is not a supported extension by FFmpeg's audio encoders, re-encoding to WAV", Warning)
+            audio_file_ext = '.wav'
+            codec_args = ['-c:a', 'copy']
+        else:
+            codec_args = []
 
         if outfile is None:
-            outfile = os.path.splitext(audio_file)[0] + '_cut' + os.path.splitext(audio_file)[-1]
+            outfile = audio_file_name + '_cut' + audio_file_ext
         elif not os.path.splitext(outfile)[1]:
-            outfile += os.path.splitext(audio_file)[-1]
-        elif os.path.splitext(audio_file)[-1] != os.path.splitext(outfile)[-1]:
-            outfile = os.path.splitext(outfile)[0] + os.path.splitext(audio_file)[-1]
-        elif os.path.isfile(outfile):
+            outfile += audio_file_ext
+        elif os.path.splitext(outfile)[-1] != audio_file_ext:
+            outfile = os.path.splitext(outfile)[0] + audio_file_ext
+
+        if os.path.isfile(outfile):
             raise FileExistsError(f"eztrim: {outfile} already exists")
 
         if ffmpeg_path is None:
@@ -251,7 +276,7 @@ 

Source code for acsuite

             try:
                 args = ['ffmpeg', '-version']
                 if subprocess.run(args, stdout=subprocess.PIPE, text=True).stdout.split()[0] != 'ffmpeg':
-                    raise FileNotFoundError("ffmpeg executable not working properly")
+                    raise ValueError("ffmpeg executable not working properly")
             except FileNotFoundError:
                 raise FileNotFoundError("ffmpeg executable not found in PATH") from None
 
@@ -304,28 +329,28 @@ 

Source code for acsuite

     ffmpeg_silence = [str(ffmpeg_path), '-hide_banner', '-loglevel', '16'] if quiet else [str(ffmpeg_path), '-hide_banner']
 
     if len(cut_ts_s) == 1:
-        args = ffmpeg_silence + ['-i', audio_file, '-vn', '-ss', cut_ts_s[0], '-to', cut_ts_e[0], '-c:a', 'copy', outfile]
+        args = ffmpeg_silence + ['-i', audio_file, '-vn', '-ss', cut_ts_s[0], '-to', cut_ts_e[0]] + codec_args + [outfile]
         run(args)
         return
 
     times = [[s, e] for s, e in zip(cut_ts_s, cut_ts_e)]
-    if os.path.isfile('_temp_concat.txt'):
-        raise ValueError("_temp_concat.txt already exists, quitting")
+    if os.path.isfile('_acsuite_temp_concat.txt'):
+        raise ValueError("_acsuite_temp_concat.txt already exists, quitting")
     else:
-        concat_file = open('_temp_concat.txt', 'w')
+        concat_file = open('_acsuite_temp_concat.txt', 'w')
         temp_filelist = []
     for key, time in enumerate(times):
-        outfile_tmp = f'_temp_output_{key}' + os.path.splitext(outfile)[-1]
+        outfile_tmp = f'_acsuite_temp_output_{key}' + os.path.splitext(outfile)[-1]
         concat_file.write(f"file {outfile_tmp}\n")
         temp_filelist.append(outfile_tmp)
-        args = ffmpeg_silence + ['-i', audio_file, '-vn', '-ss', time[0], '-to', time[1], '-c:a', 'copy', outfile_tmp]
+        args = ffmpeg_silence + ['-i', audio_file, '-vn', '-ss', time[0], '-to', time[1]] + codec_args + [outfile_tmp]
         run(args)
 
     concat_file.close()
-    args = ffmpeg_silence + ['-f', 'concat', '-i', '_temp_concat.txt', '-c', 'copy', outfile]
+    args = ffmpeg_silence + ['-f', 'concat', '-i', '_acsuite_temp_concat.txt', '-c', 'copy', outfile]
     run(args)
 
-    os.remove('_temp_concat.txt')
+    os.remove('_acsuite_temp_concat.txt')
     for file in temp_filelist:
         os.remove(file)
diff --git a/docs/html/_modules/index.html b/docs/html/_modules/index.html index 5139103..5749a52 100644 --- a/docs/html/_modules/index.html +++ b/docs/html/_modules/index.html @@ -8,7 +8,7 @@ - Overview: module code — acsuite 5.0.0 documentation + Overview: module code — acsuite 5.0.1 documentation @@ -59,7 +59,7 @@
- 5.0.0 + 5.0.1
diff --git a/docs/html/_static/documentation_options.js b/docs/html/_static/documentation_options.js index 859f161..1bfdbf0 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.0.0', + VERSION: '5.0.1', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/docs/html/genindex.html b/docs/html/genindex.html index f8b43ec..dc49500 100644 --- a/docs/html/genindex.html +++ b/docs/html/genindex.html @@ -8,7 +8,7 @@ - Index — acsuite 5.0.0 documentation + Index — acsuite 5.0.1 documentation @@ -59,7 +59,7 @@
- 5.0.0 + 5.0.1
diff --git a/docs/html/index.html b/docs/html/index.html index cfad7d1..4917e31 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -8,7 +8,7 @@ - acsuite documentation — acsuite 5.0.0 documentation + acsuite documentation — acsuite 5.0.1 documentation @@ -59,7 +59,7 @@
- 5.0.0 + 5.0.1
@@ -154,7 +154,7 @@

acsuite documentation

-

Frame-based cutting/trimming/splicing of audio with VapourSynth.

+

Frame-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]
@@ -191,7 +191,9 @@

acsuite documentation

  • audio_file (Union[bytes, PathLike, Path, str]) – A string or path-like object refering to the source audio file’s location -(i.e. ‘/path/to/audio_file.ext’).

  • +(i.e. ‘/path/to/audio_file.ext’). +If the extension is not recognized as a valid audio file extension for FFmpeg’s encoders, +the audio will be re-encoded to WAV losslessly.

  • outfile (Union[bytes, PathLike, Path, str, None]) – Either a filename ‘out.ext’ or a full path ‘/path/to/out.ext’ that will be used for the trimmed audio file. The extension will be automatically inserted for you, diff --git a/docs/html/objects.inv b/docs/html/objects.inv index 0c6c7cb..21827a3 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 64abb38..b04f22a 100644 --- a/docs/html/py-modindex.html +++ b/docs/html/py-modindex.html @@ -8,7 +8,7 @@ - Python Module Index — acsuite 5.0.0 documentation + Python Module Index — acsuite 5.0.1 documentation @@ -66,7 +66,7 @@

    - 5.0.0 + 5.0.1
    diff --git a/docs/html/search.html b/docs/html/search.html index 32406fe..6888726 100644 --- a/docs/html/search.html +++ b/docs/html/search.html @@ -8,7 +8,7 @@ - Search — acsuite 5.0.0 documentation + Search — acsuite 5.0.1 documentation @@ -60,7 +60,7 @@
    - 5.0.0 + 5.0.1
    diff --git a/docs/html/searchindex.js b/docs/html/searchindex.js index 9b376d8..bf71f54 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,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,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,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:[],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,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