#!/usr/bin/env python3 """ Parallel script to update sfx_metas with opus file paths. Checks for files in opus_audio_truncated (preferred) or opus_audio directories. """ import os from concurrent.futures import ThreadPoolExecutor, as_completed from tqdm import tqdm from suno_utils.utils.text import read_jsonl, write_jsonl def check_and_update_meta(meta, opus_path, opus_truncated_path): """ Check if opus file exists and update meta with the filepath. Args: meta: Dictionary containing metadata including 'id' opus_path: Path to opus_audio directory opus_truncated_path: Path to opus_audio_truncated directory Returns: tuple: (updated_meta or None, song_id if missing else None) """ song_id = meta["id"] opus_filename = song_id + ".opus" opus_cand = os.path.join(opus_path, opus_filename) trunc_cand = os.path.join(opus_truncated_path, opus_filename) # Prefer truncated version first if os.path.exists(trunc_cand): meta["s3_filepath"] = trunc_cand return meta, None elif os.path.exists(opus_cand): meta["s3_filepath"] = opus_cand return meta, None else: return None, song_id # Return None for missing files def main(): # Configuration input_jsonl = "/app2/suno/data/sara/sfx_get_beats/combined_v3_w_extreme_metas_v0.jsonl" output_jsonl = "/app2/suno/data/sara/sfx_get_beats/combined_v3_w_extreme_metas_v0_updated.jsonl" opus_path = "/app2/suno/data/sara/sfx_get_beats/opus_audio" opus_truncated_path = "/app2/suno/data/sara/sfx_get_beats/opus_audio_truncated" missing_output = "/app2/suno/data/sara/sfx_get_beats/missing_files.txt" # Number of worker threads max_workers = 32 # Adjust based on your system print(f"Reading metadata from {input_jsonl}...") sfx_metas = read_jsonl(input_jsonl) print(f"Loaded {len(sfx_metas)} metadata entries") # Process in parallel updated_metas = [] missing = [] print(f"Processing with {max_workers} workers...") with ThreadPoolExecutor(max_workers=max_workers) as executor: # Submit all tasks future_to_meta = { executor.submit(check_and_update_meta, meta, opus_path, opus_truncated_path): meta for meta in sfx_metas } # Collect results with progress bar for future in tqdm(as_completed(future_to_meta), total=len(sfx_metas)): try: updated_meta, missing_id = future.result() if updated_meta is not None: updated_metas.append(updated_meta) if missing_id is not None: missing.append(missing_id) except Exception as e: original_meta = future_to_meta[future] print(f"Error processing {original_meta.get('id', 'unknown')}: {e}") print(f"\nProcessing complete!") print(f"Total entries processed: {len(sfx_metas)}") print(f"Missing files: {len(missing)}") print(f"Found files (written to output): {len(updated_metas)}") # Save updated metadata print(f"\nSaving updated metadata to {output_jsonl}...") write_jsonl(updated_metas, output_jsonl) # Save missing file list if missing: print(f"Saving missing file list to {missing_output}...") with open(missing_output, 'w') as f: for song_id in missing: f.write(f"{song_id}\n") print("Done!") if __name__ == "__main__": main()