效果 Audio Tech Hub Soundware Fluid@创意塑造声音(Win+Mac)

import os
import re
import sys
# ================ 配置区 ================
# ROOT_DIR 支持三种取值:
# None -> 自动解析(推荐):
# 1) 命令行参数 / 拖拽文件夹到脚本上
# 2) 脚本(或 exe)所在目录
# r”F:\某个目录” -> 固定使用该目录
ROOT_DIR = None
# 改用关键字匹配(不区分大小写),支持任意扩展名(包括无扩展名)
YOUTUBE_KEYWORD = “youtube” # 文件名包含该关键字即视为 YouTube 源文件
MP3_KEYWORD = “mp3” # 文件名包含该关键字即视为 MP3 源文件
# INFO 文件采用多级查找:优先 info_zh.txt -> info.txt -> 包含 info 的 .txt 文件
INFO_PRIORITY = [“info_zh.txt”, “info.txt”] # 精确文件名优先
INFO_FALLBACK_KEYWORD = “info” # 若精确文件不存在,则按关键字匹配 .txt
INSERT_MODE = “prepend” # “append” | “prepend” | “replace”
PLACEHOLDER = “”
DRY_RUN = False # True=仅预览,False=执行写入
# 全局失败记录
FAILED_RECORDS = [] # 每个元素为 (目录路径, 失败原因)
# ========================================
def resolve_root_dir():
“””
确定要处理的根目录:
1. 配置区 ROOT_DIR 若非空,优先使用;
2. 命令行参数(支持把文件夹拖到脚本 / 快捷方式上,路径可带引号);
3. 脚本所在目录(打包成 exe 时为 exe 所在目录)。
“””
# 1. 配置区指定
if ROOT_DIR:
path = os.path.abspath(ROOT_DIR)
if os.path.isdir(path):
return path
print(f”[WARN] 配置的 ROOT_DIR 不是有效文件夹,已忽略: {path}”)
# 2. 命令行参数(跳过以 – 开头的开关项)
for arg in sys.argv[1:]:
if arg.startswith(“-“):
continue
path = arg.strip().strip(‘”‘).strip(“‘”)
if os.path.isdir(path):
return os.path.abspath(path)
print(f”[WARN] 命令行参数不是有效文件夹,已忽略: {path}”)
# 3. 脚本 / exe 所在目录
if getattr(sys, “frozen”, False):
return os.path.dirname(os.path.abspath(sys.executable))
return os.path.dirname(os.path.abspath(__file__))
def read_file_content(filepath):
“””尝试多种编码读取文件内容,返回字符串,失败则返回空字符串”””
encodings = [‘utf-8-sig’, ‘utf-16-le’, ‘utf-16-be’, ‘gbk’, ‘latin-1’]
for enc in encodings:
try:
with open(filepath, ‘r’, encoding=enc) as f:
return f.read()
except (UnicodeDecodeError, UnicodeError):
continue
# 全部失败,使用 errors=’replace’ 强制读取
with open(filepath, ‘r’, encoding=’latin-1′, errors=’replace’) as f:
return f.read()
def read_text_file_safe(filepath):
“””安全读取文件,返回非空行列表”””
if not os.path.exists(filepath):
return []
try:
content = read_file_content(filepath)
lines = [line.strip() for line in content.splitlines() if line.strip()]
return lines
except Exception as e:
print(f” [WARN] 读取 {filepath} 出错: {e}”)
return []
def extract_video_id(url):
“””提取 YouTube 视频 ID”””
patterns = [
r'(?:v=|\/)([0-9A-Za-z_-]{11})(?:[?&]|$)’,
r’youtu\.be\/([0-9A-Za-z_-]{11})’,
r’youtube\.com\/embed\/([0-9A-Za-z_-]{11})’
]
for pattern in patterns:
match = re.search(pattern, url)
if match:
return match.group(1)
return None
def generate_embed_html(video_id):
“””生成全浏览器兼容的 Div+Iframe 嵌入代码(16:9 自适应)”””
return f”’

