tictacsync 0.3a3__py3-none-any.whl → 0.3a4__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.
Potentially problematic release.
This version of tictacsync might be problematic. Click here for more details.
- tictacsync/device_scanner.py +19 -18
- tictacsync/entry.py +4 -4
- tictacsync/timeline.py +68 -22
- {tictacsync-0.3a3.dist-info → tictacsync-0.3a4.dist-info}/METADATA +1 -1
- tictacsync-0.3a4.dist-info/RECORD +15 -0
- tictacsync-0.3a3.dist-info/RECORD +0 -15
- {tictacsync-0.3a3.dist-info → tictacsync-0.3a4.dist-info}/LICENSE +0 -0
- {tictacsync-0.3a3.dist-info → tictacsync-0.3a4.dist-info}/WHEEL +0 -0
- {tictacsync-0.3a3.dist-info → tictacsync-0.3a4.dist-info}/entry_points.txt +0 -0
- {tictacsync-0.3a3.dist-info → tictacsync-0.3a4.dist-info}/top_level.txt +0 -0
tictacsync/device_scanner.py
CHANGED
|
@@ -230,21 +230,6 @@ class Scanner:
|
|
|
230
230
|
Sets Scanner.input_structure = 'loose'|'folder_is_device'
|
|
231
231
|
|
|
232
232
|
"""
|
|
233
|
-
visible = [f for f in listdir(self.top_directory) if f[0] != '.']
|
|
234
|
-
logger.debug('visible: %s'%visible)
|
|
235
|
-
are_dir = all([isdir(join(self.top_directory, f)) for f in visible])
|
|
236
|
-
are_files = all([isfile(join(self.top_directory, f)) for f in visible])
|
|
237
|
-
logger.debug('dir: %s'%[isdir(join(self.top_directory, f)) for f
|
|
238
|
-
in visible])
|
|
239
|
-
if are_dir:
|
|
240
|
-
visible = [e for e in visible if e != 'SyncedMedia']
|
|
241
|
-
print('\nAssuming those are device folders: ',end='')
|
|
242
|
-
[print('[gold1]%s[/gold1]'%f, end=', ') for f in visible[:-1]]
|
|
243
|
-
print('[gold1]%s[/gold1].'%visible[-1])
|
|
244
|
-
self.input_structure = 'folder_is_device'
|
|
245
|
-
else: # are_files
|
|
246
|
-
self.input_structure = 'loose'
|
|
247
|
-
self.top_dir_has_multicam = False
|
|
248
233
|
files = Path(self.top_directory).rglob('*.*')
|
|
249
234
|
paths = [
|
|
250
235
|
p
|
|
@@ -252,17 +237,33 @@ class Scanner:
|
|
|
252
237
|
if p.suffix[1:] in av_file_extensions
|
|
253
238
|
and 'SyncedMedia' not in p.parts
|
|
254
239
|
]
|
|
240
|
+
logger.debug('found media files %s'%paths)
|
|
241
|
+
parents = [p.parent for p in paths]
|
|
242
|
+
logger.debug('found parents %s'%parents)
|
|
243
|
+
def _list_all_the_same(a_list):
|
|
244
|
+
return a_list.count(a_list[0]) == len(a_list)
|
|
245
|
+
all_parents_are_the_same = _list_all_the_same(parents)
|
|
246
|
+
logger.debug('all_parents_are_the_same %s'%all_parents_are_the_same)
|
|
247
|
+
if all_parents_are_the_same:
|
|
248
|
+
# all media (video + audio) are in a same folder, so this is loose
|
|
249
|
+
self.input_structure = 'loose'
|
|
250
|
+
# for now (TO DO?) 'loose' == no multi-cam
|
|
251
|
+
self.top_dir_has_multicam = False
|
|
252
|
+
else:
|
|
253
|
+
# check later if inside each folder, media have same device,
|
|
254
|
+
# for now, we'll guess structure is 'folder_is_device'
|
|
255
|
+
self.input_structure = 'folder_is_device'
|
|
255
256
|
for p in paths:
|
|
256
257
|
new_media = media_at_path(self.input_structure, p) # dev UID set here
|
|
257
258
|
self.found_media_files.append(new_media)
|
|
258
259
|
# files from devices without UID or name
|
|
259
|
-
def
|
|
260
|
-
|
|
260
|
+
# def _list_all_the_same(l):
|
|
261
|
+
# return all(e == l[0] for e in l)
|
|
261
262
|
def _try_name(medias):
|
|
262
263
|
# return common first strings in filename
|
|
263
264
|
names = [m.path.name for m in medias]
|
|
264
265
|
transposed_names = list(map(list, zip(*names)))
|
|
265
|
-
same = list(map(
|
|
266
|
+
same = list(map(_list_all_the_same, transposed_names))
|
|
266
267
|
try:
|
|
267
268
|
first_diff = same.index(False)
|
|
268
269
|
except:
|
tictacsync/entry.py
CHANGED
|
@@ -126,10 +126,10 @@ def main():
|
|
|
126
126
|
# logger.add(sys.stdout, filter="__main__")
|
|
127
127
|
# logger.add(sys.stdout, filter="device_scanner")
|
|
128
128
|
# logger.add(sys.stdout, filter="yaltc") _extract_sound_to_merge
|
|
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"] == "_get_mix")
|
|
132
|
-
logger.add(sys.stdout, filter=lambda r: r["function"] == "_sox_mix")
|
|
129
|
+
# logger.add(sys.stdout, filter=lambda r: r["function"] == "scan_media_and_build_devices_UID")
|
|
130
|
+
# logger.add(sys.stdout, filter=lambda r: r["function"] == "_sox_multi2mono")
|
|
131
|
+
# logger.add(sys.stdout, filter=lambda r: r["function"] == "_get_mix")
|
|
132
|
+
# logger.add(sys.stdout, filter=lambda r: r["function"] == "_sox_mix")
|
|
133
133
|
top_dir = args.directory[0]
|
|
134
134
|
if os.path.isfile(top_dir):
|
|
135
135
|
file = top_dir
|
tictacsync/timeline.py
CHANGED
|
@@ -66,24 +66,23 @@ def _sox_keep(audio_file, kept_channels) -> tempfile.NamedTemporaryFile:
|
|
|
66
66
|
"""
|
|
67
67
|
Returns a NamedTemporaryFile containing the selected kept_channels
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
eg: 4 channels with TicTacCode_channel at #2
|
|
72
|
-
returns {1: [1], 2: [3], 3: [4]}
|
|
73
|
-
ie the number of channels drops by one and chan 2 is missing
|
|
74
|
-
excluded_channels is a list of Zero Based indexing chan numbers
|
|
75
|
-
|
|
69
|
+
if len(kept_channels) == 1 then it's a mono mix on the specified track
|
|
70
|
+
if len(kept_channels) == 2 then it's a stereo mix on the specified tracks
|
|
76
71
|
"""
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
77
76
|
audio_file = _pathname(audio_file)
|
|
78
77
|
nchan = sox.file_info.channels(audio_file)
|
|
79
78
|
logger.debug('in file of %i chan, have to keep %s'%
|
|
80
79
|
(nchan, kept_channels))
|
|
81
80
|
all_channels = range(1, nchan + 1) # from 1 to nchan included
|
|
82
|
-
#
|
|
83
|
-
#
|
|
81
|
+
# Building dict according to pysox.remix format.
|
|
82
|
+
# https://pysox.readthedocs.io/en/latest/api.html#sox.transform.Transformer.remix
|
|
83
|
+
# eg: {1: [3], 2: [4]} to keep channels 3 & 4
|
|
84
84
|
kept_channels = [[n] for n in kept_channels]
|
|
85
85
|
sox_remix_dict = dict(zip(all_channels, kept_channels))
|
|
86
|
-
# {1: [1], 2: [3], 3: [4]} -> from 4 to 3 chan and chan 2 is dropped
|
|
87
86
|
output_fh = tempfile.NamedTemporaryFile(suffix='.wav', delete=DEL_TEMP)
|
|
88
87
|
out_file = _pathname(output_fh)
|
|
89
88
|
logger.debug('sox in and out files: %s %s'%(audio_file, out_file))
|
|
@@ -159,6 +158,26 @@ def _sox_combine(paths) -> Path:
|
|
|
159
158
|
(merged_duration, nchan))
|
|
160
159
|
return out_file_handle
|
|
161
160
|
|
|
161
|
+
def _sox_multi2mono(multichan_tmpfl) -> tempfile.NamedTemporaryFile:
|
|
162
|
+
# return a mono mix down
|
|
163
|
+
n_chan_input = sox.file_info.channels(_pathname(multichan_tmpfl))
|
|
164
|
+
logger.debug('n chan input: %s'%n_chan_input)
|
|
165
|
+
if n_chan_input == 1: # nothing to mix down
|
|
166
|
+
return multichan_tmpfl
|
|
167
|
+
mono_tpfl = tempfile.NamedTemporaryFile(suffix='.wav',
|
|
168
|
+
delete=DEL_TEMP)
|
|
169
|
+
tfm = sox.Transformer()
|
|
170
|
+
tfm.channels(1)
|
|
171
|
+
status = tfm.build(_pathname(multichan_tmpfl),_pathname(mono_tpfl))
|
|
172
|
+
logger.debug('n chan ouput: %s'%
|
|
173
|
+
sox.file_info.channels(_pathname(mono_tpfl)))
|
|
174
|
+
logger.debug('sox.build status for _sox_multi2mono(): %s'%status)
|
|
175
|
+
if status != True:
|
|
176
|
+
print('Error, sox did not normalize file in _sox_multi2mono()')
|
|
177
|
+
sys.exit(1)
|
|
178
|
+
return mono_tpfl
|
|
179
|
+
|
|
180
|
+
|
|
162
181
|
def _sox_mix(paths:list) -> tempfile.NamedTemporaryFile:
|
|
163
182
|
"""
|
|
164
183
|
mix files referred by the list of Path into a new temporary files passed on return
|
|
@@ -183,6 +202,8 @@ def _sox_mix(paths:list) -> tempfile.NamedTemporaryFile:
|
|
|
183
202
|
cbn.set_input_format(file_type=['wav']*N)
|
|
184
203
|
filenames = [_pathname(p) for p in paths]
|
|
185
204
|
logger.debug('%i files to mix %s'%(N, filenames))
|
|
205
|
+
logger.debug('nchan for each file %s'%[sox.file_info.channels(f) for
|
|
206
|
+
f in filenames])
|
|
186
207
|
mixed_tempf = tempfile.NamedTemporaryFile(suffix='.wav',delete=DEL_TEMP)
|
|
187
208
|
status = cbn.build(filenames,
|
|
188
209
|
_pathname(mixed_tempf),
|
|
@@ -580,14 +601,19 @@ class AudioStitcherVideoMerger:
|
|
|
580
601
|
stereo) mix track, returns a tmpfl containing the corresponding
|
|
581
602
|
tracks. If not, mix all the tracks with sox.
|
|
582
603
|
|
|
604
|
+
If no L-R tracks are declared in tracks.txt, a mono mix is returned;
|
|
605
|
+
If some
|
|
606
|
+
micL micR or mixL mixR
|
|
607
|
+
|
|
583
608
|
"""
|
|
584
609
|
if device.tracks is None:
|
|
585
610
|
logger.debug('no tracks.txt, mixing all')
|
|
586
|
-
return
|
|
611
|
+
return _sox_multi2mono(multichan_tmpfl)
|
|
587
612
|
mix_tracks = device.tracks.mix
|
|
588
613
|
if mix_tracks == []:
|
|
589
614
|
logger.debug('tracks.txt present but no mix trx, mixing all')
|
|
590
|
-
return
|
|
615
|
+
return _sox_multi2mono(multichan_tmpfl)
|
|
616
|
+
# if here, mix exists
|
|
591
617
|
logger.debug('%s has mix %s'%(device.name, mix_tracks))
|
|
592
618
|
logger.debug('device %s'%device)
|
|
593
619
|
if 'ttc' in device.tracks.rawtrx:
|
|
@@ -597,18 +623,40 @@ class AudioStitcherVideoMerger:
|
|
|
597
623
|
else:
|
|
598
624
|
print('Error: no tc or ttc tag in track.txt')
|
|
599
625
|
sys.exit(1)
|
|
600
|
-
sox_TTC_chan += 1 # sox
|
|
626
|
+
sox_TTC_chan += 1 # sox Not ZBIDX
|
|
601
627
|
logger.debug('TTC chan %i'%sox_TTC_chan)
|
|
602
628
|
# redo indexing since tracks.txt numbers refere to complete
|
|
603
629
|
# files and here audio file had TTC and muted channels
|
|
604
|
-
# removed
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
if
|
|
630
|
+
# removed:
|
|
631
|
+
if len(mix_tracks) == 2: # two tracks to shift
|
|
632
|
+
mixL_chan, mixR_chan = mix_tracks
|
|
633
|
+
# shifting left chan if necessary
|
|
634
|
+
shift = 0
|
|
635
|
+
if mixL_chan > sox_TTC_chan:
|
|
636
|
+
shift += 1
|
|
637
|
+
for unused_tr in device.tracks.unused:
|
|
638
|
+
if mixL_chan > unused_tr:
|
|
639
|
+
shift += 1
|
|
640
|
+
mixL_chan -= shift
|
|
641
|
+
# shifting right chan if necessary
|
|
642
|
+
shift = 0
|
|
643
|
+
if mixR_chan > sox_TTC_chan:
|
|
644
|
+
shift += 1
|
|
645
|
+
for unused_tr in device.tracks.unused:
|
|
646
|
+
if mixR_chan > unused_tr:
|
|
647
|
+
shift += 1
|
|
648
|
+
mixR_chan -= shift
|
|
649
|
+
mix_tracks = [mixL_chan, mixR_chan]
|
|
650
|
+
else: # mono, one track to shift
|
|
651
|
+
monomix_chan = mix_tracks[0]
|
|
652
|
+
shift = 0
|
|
653
|
+
if monomix_chan > sox_TTC_chan:
|
|
610
654
|
shift += 1
|
|
611
|
-
|
|
655
|
+
for unused_tr in device.tracks.unused:
|
|
656
|
+
if monomix_chan > unused_tr:
|
|
657
|
+
shift += 1
|
|
658
|
+
monomix_chan -= shift
|
|
659
|
+
mix_tracks = [monomix_chan]
|
|
612
660
|
logger.debug('new mix_tracks: %s'%mix_tracks)
|
|
613
661
|
return _sox_keep(multichan_tmpfl, mix_tracks)
|
|
614
662
|
|
|
@@ -693,8 +741,6 @@ class AudioStitcherVideoMerger:
|
|
|
693
741
|
logger.debug('there are %i dev mixes'%len(mixes))
|
|
694
742
|
logger.debug('mixes %s'%mixes)
|
|
695
743
|
dev_mixes_mix = _sox_mix(mixes)
|
|
696
|
-
# dev_mixes_mix = _sox_combine([audio for _, audio
|
|
697
|
-
# in merged_audio_files_by_device]) # all devices
|
|
698
744
|
logger.debug('will merge with %s'%(_pathname(dev_mixes_mix)))
|
|
699
745
|
self.ref_recording.synced_audio = dev_mixes_mix
|
|
700
746
|
logger.debug('dev_mixes_mix n chan: %i'%
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
tictacsync/LTCcheck.py,sha256=IEfpB_ZajWuRTWtqji0H-B2g7GQvWmGVjfT0Icumv7o,15704
|
|
2
|
+
tictacsync/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
tictacsync/device_scanner.py,sha256=nOUw95hXYUU797wiwoO8_XOfqoalsWWoUxijbpeLkjE,27616
|
|
4
|
+
tictacsync/entry.py,sha256=KeocpXt3ghxgV4cdoZW90pCZ4TAW6upocZ5T2nYiUCQ,11393
|
|
5
|
+
tictacsync/multi2polywav.py,sha256=Zl5EP2Yf-PKiZ8ewRSwqWsDULvKKjeWANK_-Yd5RAg4,7279
|
|
6
|
+
tictacsync/remergemix.py,sha256=BUtZ8YHw5Oz8VseTD-A4imNbtF7h391pw5yyl6v6OG4,4885
|
|
7
|
+
tictacsync/synciso.py,sha256=XmUcdUF9rl4VdCm7XW4PeYWYWM0vgAY9dC2hapoul9g,4821
|
|
8
|
+
tictacsync/timeline.py,sha256=oijPv8w0ROD6-cyhF3fylOSfXKnVjLNjTvSKz9EOHTs,47608
|
|
9
|
+
tictacsync/yaltc.py,sha256=eGCDzp5aTF4zqFN4wNfiESXRnaHEXtQB-u13gYBf8g8,76810
|
|
10
|
+
tictacsync-0.3a4.dist-info/LICENSE,sha256=ZAOPXLh1zlQAnhHUd7oLslKM01YZ5UiAu3STYjwIxck,1068
|
|
11
|
+
tictacsync-0.3a4.dist-info/METADATA,sha256=ejbuKOuHqV2f1h88K60Kw41OgPWgakRBKqdO5vZHduo,5298
|
|
12
|
+
tictacsync-0.3a4.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
13
|
+
tictacsync-0.3a4.dist-info/entry_points.txt,sha256=g3tdFFrVRcrKpuyKOCLUVBMgYfV65q9kpLZUOD_XCKg,139
|
|
14
|
+
tictacsync-0.3a4.dist-info/top_level.txt,sha256=eaCWG-BsYTRR-gLTJbK4RfcaXajr0gjQ6wG97MkGRrg,11
|
|
15
|
+
tictacsync-0.3a4.dist-info/RECORD,,
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
tictacsync/LTCcheck.py,sha256=IEfpB_ZajWuRTWtqji0H-B2g7GQvWmGVjfT0Icumv7o,15704
|
|
2
|
-
tictacsync/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
tictacsync/device_scanner.py,sha256=-m2gd0XWXyJLNWfpLc_XQbMwFfNLJ4y3AmI4abz85W4,27558
|
|
4
|
-
tictacsync/entry.py,sha256=zyF8alGtJ57fmKm-_w1eCZber-T9VmeuKFL6yRyRofM,11385
|
|
5
|
-
tictacsync/multi2polywav.py,sha256=Zl5EP2Yf-PKiZ8ewRSwqWsDULvKKjeWANK_-Yd5RAg4,7279
|
|
6
|
-
tictacsync/remergemix.py,sha256=BUtZ8YHw5Oz8VseTD-A4imNbtF7h391pw5yyl6v6OG4,4885
|
|
7
|
-
tictacsync/synciso.py,sha256=XmUcdUF9rl4VdCm7XW4PeYWYWM0vgAY9dC2hapoul9g,4821
|
|
8
|
-
tictacsync/timeline.py,sha256=Qy37vFmFsGDSVpEio3ts_TmGeD96868qfioIevhp92U,45925
|
|
9
|
-
tictacsync/yaltc.py,sha256=eGCDzp5aTF4zqFN4wNfiESXRnaHEXtQB-u13gYBf8g8,76810
|
|
10
|
-
tictacsync-0.3a3.dist-info/LICENSE,sha256=ZAOPXLh1zlQAnhHUd7oLslKM01YZ5UiAu3STYjwIxck,1068
|
|
11
|
-
tictacsync-0.3a3.dist-info/METADATA,sha256=RLwLKCbmVfO1A1dBZL-wdF9I4nHk2km0c5j05N9mTIY,5298
|
|
12
|
-
tictacsync-0.3a3.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
13
|
-
tictacsync-0.3a3.dist-info/entry_points.txt,sha256=g3tdFFrVRcrKpuyKOCLUVBMgYfV65q9kpLZUOD_XCKg,139
|
|
14
|
-
tictacsync-0.3a3.dist-info/top_level.txt,sha256=eaCWG-BsYTRR-gLTJbK4RfcaXajr0gjQ6wG97MkGRrg,11
|
|
15
|
-
tictacsync-0.3a3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|