tags: virtualdj title: VirtualDJ Prepared Stems Format h1: As of the time of writing, Virutal DJ splits into 5 stems. Prepared stems are stored in a `.mp4` file with (no video and) 5 audio tracks. In order, these are: 1. Vocal 2. Hihat 3. Bass 4. Instruments 5. Kick The `.vdjstems` file includes a title tag on each stream identifying what it is. ## Extractor Script This is a simple python script to extract the 5 stems. This works on newer `.vdjstems` that include a title on each stem. ```py #!/usr/bin/env python from subprocess import run import json import os import argparse def main(): parser = argparse.ArgumentParser(prog="vdj_extract_stems", description="Extract VDJ Stems") parser.add_argument("files",nargs="+") ns = parser.parse_args() os.makedirs("extract",exist_ok=True) for ifn in ns.files: proc(ifn) def proc(ifn): m = run(["ffprobe","-print_format","json","-show_streams",ifn],capture_output=True) data = json.loads(m.stdout.decode()) streams = data["streams"] for stream in streams: title = stream["tags"]["title"] index = stream["index"] xs = ifn.split(".") x = ".".join(xs[:-2]) ofn = f"extract/{x}_{title.upper()}.m4a" run(["ffmpeg","-n","-i",ifn,"-c:a","copy","-map",f"0:{index}",ofn]) if __name__ == "__main__": main() ``` ### Slightly More Robust This defaults to naming each stem `STEM00`, `STEM01` etc. if the stems are not tagged. Most likely VDJ uses the same order. ```py #!/usr/bin/env python3 from subprocess import run import json import os import argparse def main(): parser = argparse.ArgumentParser(prog="vdj_extract_stems", description="Extract VDJ Stems") parser.add_argument("files",nargs="+") ns = parser.parse_args() os.makedirs("extract",exist_ok=True) for ifn in ns.files: proc(ifn) def proc(ifn): m = run(["ffprobe","-print_format","json","-show_streams",ifn],capture_output=True) data = json.loads(m.stdout.decode()) streams = data["streams"] mapping = [] try: for stream in streams: title = stream["tags"]["title"] index = stream["index"] xs = ifn.split(".") x = ".".join(xs[:-2]) ofn = f"extract/{x}_{title.upper()}.m4a" mapping.append((index,ofn)) except KeyError: for i,stream in enumerate(streams): index = stream["index"] title = f"STEM{i:02d}" xs = ifn.split(".") x = ".".join(xs[:-2]) ofn = f"extract/{x}_{title.upper()}.m4a" mapping.append((index,ofn)) for index,ofn in mapping: run(["ffmpeg","-n","-i",ifn,"-c:a","copy","-map",f"0:{index}",ofn]) if __name__ == "__main__": main() ```