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.

@@ -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 _same(l):
260
- return all(e == l[0] for e in l)
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(_same, transposed_names))
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"] == "build_audio_and_write_video")
130
- # logger.add(sys.stdout, filter=lambda r: r["function"] == "_get_audio_devices")
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
- Building dict according to pysox.remix format.
70
- https://pysox.readthedocs.io/en/latest/api.html#sox.transform.Transformer.remix
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
- # list of list for pysox API
83
- # eg [[1], [3], [4]]
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 _sox_mix(_split_channels(multichan_tmpfl))
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 _sox_mix(_split_channels(multichan_tmpfl))
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 NZBIDX
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
- shift = 0
606
- if mix_tracks[0] > sox_TTC_chan:
607
- shift += 1
608
- for unused_tr in device.tracks.unused:
609
- if mix_tracks[0] > unused_tr:
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
- mix_tracks = [t-shift for t in mix_tracks]
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'%
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tictacsync
3
- Version: 0.3a3
3
+ Version: 0.3a4
4
4
  Summary: command for syncing audio video recordings
5
5
  Home-page: https://tictacsync.org/
6
6
  Author: Raymond Lutz
@@ -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,,