tictacsync 0.96a0__tar.gz → 0.97a0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tictacsync might be problematic. Click here for more details.
- {tictacsync-0.96a0/tictacsync.egg-info → tictacsync-0.97a0}/PKG-INFO +7 -4
- {tictacsync-0.96a0 → tictacsync-0.97a0}/README.md +6 -3
- {tictacsync-0.96a0 → tictacsync-0.97a0}/setup.py +1 -1
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync/device_scanner.py +10 -10
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync/entry.py +15 -15
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync/multi2polywav.py +2 -2
- tictacsync-0.97a0/tictacsync/remrgmx.py +38 -0
- {tictacsync-0.96a0 → tictacsync-0.97a0/tictacsync.egg-info}/PKG-INFO +7 -4
- tictacsync-0.96a0/tictacsync/remrgmx.py +0 -28
- {tictacsync-0.96a0 → tictacsync-0.97a0}/LICENSE +0 -0
- {tictacsync-0.96a0 → tictacsync-0.97a0}/setup.cfg +0 -0
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync/__init__.py +0 -0
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync/remergemix.py +0 -0
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync/timeline.py +0 -0
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync/yaltc.py +0 -0
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync.egg-info/SOURCES.txt +0 -0
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync.egg-info/dependency_links.txt +0 -0
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync.egg-info/entry_points.txt +0 -0
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync.egg-info/not-zip-safe +0 -0
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync.egg-info/requires.txt +0 -0
- {tictacsync-0.96a0 → tictacsync-0.97a0}/tictacsync.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tictacsync
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.97a0
|
|
4
4
|
Summary: command for syncing audio video recordings
|
|
5
5
|
Home-page: https://tictacsync.org/
|
|
6
6
|
Author: Raymond Lutz
|
|
@@ -73,19 +73,22 @@ The program `tictacsync` will recursively scan the directory given as argument,
|
|
|
73
73
|
If shooting multicam, put clips in their respective directories (using the camera name as folder name) _and_ the audio under their own directory. `tictacsync` will detect that structured input and will generate multicam folders ready to be imported into your NLE (for now only DaVinci Resolve has been validated).
|
|
74
74
|
|
|
75
75
|
## Options
|
|
76
|
+
#### `-v`
|
|
76
77
|
|
|
77
78
|
For a very verbose output add the `-v` flag:
|
|
78
79
|
|
|
79
80
|
> tictacsync -v dailies/loose/MVI_0024.MP4
|
|
80
|
-
|
|
81
|
+
#### `--terse`
|
|
81
82
|
For a one line output (or to suppress the progress bars) use the `--terse` flag:
|
|
82
83
|
|
|
83
84
|
> tictacsync --terse dailies/loose/MVI_0024.MP4
|
|
84
85
|
dailies/loose/MVI_0024.MP4 UTC:2024-03-12 23:07:01.4281 pulse: 27450 in chan 0
|
|
86
|
+
#### `--isos`
|
|
85
87
|
|
|
86
|
-
|
|
88
|
+
Specifying `--isos` produces _synced_ ISO audio files: for each synced \<video-clip\> a directory named `<video-clip>_ISO` will contain a set of ISO audio files each of exact same length, padded or trimmed to coincide with the video start. After re-editing and re-mixing in your DAW of choice a `remergemix` command will resync the new audio with the video and _the new sound track will be updated on your NLE timeline_, _automagically_ on some NLEs or on command for [Davinci Resolve](https://www.niwa.nu/dr-scripts/).
|
|
87
89
|
|
|
88
|
-
> tictacsync --isos dailies/
|
|
90
|
+
> tictacsync --isos dailies/day01
|
|
91
|
+
#### `-p`
|
|
89
92
|
|
|
90
93
|
When called with the `-p` flag, zoomable plots will be produced for diagnostic purpose (close the plotting window for the 2nd one) and the decoded starting time will be output to stdin:
|
|
91
94
|
|
|
@@ -50,19 +50,22 @@ The program `tictacsync` will recursively scan the directory given as argument,
|
|
|
50
50
|
If shooting multicam, put clips in their respective directories (using the camera name as folder name) _and_ the audio under their own directory. `tictacsync` will detect that structured input and will generate multicam folders ready to be imported into your NLE (for now only DaVinci Resolve has been validated).
|
|
51
51
|
|
|
52
52
|
## Options
|
|
53
|
+
#### `-v`
|
|
53
54
|
|
|
54
55
|
For a very verbose output add the `-v` flag:
|
|
55
56
|
|
|
56
57
|
> tictacsync -v dailies/loose/MVI_0024.MP4
|
|
57
|
-
|
|
58
|
+
#### `--terse`
|
|
58
59
|
For a one line output (or to suppress the progress bars) use the `--terse` flag:
|
|
59
60
|
|
|
60
61
|
> tictacsync --terse dailies/loose/MVI_0024.MP4
|
|
61
62
|
dailies/loose/MVI_0024.MP4 UTC:2024-03-12 23:07:01.4281 pulse: 27450 in chan 0
|
|
63
|
+
#### `--isos`
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
Specifying `--isos` produces _synced_ ISO audio files: for each synced \<video-clip\> a directory named `<video-clip>_ISO` will contain a set of ISO audio files each of exact same length, padded or trimmed to coincide with the video start. After re-editing and re-mixing in your DAW of choice a `remergemix` command will resync the new audio with the video and _the new sound track will be updated on your NLE timeline_, _automagically_ on some NLEs or on command for [Davinci Resolve](https://www.niwa.nu/dr-scripts/).
|
|
64
66
|
|
|
65
|
-
> tictacsync --isos dailies/
|
|
67
|
+
> tictacsync --isos dailies/day01
|
|
68
|
+
#### `-p`
|
|
66
69
|
|
|
67
70
|
When called with the `-p` flag, zoomable plots will be produced for diagnostic purpose (close the plotting window for the 2nd one) and the decoded starting time will be output to stdin:
|
|
68
71
|
|
|
@@ -32,7 +32,7 @@ setup(
|
|
|
32
32
|
'multi2polywav = tictacsync.multi2polywav:main',
|
|
33
33
|
]
|
|
34
34
|
},
|
|
35
|
-
version = '0.
|
|
35
|
+
version = '0.97a',
|
|
36
36
|
description = "command for syncing audio video recordings",
|
|
37
37
|
long_description_content_type='text/markdown',
|
|
38
38
|
long_description = long_descr,
|
|
@@ -110,7 +110,7 @@ def media_at_path(input_structure, p):
|
|
|
110
110
|
if stream['codec_type']=='audio'
|
|
111
111
|
]
|
|
112
112
|
if len(audio_streams) > 1:
|
|
113
|
-
print('
|
|
113
|
+
print('\nfor [gold1]%s[/gold1], ffprobe gave multiple audio streams, quitting.'%p)
|
|
114
114
|
quit()
|
|
115
115
|
# raise Exception('ffprobe gave multiple audio streams?')
|
|
116
116
|
if len(audio_streams) == 0:
|
|
@@ -158,10 +158,10 @@ def get_device_ffprobe_UID(file):
|
|
|
158
158
|
video_streams = [st for st in streams if st['codec_type'] == 'video']
|
|
159
159
|
audio_streams = [st for st in streams if st['codec_type'] == 'audio']
|
|
160
160
|
if len(video_streams) > 1:
|
|
161
|
-
print('
|
|
161
|
+
print('\nmore than one video stream for %s... quitting'%file)
|
|
162
162
|
quit()
|
|
163
163
|
if len(audio_streams) != 1:
|
|
164
|
-
print('
|
|
164
|
+
print('\nnbr of audio stream for %s not 1 ... quitting'%file)
|
|
165
165
|
quit()
|
|
166
166
|
codecs = [stream['codec_type'] for stream in streams]
|
|
167
167
|
# cameras have two streams: video AND audio
|
|
@@ -375,7 +375,7 @@ class Scanner:
|
|
|
375
375
|
sys.exit(1)
|
|
376
376
|
err_msg = tracks.error_msg
|
|
377
377
|
if err_msg != None:
|
|
378
|
-
print('
|
|
378
|
+
print('\nError, quitting: in file %s, %s'%(tracks_file, err_msg))
|
|
379
379
|
raise Exception
|
|
380
380
|
else:
|
|
381
381
|
logger.debug('tracks object%s'%tracks)
|
|
@@ -584,7 +584,7 @@ class Scanner:
|
|
|
584
584
|
LR_OKs = [LR_OK(p) for p in pair_idx_start]
|
|
585
585
|
logger.debug('LR_OKs %s'%LR_OKs)
|
|
586
586
|
if not all(LR_OKs):
|
|
587
|
-
print('
|
|
587
|
+
print('\nError in %s'%tracks_file)
|
|
588
588
|
print('Some tracks are paired but not L and R: %s'%rawtrx)
|
|
589
589
|
print('quitting...')
|
|
590
590
|
quit()
|
|
@@ -597,12 +597,12 @@ class Scanner:
|
|
|
597
597
|
n_tc_token = sum([t == 'tc' for t in singles_tag])
|
|
598
598
|
logger.debug('n tc tags %s'%n_tc_token)
|
|
599
599
|
if n_tc_token == 0:
|
|
600
|
-
print('
|
|
600
|
+
print('\nError in %s'%tracks_file)
|
|
601
601
|
print('with %s'%rawtrx)
|
|
602
602
|
print('no TC track found, quitting...')
|
|
603
603
|
quit()
|
|
604
604
|
if n_tc_token > 1:
|
|
605
|
-
print('
|
|
605
|
+
print('\nError in %s'%tracks_file)
|
|
606
606
|
print('with %s'%rawtrx)
|
|
607
607
|
print('more than one TC track, quitting...')
|
|
608
608
|
quit()
|
|
@@ -632,7 +632,7 @@ class Scanner:
|
|
|
632
632
|
# sequence is Lmix Rmix
|
|
633
633
|
return i_first+1, i_2nd+1
|
|
634
634
|
else:
|
|
635
|
-
print('
|
|
635
|
+
print('\nError in %s'%tracks_file)
|
|
636
636
|
print('with %s'%rawtrx)
|
|
637
637
|
print('can not find stereo mix')
|
|
638
638
|
quit()
|
|
@@ -641,7 +641,7 @@ class Scanner:
|
|
|
641
641
|
# sequence is Rmix Lmix
|
|
642
642
|
return i_2nd+1, i_first+1
|
|
643
643
|
else:
|
|
644
|
-
print('
|
|
644
|
+
print('\nError in %s'%tracks_file)
|
|
645
645
|
print('with %s'%rawtrx)
|
|
646
646
|
print('can not find stereo mix')
|
|
647
647
|
quit()
|
|
@@ -656,7 +656,7 @@ class Scanner:
|
|
|
656
656
|
# consistency check
|
|
657
657
|
if output_tracks.mix != []:
|
|
658
658
|
# already found a mono mix above!
|
|
659
|
-
print('
|
|
659
|
+
print('\nError in %s'%tracks_file)
|
|
660
660
|
print('with %s'%rawtrx)
|
|
661
661
|
print('found a mono mix AND a stereo mix')
|
|
662
662
|
quit()
|
|
@@ -166,7 +166,7 @@ def main():
|
|
|
166
166
|
parser.add_argument('--isos',
|
|
167
167
|
action='store_true',
|
|
168
168
|
dest='write_ISOs',
|
|
169
|
-
help='
|
|
169
|
+
help='Cut ISO sound files')
|
|
170
170
|
parser.add_argument('--nosync',
|
|
171
171
|
action='store_true',
|
|
172
172
|
dest='nosync',
|
|
@@ -226,21 +226,21 @@ def main():
|
|
|
226
226
|
maxch = len(devices)
|
|
227
227
|
for i, d in enumerate(devices):
|
|
228
228
|
print('\t%i - %s'%(i+1, d.name))
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
# ref_device = list(devices)[choice - 1]
|
|
242
|
-
choice = 3
|
|
229
|
+
while True:
|
|
230
|
+
print('\nEnter your choice:', end='')
|
|
231
|
+
choice = input()
|
|
232
|
+
try:
|
|
233
|
+
choice = int(choice)
|
|
234
|
+
except:
|
|
235
|
+
print('Please use numeric digits.')
|
|
236
|
+
continue
|
|
237
|
+
if choice not in list(range(1, maxch + 1)):
|
|
238
|
+
print('Please enter a number in [1..%i]'%maxch)
|
|
239
|
+
continue
|
|
240
|
+
break
|
|
243
241
|
ref_device = list(devices)[choice - 1]
|
|
242
|
+
# ref_device = list(devices)[3 - 1]
|
|
243
|
+
print('When only audio recordings are present, ISOs files will be cut and written.')
|
|
244
244
|
if not args.terse:
|
|
245
245
|
if scanner.input_structure == 'folder_is_device':
|
|
246
246
|
print('\nDetected structured folders', end='')
|
|
@@ -66,14 +66,14 @@ def build_poly_name(multifiles):
|
|
|
66
66
|
s1 = str(multifiles[0].stem)
|
|
67
67
|
s2 = str(multifiles[1].stem)
|
|
68
68
|
if len(s1) != len(s2):
|
|
69
|
-
print('
|
|
69
|
+
print('\nCan not build compound name with %s.wav and %s.wav'%(s1,s2))
|
|
70
70
|
print('names lengths differ.')
|
|
71
71
|
print('In folder "%s", quitting.'%multifiles[0].parent)
|
|
72
72
|
sys.exit(1)
|
|
73
73
|
pairs = list(zip(s1, s2))
|
|
74
74
|
not_same = [a for a, b in pairs if a != b ]
|
|
75
75
|
if len(not_same) > 2:
|
|
76
|
-
print('
|
|
76
|
+
print('\nCan not build compound name with %s.wav and %s.wav'%(s1,s2))
|
|
77
77
|
print('names differ by more than two characters.')
|
|
78
78
|
print('In folder "%s", quitting.'%multifiles[0].parent)
|
|
79
79
|
sys.exit(1)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import os, itertools
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
video_extensions = \
|
|
5
|
+
"""webm mkv flv flv vob ogv ogg drc gif gifv mng avi mov
|
|
6
|
+
qt wmv yuv rm rmvb viv asf mp4 m4p m4v mpg mp2 mpeg mpe
|
|
7
|
+
mpv mpg mpeg m2v m4v svi 3gp 3g2 mxf roq nsv""".split() # from wikipedia
|
|
8
|
+
|
|
9
|
+
def is_video(f):
|
|
10
|
+
# True if name as video extension
|
|
11
|
+
name_ext = f.split('.')
|
|
12
|
+
if len(name_ext) != 2:
|
|
13
|
+
return False
|
|
14
|
+
name, ext = name_ext
|
|
15
|
+
return ext.lower() in video_extensions
|
|
16
|
+
|
|
17
|
+
def find_ISO_vids_pairs(top):
|
|
18
|
+
# top is
|
|
19
|
+
vids = []
|
|
20
|
+
ISOs = []
|
|
21
|
+
for (root,dirs,files) in os.walk(top, topdown=True):
|
|
22
|
+
for d in dirs:
|
|
23
|
+
if d[-4:] == '_ISO':
|
|
24
|
+
ISOs.append(Path(root)/d)
|
|
25
|
+
for f in files:
|
|
26
|
+
if is_video(f):
|
|
27
|
+
vids.append(Path(root)/f)
|
|
28
|
+
matches = []
|
|
29
|
+
for pair in list(itertools.product(vids, ISOs)):
|
|
30
|
+
# print(pair)
|
|
31
|
+
vid, ISO = pair
|
|
32
|
+
vidname, ext = vid.name.split('.')
|
|
33
|
+
if vidname == ISO.name[:-4]:
|
|
34
|
+
matches.append(pair)
|
|
35
|
+
# print(vidname, ISO.name[:-4])
|
|
36
|
+
return matches
|
|
37
|
+
|
|
38
|
+
[print( vid, ISO) for vid, ISO in find_ISO_vids_pairs('.')]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tictacsync
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.97a0
|
|
4
4
|
Summary: command for syncing audio video recordings
|
|
5
5
|
Home-page: https://tictacsync.org/
|
|
6
6
|
Author: Raymond Lutz
|
|
@@ -73,19 +73,22 @@ The program `tictacsync` will recursively scan the directory given as argument,
|
|
|
73
73
|
If shooting multicam, put clips in their respective directories (using the camera name as folder name) _and_ the audio under their own directory. `tictacsync` will detect that structured input and will generate multicam folders ready to be imported into your NLE (for now only DaVinci Resolve has been validated).
|
|
74
74
|
|
|
75
75
|
## Options
|
|
76
|
+
#### `-v`
|
|
76
77
|
|
|
77
78
|
For a very verbose output add the `-v` flag:
|
|
78
79
|
|
|
79
80
|
> tictacsync -v dailies/loose/MVI_0024.MP4
|
|
80
|
-
|
|
81
|
+
#### `--terse`
|
|
81
82
|
For a one line output (or to suppress the progress bars) use the `--terse` flag:
|
|
82
83
|
|
|
83
84
|
> tictacsync --terse dailies/loose/MVI_0024.MP4
|
|
84
85
|
dailies/loose/MVI_0024.MP4 UTC:2024-03-12 23:07:01.4281 pulse: 27450 in chan 0
|
|
86
|
+
#### `--isos`
|
|
85
87
|
|
|
86
|
-
|
|
88
|
+
Specifying `--isos` produces _synced_ ISO audio files: for each synced \<video-clip\> a directory named `<video-clip>_ISO` will contain a set of ISO audio files each of exact same length, padded or trimmed to coincide with the video start. After re-editing and re-mixing in your DAW of choice a `remergemix` command will resync the new audio with the video and _the new sound track will be updated on your NLE timeline_, _automagically_ on some NLEs or on command for [Davinci Resolve](https://www.niwa.nu/dr-scripts/).
|
|
87
89
|
|
|
88
|
-
> tictacsync --isos dailies/
|
|
90
|
+
> tictacsync --isos dailies/day01
|
|
91
|
+
#### `-p`
|
|
89
92
|
|
|
90
93
|
When called with the `-p` flag, zoomable plots will be produced for diagnostic purpose (close the plotting window for the 2nd one) and the decoded starting time will be output to stdin:
|
|
91
94
|
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
def is_video(f):
|
|
2
|
-
# True if name as video extension
|
|
3
|
-
name_ext = f.split('.')
|
|
4
|
-
if len(name_ext) != 2:
|
|
5
|
-
return False
|
|
6
|
-
name, ext = name_ext
|
|
7
|
-
return ext.lower() in video_extensions
|
|
8
|
-
|
|
9
|
-
# def find_ISO_vids_pairs(top):
|
|
10
|
-
# # top is
|
|
11
|
-
vids = []
|
|
12
|
-
ISOs = []
|
|
13
|
-
for (root,dirs,files) in os.walk(Path('.'), topdown=True):
|
|
14
|
-
for d in dirs:
|
|
15
|
-
if d[-4:] == '_ISO':
|
|
16
|
-
ISOs.append(Path(root)/d)
|
|
17
|
-
for f in files:
|
|
18
|
-
if is_video(f):
|
|
19
|
-
vids.append(Path(root)/f)
|
|
20
|
-
for pair in list(itertools.product(vids, ISOs)):
|
|
21
|
-
# print(pair)
|
|
22
|
-
matches = []
|
|
23
|
-
vid, ISO = pair
|
|
24
|
-
vidname, ext = vid.name.split('.')
|
|
25
|
-
if vidname == ISO.name[:-4]:
|
|
26
|
-
matches.append(pair)
|
|
27
|
-
# print(vidname, ISO.name[:-4])
|
|
28
|
-
# return matches
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|