”’
def find_file_by_keyword(directory, keyword, extension=”.txt”):
“””
在目录中查找第一个文件名包含关键字(不区分大小写)且具有指定扩展名的文件
若 extension=None,则不限制扩展名
返回文件完整路径,若不存在则返回 None
“””
if not os.path.isdir(directory):
return None
keyword_lower = keyword.lower()
for filename in os.listdir(directory):
filepath = os.path.join(directory, filename)
if not os.path.isfile(filepath):
continue
name, ext = os.path.splitext(filename)
# 如果指定了扩展名,则检查扩展名是否匹配(忽略大小写)
if extension is not None and ext.lower() != extension.lower():
continue
if keyword_lower in filename.lower():
return filepath
return None
def find_info_file(directory):
“””
在目录中查找 INFO 文件,按优先级:
1. 精确文件名匹配(从 INFO_PRIORITY 列表)
2. 若未找到,则按 INFO_FALLBACK_KEYWORD 进行关键字匹配(仅 .txt)
返回文件完整路径,若不存在返回 None
“””
# 1. 精确匹配
for filename in INFO_PRIORITY:
filepath = os.path.join(directory, filename)
if os.path.isfile(filepath):
return filepath
# 2. 回退:关键字匹配
return find_file_by_keyword(directory, INFO_FALLBACK_KEYWORD, extension=”.txt”)
def insert_embeds(info_file, content_lines, mode, placeholder, dry_run):
“””将内容列表插入到 INFO 文件”””
if not content_lines:
return False
if dry_run:
print(f” [预览] 将插入 {len(content_lines)} 行内容到 {info_file}(模式:{mode})”)
return True
try:
if mode == “append”:
with open(info_file, ‘a’, encoding=’utf-8′) as f:
f.write(“\n\n”)
f.write(“\n”.join(content_lines))
f.write(“\n”)
print(f” [OK] 已追加 {len(content_lines)} 行到 {info_file}”)
return True
elif mode == “prepend”:
if not os.path.exists(info_file):
with open(info_file, ‘w’, encoding=’utf-8′) as f:
f.write(“\n”.join(content_lines))
f.write(“\n”)
print(f” [OK] 已创建文件并写入 {len(content_lines)} 行到 {info_file}”)
return True
else:
original_content = read_file_content(info_file)
new_content = “\n”.join(content_lines) + “\n\n” + original_content
with open(info_file, ‘w’, encoding=’utf-8′) as f:
f.write(new_content)
print(f” [OK] 已插入 {len(content_lines)} 行到 {info_file} 开头”)
return True
elif mode == “replace”:
if not os.path.exists(info_file):
return False
content = read_file_content(info_file)
if placeholder not in content:
print(f” [WARN] 未找到占位符,改为追加模式”)
with open(info_file, ‘a’, encoding=’utf-8′) as f:
f.write(“\n\n”)
f.write(“\n”.join(content_lines))
f.write(“\n”)
return True
new_content = content.replace(placeholder, “\n”.join(content_lines))
with open(info_file, ‘w’, encoding=’utf-8′) as f:
f.write(new_content)
print(f” [OK] 已替换占位符,共 {len(content_lines)} 行”)
return True
else:
print(f” [FAIL] 未知模式: {mode}”)
return False
except Exception as e:
print(f” [FAIL] 写入失败: {e}”)
return False
def process_directory(dir_path):
“””处理单个子文件夹,收集失败原因”””
global FAILED_RECORDS
print(f”\n[DIR] 处理目录: {dir_path}”)
final_lines = []
has_youtube = False
has_mp3 = False
failure_reason = None # 记录本目录失败原因
# —- 1. 处理 YouTube(按关键字匹配) —-
yt_file = find_file_by_keyword(dir_path, YOUTUBE_KEYWORD, extension=None) # 不限扩展名
if yt_file:
print(f” 找到 YouTube 文件: {os.path.basename(yt_file)}”)
links = read_text_file_safe(yt_file)
if links:
embed_codes = []
for url in links:
vid = extract_video_id(url)
if vid:
embed_codes.append(generate_embed_html(vid))
else:
print(f” [WARN] 无法解析 YouTube 链接: {url}”)
if embed_codes:
final_lines.extend(embed_codes)
has_youtube = True
print(f” -> 生成 {len(embed_codes)} 个嵌入代码”)
else:
failure_reason = “YouTube 链接全部无法解析”
print(f” [WARN] {failure_reason},没有生成嵌入代码”)
else:
failure_reason = “YouTube 文件为空或读取失败”
print(f” [WARN] {failure_reason}”)
else:
failure_reason = f”未找到包含 ‘{YOUTUBE_KEYWORD}’ 的文件”
print(f” [WARN] {failure_reason}”)
# —- 2. 处理 MP3(按关键字匹配) —-
mp3_file = find_file_by_keyword(dir_path, MP3_KEYWORD, extension=None) # 不限扩展名
if mp3_file:
print(f” 找到 MP3 文件: {os.path.basename(mp3_file)}”)
mp3_links = read_text_file_safe(mp3_file)
if mp3_links:
if has_youtube:
final_lines.append(“”) # 分隔符
final_lines.extend(mp3_links)
has_mp3 = True
print(f” -> 读取 {len(mp3_links)} 个 MP3 链接”)
else:
if not failure_reason:
failure_reason = “MP3 文件为空或读取失败”
print(f” [WARN] MP3 文件为空或读取失败”)
else:
# MP3 缺失不作为严重失败,仅提示
print(f” [INFO] 未找到包含 ‘{MP3_KEYWORD}’ 的文件,仅处理 YouTube”)
# 如果没有任何内容可插入,记录失败原因(若尚未记录)
if not final_lines:
if not failure_reason:
failure_reason = “无 YouTube 或 MP3 有效内容”
FAILED_RECORDS.append((dir_path, failure_reason))
print(f” -> 无内容可插入,跳过”)
return
# —- 3. 智能查找 INFO 文件 —-
info_file = find_info_file(dir_path)
if not info_file:
reason = f”未找到任何 INFO 文件(尝试了 {INFO_PRIORITY},以及包含 ‘{INFO_FALLBACK_KEYWORD}’ 的 .txt 文件)”
FAILED_RECORDS.append((dir_path, reason))
print(f” [FAIL] {reason},跳过插入”)
return
else:
print(f” 找到 INFO 文件: {os.path.basename(info_file)}”)
# —- 4. 插入内容 —-
success = insert_embeds(info_file, final_lines, INSERT_MODE, PLACEHOLDER, DRY_RUN)
if not success:
reason = “插入内容失败(请查看上方的 [FAIL] 信息)”
FAILED_RECORDS.append((dir_path, reason))
# 不返回,继续尝试删除 MP3 源文件(如果插入失败通常不会删除)
# —- 5. 删除 MP3 源文件(仅在成功插入且非试运行且存在 MP3 文件时) —-
if success and not DRY_RUN and has_mp3 and mp3_file and os.path.exists(mp3_file):
try:
os.remove(mp3_file)
print(f” [OK] 已删除源文件 {mp3_file}”)
except Exception as e:
print(f” [FAIL] 删除 {mp3_file} 失败: {e}”)
def main():
root_dir = resolve_root_dir()
print(f”===== 批量处理开始 =====\n根目录: {root_dir}”)
if DRY_RUN:
print(“【试运行模式】不会实际修改文件\n”)
if not os.path.isdir(root_dir):
print(f”[FAIL] 根目录不存在或不是文件夹: {root_dir}”)
return
processed = 0
for root, dirs, files in os.walk(root_dir):
process_directory(root)
processed += 1
print(f”\n===== 完成 =====\n共扫描 {processed} 个文件夹(含根目录)。”)
# 输出所有失败记录
if FAILED_RECORDS:
print(“\n【失败汇总】以下目录处理未成功:”)
for path, reason in FAILED_RECORDS:
print(f” – {path} : {reason}”)
else:
print(“所有目录均处理成功。”)
if DRY_RUN:
print(“\n这是试运行,未实际修改任何文件。”)
print(“确认无误后,请将脚本中的 DRY_RUN 改为 False 再执行。”)
if __name__ == “__main__”:
main()

VST2/VST3/AU | Windows:144.2 MB | Mac:287.8 MB
Fluid – 以无限创意塑造声音 Fluid 是一款动态 VST 插件,内置丰富的乐器,将模拟声音的灵魂与数字控制的强大功能完美融合,带您进入声音设计的新境界。无论您是创作突破

流派界限的
音乐作品,还是为电影设计沉浸式音频,Fluid 都能让您灵活地塑造、操控和完善您的声音,所有操作均可通过直观的界面完成。126 种全新乐器 ✓

34
种基于合成器的模拟音色
✓ 11 种键盘音色
✓ 17 种拨弦音色
✓ 14 种钟音音色
✓ 10 种合成器音垫
✓ 40 种前沿合成器

主要特性
✓ 混合声音引擎:Fluid 汲取模拟温暖音色的精髓,并将其与前沿的数字功能融合,呈现出丰富、充满活力且完全可定制的声音。
✓ 实时调制:借助功能强大的宏控制,您可以随声音变化而塑造声音。轻松创建动态纹理、复杂音景,或精准微调混音。✓
强大的内置效果:解锁一系列高品质效果,包括颗粒合成、滤波器、延迟、合唱等等。无论您是想为音轨增添深度、动感还是冲击力,Fluid 的效果引擎都能满足您的需求。✓
深度自定义:调整颗粒大小、音高和时间等高级参数,或切换到简易模式,专注于工作流程,无需陷入细节的繁琐设置。✓
专为各级别制作人设计:Fluid 可与您的 DAW 无缝集成,旨在为从新手到专业人士的制作人提供支持。简洁直观的用户界面让您专注于创作,不受干扰;而高级选项则为您提供了突破界限的空间。Fluid

适合哪些用户?
Fluid 专为希望使用专业级音效提升作品的音乐制作人、声音设计师和艺术家而设计。无论你是制作节拍、电影配乐还是声音设计,Fluid 都为你提供了海量的乐器音色,旨在激发你的创作灵感。它不仅仅是重现模拟音色,更是将它们推向全新的创意领域。

资源下载
下载价格5 音符
本店资源,一次购买,永久更新(百度网盘)
0

评论0

请先
请拖动滑块到最右边
没有账号?注册  忘记密码?