tictacsync 0.82a0__py3-none-any.whl → 0.95a0__py3-none-any.whl
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.
- tictacsync/device_scanner.py +64 -32
- tictacsync/entry.py +111 -69
- tictacsync/multi2polywav.py +1 -1
- tictacsync/timeline.py +123 -77
- tictacsync/yaltc.py +139 -152
- {tictacsync-0.82a0.dist-info → tictacsync-0.95a0.dist-info}/METADATA +1 -1
- tictacsync-0.95a0.dist-info/RECORD +15 -0
- tictacsync-0.82a0.dist-info/RECORD +0 -15
- {tictacsync-0.82a0.dist-info → tictacsync-0.95a0.dist-info}/LICENSE +0 -0
- {tictacsync-0.82a0.dist-info → tictacsync-0.95a0.dist-info}/WHEEL +0 -0
- {tictacsync-0.82a0.dist-info → tictacsync-0.95a0.dist-info}/entry_points.txt +0 -0
- {tictacsync-0.82a0.dist-info → tictacsync-0.95a0.dist-info}/top_level.txt +0 -0
tictacsync/device_scanner.py
CHANGED
|
@@ -69,6 +69,7 @@ class Tracks:
|
|
|
69
69
|
others: list #of all other tags: (tag, track#) tuples
|
|
70
70
|
rawtrx: list # list of strings read from file
|
|
71
71
|
error_msg: str # 'None' if none
|
|
72
|
+
lag_values: list # list of lag in ms, entry is None if not specified.
|
|
72
73
|
|
|
73
74
|
@dataclass
|
|
74
75
|
class Device:
|
|
@@ -109,7 +110,13 @@ def media_at_path(input_structure, p):
|
|
|
109
110
|
if stream['codec_type']=='audio'
|
|
110
111
|
]
|
|
111
112
|
if len(audio_streams) > 1:
|
|
112
|
-
|
|
113
|
+
print('for [gold1]%s[/gold1], ffprobe gave multiple audio streams, quitting.'%p)
|
|
114
|
+
quit()
|
|
115
|
+
# raise Exception('ffprobe gave multiple audio streams?')
|
|
116
|
+
if len(audio_streams) == 0:
|
|
117
|
+
print('ffprobe gave no audio stream for [gold1]%s[/gold1], quitting.'%p)
|
|
118
|
+
quit()
|
|
119
|
+
# raise Exception('ffprobe gave no audio stream for %s, quitting'%p)
|
|
113
120
|
audio_str = audio_streams[0]
|
|
114
121
|
n = audio_str['channels']
|
|
115
122
|
# pprint(ffmpeg.probe(p))
|
|
@@ -146,6 +153,7 @@ def get_device_ffprobe_UID(file):
|
|
|
146
153
|
print(e.stderr, file)
|
|
147
154
|
return None, None #-----------------------------------------------------
|
|
148
155
|
# fall back to folder name
|
|
156
|
+
logger.debug('ffprobe %s'%probe)
|
|
149
157
|
streams = probe['streams']
|
|
150
158
|
codecs = [stream['codec_type'] for stream in streams]
|
|
151
159
|
device_type = 'CAM' if 'video' in codecs else 'REC'
|
|
@@ -155,6 +163,7 @@ def get_device_ffprobe_UID(file):
|
|
|
155
163
|
probe_lines = [l for l in probe_string.split('\n')
|
|
156
164
|
if '_time' not in l
|
|
157
165
|
and 'time_' not in l
|
|
166
|
+
and 'location' not in l
|
|
158
167
|
and 'date' not in l ]
|
|
159
168
|
# this removes any metadata related to the file
|
|
160
169
|
# but keeps metadata related to the device
|
|
@@ -302,12 +311,12 @@ class Scanner:
|
|
|
302
311
|
audio_devices = [d for d in devices if d.dev_type == 'REC']
|
|
303
312
|
for recorder in audio_devices:
|
|
304
313
|
recorder.tracks = self._get_tracks_from_file(recorder)
|
|
314
|
+
if recorder.tracks:
|
|
315
|
+
if not all([lv == None for lv in recorder.tracks.lag_values]):
|
|
316
|
+
logger.debug('%s has lag_values %s'%(
|
|
317
|
+
recorder.name, recorder.tracks.lag_values))
|
|
305
318
|
no_name_devices = [m.device for m in self.found_media_files
|
|
306
319
|
if not m.device.name]
|
|
307
|
-
# if no_name_devices:
|
|
308
|
-
# pprint_no_name = pformat([(d, self.get_media_for_device(d)) for d in no_name_devices])
|
|
309
|
-
# print('those are anon devices%s\n'%pprint_no_name)
|
|
310
|
-
# logger.debug('those media have anon device%s'%no_name_devices)
|
|
311
320
|
for anon_dev in no_name_devices:
|
|
312
321
|
medias = self.get_media_for_device(anon_dev)
|
|
313
322
|
guess_name = _try_name(medias)
|
|
@@ -321,7 +330,7 @@ class Scanner:
|
|
|
321
330
|
|
|
322
331
|
def _get_tracks_from_file(self, device) -> Tracks:
|
|
323
332
|
"""
|
|
324
|
-
Look for track names in TRACKSFN file,
|
|
333
|
+
Look for eventual track names in TRACKSFN file, stored inside the
|
|
325
334
|
recorder folder alongside the audio files. If there, returns a Tracks
|
|
326
335
|
object, if not returns None.
|
|
327
336
|
"""
|
|
@@ -477,14 +486,16 @@ class Scanner:
|
|
|
477
486
|
read track names for naming separated ISOs
|
|
478
487
|
from tracks_file.
|
|
479
488
|
|
|
489
|
+
tokens looked for: mix mixL mixR 0 ttc
|
|
490
|
+
|
|
480
491
|
repeting prefixes signals a stereo track
|
|
481
492
|
and entries will correspondingly panned into
|
|
482
493
|
a stero mix named mixL.wav and mixR.wav
|
|
483
494
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
495
|
+
xyz L # spaces are ignored |
|
|
496
|
+
zyz R | stereo pair
|
|
497
|
+
abc L
|
|
498
|
+
abc R
|
|
488
499
|
|
|
489
500
|
mixL
|
|
490
501
|
|
|
@@ -502,41 +513,56 @@ class Scanner:
|
|
|
502
513
|
ch = [c for c in chaine if c != ' ']
|
|
503
514
|
return ''.join(ch)
|
|
504
515
|
def _WO_LR(chaine):
|
|
505
|
-
ch = [c for c in chaine if c not in '
|
|
516
|
+
ch = [c for c in chaine if c not in 'LR']
|
|
506
517
|
return ''.join(ch)
|
|
507
518
|
def _seemsStereoMic(tag):
|
|
508
519
|
# is tag likely a stereo pair tag?
|
|
509
|
-
# should start with 'mic' and end with '
|
|
510
|
-
return tag[:3]=='mic' and tag[-1] in '
|
|
520
|
+
# should start with 'mic' and end with 'L' or 'R'
|
|
521
|
+
return tag[:3]=='mic' and tag[-1] in 'LR'
|
|
511
522
|
file=open(tracks_file,"r")
|
|
512
523
|
whole_txt = file.read()
|
|
513
524
|
logger.debug('all_lines:\n%s'%whole_txt)
|
|
514
|
-
tracks_lines = [l.split('#')[0] for l in whole_txt.splitlines()
|
|
515
|
-
|
|
525
|
+
tracks_lines = [l.split('#')[0] for l in whole_txt.splitlines()
|
|
526
|
+
if len(l) > 0 ]
|
|
527
|
+
tracks_lines = [_WOspace(l) for l in tracks_lines if len(l) > 0 ]
|
|
516
528
|
rawtrx = tracks_lines
|
|
529
|
+
# add index with tuples, starting at 1
|
|
530
|
+
logger.debug('tracks_lines whole: %s'%tracks_lines)
|
|
531
|
+
def _detach_lag_value(line):
|
|
532
|
+
# look for ";number" ending any line, returns a two-list
|
|
533
|
+
splt = line.split(';')
|
|
534
|
+
if len(splt) == 1:
|
|
535
|
+
splt += [None]
|
|
536
|
+
if len(splt) != 2:
|
|
537
|
+
# error
|
|
538
|
+
print('Text error in %s, line %s has too many ";"'%(
|
|
539
|
+
tracks_file, line))
|
|
540
|
+
return splt
|
|
541
|
+
tracks_lines, lag_values = zip(*[_detach_lag_value(l) for l
|
|
542
|
+
in tracks_lines])
|
|
543
|
+
logger.debug('tracks_lines WO lag: %s'%[tracks_lines])
|
|
544
|
+
logger.debug('lag_values: %s'%[lag_values])
|
|
517
545
|
tracks_lines = [(t,ix+1) for ix,t in enumerate(tracks_lines)]
|
|
518
|
-
# tracks_lines = [l for l in tracks_lines if l not in ['ttc', '0']]
|
|
519
|
-
# track_names = [l.split()[0] for l in tracks_lines if l != 'ttc']
|
|
520
|
-
logger.debug('tracks_lines: %s'%tracks_lines)
|
|
521
546
|
# first check for stereo mic pairs (could be more than one pair):
|
|
522
547
|
spairs = [e for e in tracks_lines if _seemsStereoMic(e[0])]
|
|
523
548
|
# spairs is stereo pairs candidates
|
|
524
549
|
msg = 'Confusing stereo pair tags: %s'%' '.join([e[0]
|
|
525
550
|
for e in spairs])
|
|
526
|
-
error_output_stereo = Tracks(None,[],[],[],[],[],msg)
|
|
551
|
+
error_output_stereo = Tracks(None,[],[],[],[],[],msg,[])
|
|
527
552
|
if len(spairs)%2 == 1: # not pairs?, quit.
|
|
528
553
|
return error_output_stereo
|
|
529
554
|
logger.debug('_seemsStereoM: %s'%spairs)
|
|
530
|
-
output_tracks = Tracks(None,[],[],[],[],rawtrx,None)
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
555
|
+
output_tracks = Tracks(None,[],[],[],[],rawtrx,None,[])
|
|
556
|
+
output_tracks.lag_values = lag_values
|
|
557
|
+
# def _LR(p):
|
|
558
|
+
# # p = (('mic1l', 1), ('mic1r', 2))
|
|
559
|
+
# # check if L then R
|
|
560
|
+
# p1, p2 = p
|
|
561
|
+
# return p1[0][-1] == 'l' and p2[0][-1] == 'r'
|
|
536
562
|
if spairs:
|
|
537
563
|
even_idxes = range(0,len(spairs),2)
|
|
538
564
|
paired = [(spairs[i], spairs[i+1]) for i in even_idxes]
|
|
539
|
-
# eg [(('
|
|
565
|
+
# eg [(('mic1L', 1), ('mic1R', 2)), (('mic2L', 3), ('mic2R', 4))]
|
|
540
566
|
def _mic_same(p):
|
|
541
567
|
# p = (('mic1l', 1), ('mic1r', 2))
|
|
542
568
|
# check if mic1 == mic1
|
|
@@ -546,16 +572,22 @@ class Scanner:
|
|
|
546
572
|
logger.debug('mic_prefix_OK: %s'%mic_prefix_OK)
|
|
547
573
|
if not mic_prefix_OK:
|
|
548
574
|
return error_output_stereo
|
|
549
|
-
mic_LR_OK = all([_LR(p) for p in paired])
|
|
550
|
-
logger.debug('mic_LR_OK %s'%mic_LR_OK)
|
|
551
|
-
if not mic_LR_OK:
|
|
552
|
-
|
|
575
|
+
# mic_LR_OK = all([_LR(p) for p in paired])
|
|
576
|
+
# logger.debug('mic_LR_OK %s'%mic_LR_OK)
|
|
577
|
+
# if not mic_LR_OK:
|
|
578
|
+
# return error_output_stereo
|
|
553
579
|
def _stereo_mic_pref_chan(p):
|
|
554
|
-
# p = (('
|
|
580
|
+
# p = (('mic1R', 1), ('mic1L', 2))
|
|
555
581
|
# returns ('mic1', (1,2))
|
|
556
582
|
first, second = p
|
|
557
583
|
mic_prefix = _WO_LR(first[0])
|
|
558
|
-
|
|
584
|
+
# check if first token last char
|
|
585
|
+
if p[0][0][-1] == 'L':
|
|
586
|
+
logger.debug('sequence %s is L+R'%[p])
|
|
587
|
+
return (mic_prefix, (first[1], second[1]) )
|
|
588
|
+
else:
|
|
589
|
+
logger.debug('sequence %s is R+L'%[p])
|
|
590
|
+
return (mic_prefix, (second[1], first[1]) )
|
|
559
591
|
grouped_stereo_mic_channels = [_stereo_mic_pref_chan(p) for p
|
|
560
592
|
in paired]
|
|
561
593
|
logger.debug('grouped_stereo_mic_channels: %s'%
|
tictacsync/entry.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
print('Loading modules...', end='')
|
|
2
2
|
|
|
3
3
|
# I know, the following is ugly, but I need those try's to
|
|
4
4
|
# run the command in my dev setting AND from
|
|
@@ -16,11 +16,11 @@ except:
|
|
|
16
16
|
import timeline
|
|
17
17
|
import multi2polywav
|
|
18
18
|
|
|
19
|
-
import argparse
|
|
19
|
+
import argparse, tempfile
|
|
20
20
|
from loguru import logger
|
|
21
21
|
from pathlib import Path
|
|
22
22
|
# import os, sys
|
|
23
|
-
import os, sys
|
|
23
|
+
import os, sys, sox
|
|
24
24
|
from rich.progress import track
|
|
25
25
|
# from pprint import pprint
|
|
26
26
|
from rich.console import Console
|
|
@@ -29,6 +29,8 @@ from rich.table import Table
|
|
|
29
29
|
from rich import print
|
|
30
30
|
from pprint import pprint
|
|
31
31
|
|
|
32
|
+
DEL_TEMP = False
|
|
33
|
+
|
|
32
34
|
av_file_extensions = \
|
|
33
35
|
"""MOV webm mkv flv flv vob ogv ogg drc gif gifv mng avi MTS M2TS TS mov qt
|
|
34
36
|
wmv yuv rm rmvb viv asf amv mp4 m4p m4v mpg mp2 mpeg mpe mpv mpg mpeg m2v
|
|
@@ -40,7 +42,7 @@ logger.level("DEBUG", color="<yellow>")
|
|
|
40
42
|
|
|
41
43
|
def process_files_with_progress_bars(medias):
|
|
42
44
|
recordings = []
|
|
43
|
-
|
|
45
|
+
rec_with_TTC = []
|
|
44
46
|
times = []
|
|
45
47
|
for m in track(medias,
|
|
46
48
|
description="1/4 Initializing Recordings:"):
|
|
@@ -49,29 +51,32 @@ def process_files_with_progress_bars(medias):
|
|
|
49
51
|
for r in track(recordings,
|
|
50
52
|
description="2/4 Looking for TicTacCode:"):
|
|
51
53
|
if r.seems_to_have_TicTacCode_at_beginning():
|
|
52
|
-
|
|
53
|
-
for r in track(
|
|
54
|
+
rec_with_TTC.append(r)
|
|
55
|
+
for r in track(rec_with_TTC,
|
|
54
56
|
description="3/4 Finding start times:"):
|
|
55
57
|
times.append(r.get_start_time())
|
|
56
|
-
return recordings,
|
|
58
|
+
return recordings, rec_with_TTC, times
|
|
57
59
|
|
|
58
60
|
def process_files(medias):
|
|
59
61
|
recordings = []
|
|
60
|
-
|
|
62
|
+
rec_with_TTC = []
|
|
61
63
|
times = []
|
|
62
64
|
for m in medias:
|
|
63
65
|
recordings.append(yaltc.Recording(m))
|
|
64
66
|
for r in recordings:
|
|
65
67
|
# print('%s duration %.2fs'%(r.AVpath.name, r.get_duration()))
|
|
66
68
|
if r.seems_to_have_TicTacCode_at_beginning():
|
|
67
|
-
|
|
68
|
-
for r in
|
|
69
|
+
rec_with_TTC.append(r)
|
|
70
|
+
for r in rec_with_TTC:
|
|
69
71
|
times.append(r.get_start_time())
|
|
70
|
-
return recordings,
|
|
72
|
+
return recordings, rec_with_TTC, times
|
|
71
73
|
|
|
72
74
|
def process_single(file, args):
|
|
73
75
|
# argument is a single file
|
|
74
76
|
m = device_scanner.media_at_path(None, Path(file))
|
|
77
|
+
if args.plotting:
|
|
78
|
+
print('\nPlots can be zoomed and panned...')
|
|
79
|
+
print('Close window for next one.')
|
|
75
80
|
a_rec = yaltc.Recording(m, do_plots=args.plotting)
|
|
76
81
|
time = a_rec.get_start_time()
|
|
77
82
|
# time = a_rec.get_start_time(plots=args.plotting)
|
|
@@ -94,43 +99,93 @@ def process_single(file, args):
|
|
|
94
99
|
print('Start time couldnt be determined')
|
|
95
100
|
sys.exit(1)
|
|
96
101
|
|
|
102
|
+
def process_lag_adjustement(media_object):
|
|
103
|
+
# trim channels that are lagging (as stated in tracks.txt)
|
|
104
|
+
# replace the old file, and rename the old one with .wavbk
|
|
105
|
+
# if .wavbk exist, process was done already, so dont process
|
|
106
|
+
# returns nothing
|
|
107
|
+
lags = media_object.device.tracks.lag_values
|
|
108
|
+
logger.debug('will process %s lags'%[lags])
|
|
109
|
+
channels = timeline._split_channels(media_object.path)
|
|
110
|
+
# add bk to file on filesystem, but media_object.path is unchanged (?)
|
|
111
|
+
backup_name = str(media_object.path) + 'bk'
|
|
112
|
+
if Path(backup_name).exists():
|
|
113
|
+
logger.debug('%s exists, so return now.'%backup_name)
|
|
114
|
+
return
|
|
115
|
+
media_object.path.replace(backup_name)
|
|
116
|
+
logger.debug('channels %s'%channels)
|
|
117
|
+
def _trim(lag, chan_file):
|
|
118
|
+
if lag == None:
|
|
119
|
+
return chan_file
|
|
120
|
+
else:
|
|
121
|
+
logger.debug('process %s for lag of %s'%(chan_file, lag))
|
|
122
|
+
sox_transform = sox.Transformer()
|
|
123
|
+
sox_transform.trim(float(lag)*1e-3)
|
|
124
|
+
output_fh = tempfile.NamedTemporaryFile(suffix='.wav', delete=DEL_TEMP)
|
|
125
|
+
out_file = timeline._pathname(output_fh)
|
|
126
|
+
input_file = timeline._pathname(chan_file)
|
|
127
|
+
logger.debug('sox in and out files: %s %s'%(input_file, out_file))
|
|
128
|
+
logger.debug('calling sox_transform.build()')
|
|
129
|
+
status = sox_transform.build(input_file, out_file, return_output=True )
|
|
130
|
+
logger.debug('sox.build exit code %s'%str(status))
|
|
131
|
+
return output_fh
|
|
132
|
+
new_channels = [_trim(*e) for e in zip(lags, channels)]
|
|
133
|
+
logger.debug('new_channels %s'%new_channels)
|
|
134
|
+
trimmed_multichanfile = timeline._sox_combine(new_channels)
|
|
135
|
+
logger.debug('trimmed_multichanfile %s'%timeline._pathname(trimmed_multichanfile))
|
|
136
|
+
Path(timeline._pathname(trimmed_multichanfile)).replace(media_object.path)
|
|
137
|
+
|
|
97
138
|
def main():
|
|
98
139
|
parser = argparse.ArgumentParser()
|
|
99
140
|
parser.add_argument(
|
|
100
|
-
"
|
|
141
|
+
"path",
|
|
101
142
|
type=str,
|
|
102
143
|
nargs=1,
|
|
103
|
-
help="
|
|
144
|
+
help="directory_name or media_file"
|
|
104
145
|
)
|
|
105
146
|
# parser.add_argument("directory", nargs="?", help="path of media directory")
|
|
106
147
|
# parser.add_argument('-v', action='store_true')
|
|
107
|
-
parser.add_argument('-v',
|
|
108
|
-
|
|
109
|
-
|
|
148
|
+
parser.add_argument('-v',
|
|
149
|
+
action='store_true', #ie default False
|
|
150
|
+
dest='verbose_output',
|
|
151
|
+
help='Set verbose ouput')
|
|
110
152
|
parser.add_argument('-o', nargs=1,
|
|
111
|
-
help='
|
|
112
|
-
parser.add_argument('-
|
|
153
|
+
help='Where to write the SyncedMedia folder [default to "path" ]')
|
|
154
|
+
parser.add_argument('-t','--timelineoffset',
|
|
155
|
+
nargs=1,
|
|
156
|
+
default=['00:00:00:00'],
|
|
157
|
+
dest='timelineoffset',
|
|
158
|
+
help='When processing multicam, where to place clips on NLE timeline (HH:MM:SS:FF)')
|
|
159
|
+
parser.add_argument('-p',
|
|
160
|
+
action='store_true',
|
|
113
161
|
dest='plotting',
|
|
114
|
-
help='
|
|
115
|
-
parser.add_argument('--isos',
|
|
162
|
+
help='Produce plots')
|
|
163
|
+
parser.add_argument('--isos',
|
|
164
|
+
action='store_true',
|
|
116
165
|
dest='write_ISOs',
|
|
117
166
|
help='Write ISO sound files')
|
|
118
|
-
parser.add_argument('--nosync',
|
|
167
|
+
parser.add_argument('--nosync',
|
|
168
|
+
action='store_true',
|
|
119
169
|
dest='nosync',
|
|
120
|
-
help='
|
|
121
|
-
parser.add_argument('--terse',
|
|
170
|
+
help='Just scan and decode')
|
|
171
|
+
parser.add_argument('--terse',
|
|
172
|
+
action='store_true',
|
|
122
173
|
dest='terse',
|
|
123
|
-
help='
|
|
174
|
+
help='Terse output')
|
|
124
175
|
args = parser.parse_args()
|
|
176
|
+
# print(args)
|
|
177
|
+
if len(args.timelineoffset) != 1:
|
|
178
|
+
print('--timelineoffset needs one value, got %s'%args.timelineoffset)
|
|
179
|
+
quit()
|
|
125
180
|
if args.verbose_output:
|
|
126
181
|
logger.add(sys.stderr, level="DEBUG")
|
|
127
182
|
# logger.add(sys.stdout, filter="__main__")
|
|
128
183
|
# logger.add(sys.stdout, filter="yaltc")
|
|
129
|
-
# logger.add(sys.stdout, filter=lambda r: r["function"] == "
|
|
130
|
-
# logger.add(sys.stdout, filter=lambda r: r["function"] == "
|
|
131
|
-
# logger.add(sys.stdout, filter=lambda r: r["function"] == "
|
|
132
|
-
# logger.add(sys.stdout, filter=lambda r: r["function"] == "
|
|
133
|
-
top_dir = args.
|
|
184
|
+
# logger.add(sys.stdout, filter=lambda r: r["function"] == "process_lag_adjustement")
|
|
185
|
+
# logger.add(sys.stdout, filter=lambda r: r["function"] == "_dedrift_rec")
|
|
186
|
+
# logger.add(sys.stdout, filter=lambda r: r["function"] == "scan_media_and_build_devices_UID")
|
|
187
|
+
# logger.add(sys.stdout, filter=lambda r: r["function"] == "_parse_track_values")
|
|
188
|
+
top_dir = args.path[0]
|
|
134
189
|
if os.path.isfile(top_dir):
|
|
135
190
|
file = top_dir
|
|
136
191
|
process_single(file, args)
|
|
@@ -148,7 +203,13 @@ def main():
|
|
|
148
203
|
sys.exit(1)
|
|
149
204
|
multi2polywav.poly_all(top_dir)
|
|
150
205
|
scanner = device_scanner.Scanner(top_dir, stay_silent=args.terse)
|
|
151
|
-
scanner.scan_media_and_build_devices_UID()
|
|
206
|
+
scanner.scan_media_and_build_devices_UID()
|
|
207
|
+
for m in scanner.found_media_files:
|
|
208
|
+
if m.device.tracks:
|
|
209
|
+
if not all([lv == None for lv in m.device.tracks.lag_values]):
|
|
210
|
+
logger.debug('%s has lag_values %s'%(
|
|
211
|
+
m.path, m.device.tracks.lag_values))
|
|
212
|
+
process_lag_adjustement(m)
|
|
152
213
|
if not args.terse:
|
|
153
214
|
if scanner.input_structure == 'folder_is_device':
|
|
154
215
|
print('\nDetected structured folders', end='')
|
|
@@ -159,10 +220,8 @@ def main():
|
|
|
159
220
|
else:
|
|
160
221
|
print('\nDetected loose structure')
|
|
161
222
|
if scanner.CAM_numbers() > 1:
|
|
162
|
-
print('\nNote: different CAMs are present, will sync audio')
|
|
163
|
-
print('
|
|
164
|
-
print('respective timecode for NLE timeline alignement')
|
|
165
|
-
print('you should regroup clips by CAM under their own DIR.')
|
|
223
|
+
print('\nNote: different CAMs are present, will sync audio for each of them but if you want to set their')
|
|
224
|
+
print('respective timecode for NLE timeline alignement you should regroup clips by CAM under their own DIR.')
|
|
166
225
|
print('\nFound [gold1]%i[/gold1] media files '%(
|
|
167
226
|
len(scanner.found_media_files)), end='')
|
|
168
227
|
print('from [gold1]%i[/gold1] devices:\n'%(
|
|
@@ -173,25 +232,18 @@ def main():
|
|
|
173
232
|
for m in medias[:-1]:
|
|
174
233
|
print('[gold1]%s[/gold1]'%m.path.name, end=', ')
|
|
175
234
|
print('[gold1]%s[/gold1]'%medias[-1].path.name)
|
|
176
|
-
# print('\nThese recordings will be analysed for timestamps:\n')
|
|
177
|
-
# for m in (scanner.found_media_files):
|
|
178
|
-
# print(' ', '[gold1]%s[/gold1]'%m.path.name)
|
|
179
235
|
print()
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
else:
|
|
183
|
-
rez = process_files_with_progress_bars(scanner.found_media_files)
|
|
184
|
-
recordings, rec_with_yaltc, times = rez
|
|
236
|
+
rez = process_files(scanner.found_media_files)
|
|
237
|
+
recordings, rec_with_TTC, times = rez
|
|
185
238
|
recordings_with_time = [
|
|
186
239
|
rec
|
|
187
|
-
for rec in
|
|
240
|
+
for rec in rec_with_TTC
|
|
188
241
|
if rec.get_start_time()
|
|
189
242
|
]
|
|
190
243
|
if not args.terse:
|
|
191
|
-
print('\n\n')
|
|
192
244
|
table = Table(title="tictacsync results")
|
|
193
245
|
table.add_column("Recording\n", justify="center", style='gold1')
|
|
194
|
-
table.add_column("
|
|
246
|
+
table.add_column("TTC chan\n (1st=#0)", justify="center", style='gold1')
|
|
195
247
|
# table.add_column("Device\n", justify="center", style='gold1')
|
|
196
248
|
table.add_column("UTC times\nstart:end", justify="center", style='gold1')
|
|
197
249
|
table.add_column("Clock drift\n(ppm)", justify="right", style='gold1')
|
|
@@ -199,7 +251,7 @@ def main():
|
|
|
199
251
|
table.add_column("Date\n", justify="center", style='gold1')
|
|
200
252
|
rec_WO_time = [
|
|
201
253
|
rec.AVpath.name
|
|
202
|
-
for rec in
|
|
254
|
+
for rec in rec_with_TTC
|
|
203
255
|
if not rec.get_start_time()
|
|
204
256
|
]
|
|
205
257
|
if rec_WO_time:
|
|
@@ -226,9 +278,6 @@ def main():
|
|
|
226
278
|
print()
|
|
227
279
|
n_devices = scanner.get_devices_number()
|
|
228
280
|
OUT_struct_for_mcam = scanner.top_dir_has_multicam
|
|
229
|
-
# if n_devices > 2:
|
|
230
|
-
# print('\nMerging for more than 2 devices is not implemented yet, quitting...')
|
|
231
|
-
# sys.exit(1)
|
|
232
281
|
if len(recordings_with_time) < 2:
|
|
233
282
|
if not args.terse:
|
|
234
283
|
print('\nNothing to sync, exiting.\n')
|
|
@@ -244,32 +293,25 @@ def main():
|
|
|
244
293
|
print('Warning, can\'t write ISOs without structured folders: [gold1]--isos[/gold1] option ignored.\n')
|
|
245
294
|
asked_ISOs = False
|
|
246
295
|
output_dir = args.o
|
|
247
|
-
if args.verbose_output or args.terse: # verbose, so no progress bars
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
else:
|
|
253
|
-
print()
|
|
254
|
-
for stitcher in track(matcher.video_mergers,
|
|
255
|
-
description="4/4 Merging sound to videos:"):
|
|
256
|
-
stitcher.build_audio_and_write_video(top_dir, arg_out_dir,
|
|
257
|
-
OUT_struct_for_mcam,
|
|
258
|
-
asked_ISOs,)
|
|
296
|
+
# if args.verbose_output or args.terse: # verbose, so no progress bars
|
|
297
|
+
for merger in matcher.video_mergers:
|
|
298
|
+
merger.build_audio_and_write_video(top_dir, arg_out_dir,
|
|
299
|
+
OUT_struct_for_mcam,
|
|
300
|
+
asked_ISOs,)
|
|
259
301
|
if not args.terse:
|
|
260
302
|
print("\n")
|
|
261
303
|
# find out where files were wrtitten
|
|
262
|
-
|
|
304
|
+
a_merger = matcher.video_mergers[0]
|
|
263
305
|
print('\nWrote output in folder [gold1]%s[/gold1]'%(
|
|
264
|
-
|
|
265
|
-
for
|
|
266
|
-
print('[gold1]%s[/gold1]'%
|
|
267
|
-
for audio in
|
|
306
|
+
a_merger.synced_clip_dir))
|
|
307
|
+
for merger in matcher.video_mergers:
|
|
308
|
+
print('[gold1]%s[/gold1]'%merger.videoclip.AVpath.name, end='')
|
|
309
|
+
for audio in merger.get_matched_audio_recs():
|
|
268
310
|
print(' + [gold1]%s[/gold1]'%audio.AVpath.name, end='')
|
|
269
|
-
new_file =
|
|
270
|
-
print(' became [gold1]%s[/gold1]'%
|
|
311
|
+
new_file = merger.videoclip.final_synced_file.parts
|
|
312
|
+
print(' became [gold1]%s[/gold1]'%merger.videoclip.final_synced_file.name)
|
|
271
313
|
# matcher._build_otio_tracks_for_cam()
|
|
272
|
-
matcher.shrink_gaps_between_takes()
|
|
314
|
+
matcher.shrink_gaps_between_takes(args.timelineoffset)
|
|
273
315
|
sys.exit(0)
|
|
274
316
|
|
|
275
317
|
if __name__ == '__main__':
|
tictacsync/multi2polywav.py
CHANGED