Skip to content

Instantly share code, notes, and snippets.

@infval
Last active November 17, 2021 22:00
Show Gist options
  • Save infval/183d34b63199fde9b0ddcfe4353e973f to your computer and use it in GitHub Desktop.
Save infval/183d34b63199fde9b0ddcfe4353e973f to your computer and use it in GitHub Desktop.
Batch SFD mux / demux (Multiplexer / DeMultiplexer) | M1V, ADX, SFA | Python 3, ffmpeg, SFDmux
#!/usr/bin/env python3
from pathlib import Path
from os import system
import sys
overwrite = ''
if len(sys.argv) > 1 and sys.argv[1] == '-y':
overwrite = '-y'
p = Path('.')
for sfd_path in p.glob('*.sfd'):
print('#### {}'.format(sfd_path))
m1v_path = sfd_path.with_suffix('.m1v')
sfa_path = sfd_path.with_suffix('.sfa')
system(r'ffmpeg -i "{}" -c:v copy "{}" {}'.format(sfd_path, m1v_path, overwrite))
system(r'ffmpeg -i "{}" -c:a copy -f adx "{}" {}'.format(sfd_path, sfa_path, overwrite))
# Keep original number of samples (adx)
with open(sfa_path, "r+b") as f_sfa:
detect_str = f_sfa.read(0x0C)
b = sfd_path.read_bytes()
i = b.find(detect_str)
if i != -1:
i += len(detect_str)
# False positive detection
if b.find(detect_str, i) != -1:
f_sfa.seek(0x10)
detect_str = f_sfa.read(1024)
i = b.find(detect_str)
if i != -1:
i += len(detect_str)
# False positive detection
if b.find(detect_str, i) != -1:
print('Original number of samples not found! (3)')
continue
print("Second attempt!")
i -= 4
else:
print('Original number of samples not found! (2)')
continue
num_samples = b[i: i + 4]
f_sfa.seek(0x0C)
f_sfa.write(num_samples)
print("Keep original number of samples")
else:
print('Original number of samples not found! (1)')
#!/usr/bin/env python3
from pathlib import Path
from os import system
import sys
overwrite = False
if len(sys.argv) > 1 and sys.argv[1] == '-y':
overwrite = True
p = Path('.')
for m1v_path in p.glob('*.m1v'):
print('#### {}'.format(m1v_path))
sfd_path = m1v_path.with_suffix('.sfd')
audio_suf = ['.sfa', '.adx']
for suffix in audio_suf:
audio_path = m1v_path.with_suffix(suffix)
if audio_path.exists():
print('#### {}'.format(audio_path))
break
else:
print('File not found: {} + {}'.format(m1v_path.with_suffix(''), " | ".join(audio_suf)))
continue
if sfd_path.exists() and not overwrite:
answer = input("File '{}' already exists. Overwrite ? [y/N]".format(sfd_path))
if answer.strip().lower() != 'y':
continue
system(r'Sfdmux "-V={}" "-A={}" "-S={}"'.format(m1v_path, audio_path, sfd_path))
@Luiz-Brito-Tech
Copy link

Luiz-Brito-Tech commented Nov 13, 2020

To wich point does sfd_mux work? I ran the script and i can only make it print the files' paths.

@infval
Copy link
Author

infval commented Aug 20, 2021

To wich point does sfd_mux work? I ran the script and i can only make it print the files' paths.

It's just a batch script. You need to add Sfdmux.exe and Sfdmux.dll to the script directory (https://forum.xentax.com/viewtopic.php?t=3084#p25927, registration required). The script searches the current directory for all .m1v + .sfa or .adx and runs Sfdmux.exe, for example:
Sfdmux "-V=file.m1v" "-A=file.adx" "-S=file.sfd"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment