发烧的悟净 发表于 2024-10-18 09:18

使用 Roon 听音乐,搭建智能化资源管理系统的幸福体验

本帖最后由 发烧的悟净 于 2024-10-18 09:39 编辑

      作为一名HIFI爱好者,每天打开Roon,看到最新下载的音乐自动整齐地加载到音乐库中,是一件无比美妙的事情。通过合理的自动化脚本,我们可以让Roon和NAS的搭配达到完美的效果,让每一天的音乐时光都变得更加愉快。本文将分享如何搭建一套智能化的音乐资源管理系统,包括自动化的资源下载、格式转换、文件整理以及最终入库。
自动化资源下载:轻松获取最新音乐系统的第一步是通过Transmission实现自动化音乐下载。我使用Python编写了一个脚本,定期抓取自己喜欢的音乐资源,并通过Transmission的API自动将它们加入下载队列。这一步彻底免除了手动寻找资源的麻烦,每天都有新的音乐自动到来,仿佛拥有了一个私人音乐管家。
import requests

# 通过Transmission API将抓取的种子文件加入下载队列
def add_torrent(torrent_url):
    session_id = get_transmission_session_id()# 获取Transmission session id
    headers = {'X-Transmission-Session-Id': session_id}
    data = {"method": "torrent-add", "arguments": {"filename": torrent_url}}
    response = requests.post(TRANSMISSION_URL, headers=headers, json=data)
    print("下载任务已添加:", response.status_code)



音乐文件整理与格式转换:为Roon优化在下载完成后,接下来的任务就是将音乐文件按照Roon的需求整理好。为保证最高的音质和播放兼容性,我的曲库中所有PCM格式的文件都统一转换为FLAC格式,而SACD文件则被提取成DSF格式。通过这些自动化的格式转换,不仅可以节省空间,还能提高Roon的解析效率。
1. WAV 转 FLAC所有从网上下载的WAV文件都会被自动转换成FLAC格式,因为FLAC不仅支持无损压缩,还能大幅减少存储空间。
import subprocess

def convert_wav_to_flac(wav_file):
    flac_file = wav_file.with_suffix('.flac')
    subprocess.run(['ffmpeg', '-i', str(wav_file), str(flac_file)])
    print(f"已转换 {wav_file} 为 FLAC 文件.")



2. SACD 转 DSFSACD资源往往是高音质音乐爱好者的珍藏。我使用一个Python脚本自动将SACD ISO文件提取成DSF文件,以便在Roon中更好地管理和播放这些音乐。
def extract_sacd_to_dsf(iso_file):
    output_dir = iso_file.with_suffix('')# 将ISO提取到目录
    subprocess.run(['sacd_extract', '-2', '-s', '-A', '-a', '-o', output_dir, '-i', iso_file])
    print(f"已提取SACD {iso_file} 为DSF文件.")



分轨与文件整理:精准管理3. CUE 提取分轨有些下载的音乐专辑是整轨文件,而通过CUE分轨,可以让每首歌曲在Roon中独立显示。自动化的CUE分轨脚本,让这一过程变得简单而高效。
def split_cue(file, cue_file):
    subprocess.run(['shnsplit', '-f', cue_file, '-o', 'flac', file])
    print(f"已通过 {cue_file} 分割 {file} 文件.")



4. 复制专辑封面图片为了让Roon能够正确识别专辑封面,我们需要确保封面图片与音乐文件在同一目录下。如果封面存放在子目录中,我的脚本会自动将封面图片复制到父目录,以便Roon快速抓取封面信息。
def copy_album_cover(subdir):
    for image_file in subdir.glob('*.jpg'):
      destination = subdir.parent / image_file.name
      image_file.replace(destination)
      print(f"已将 {image_file} 移动至专辑目录 {destination}.")



5. 清空空目录随着资源的下载和整理,可能会产生一些空文件夹。为了保持目录整洁并避免不必要的混乱,我的脚本会自动扫描并删除所有空目录。
def remove_empty_directories(directory):
    for dirpath in directory.rglob('*'):
      if dirpath.is_dir() and not any(dirpath.iterdir()):
            dirpath.rmdir()
            print(f"已删除空目录 {dirpath}.")



提交入库:Roon 的每日惊喜6. 提交入NAS库最后一步是将处理完的音乐文件自动同步到NAS,并确保Roon每天都能自动加载最新的音乐。这个步骤让我每天早上打开Roon时都充满期待,因为我知道,所有最新的音乐已经悄悄地躺在了我的音乐库里。
def sync_to_nas(local_directory, nas_directory):
    subprocess.run(['rsync', '-av', local_directory, nas_directory])
    print(f"已将 {local_directory} 同步至 NAS 目录 {nas_directory}.")



幸福体验:Roon 的音乐新发现通过这样一套自动化的资源管理系统,每天早晨我只需要打开Roon,今天的最新音乐便会自动出现在我的曲库中。无论是全新的SACD资源,还是从网上抓取的经典专辑,都能完美呈现。Roon自动扫描并识别封面和曲目信息,播放体验也始终流畅优雅。
拥有这套智能化的下载和整理系统,音乐的管理和欣赏变得如此简单而有趣。这不仅节省了大量时间,更让我体验到HIFI世界中的那份安静和专注,真正实现了听音乐的幸福感。
每天都有新发现,每次都有新惊喜。希望这篇文章也能带给你搭建这样一套系统的灵感,让Roon和音乐世界为你带来更多的美好体验。


发烧的悟净 发表于 2024-10-18 09:36

本帖最后由 发烧的悟净 于 2024-10-18 09:37 编辑

本周加入的古典专辑是这个样子的

zhidongky2 发表于 2024-10-19 15:28

楼主,roon里面的华语流行音乐多吗

番茄炒蛋饭 发表于 2024-10-19 18:11

高手,我开发的HI-Player也深度支持ROON

发烧的悟净 发表于 2024-10-20 00:27

番茄炒蛋饭 发表于 2024-10-19 18:11
高手,我开发的HI-Player也深度支持ROON

有机会尝试一下{:4_93:}

发烧的悟净 发表于 2024-10-20 00:28

zhidongky2 发表于 2024-10-19 15:28
楼主,roon里面的华语流行音乐多吗

不算多

skychty 发表于 2024-10-22 11:55

本帖最后由 skychty 于 2024-10-22 11:56 编辑

番茄炒蛋饭 发表于 2024-10-19 18:11
高手,我开发的HI-Player也深度支持ROON
大神,大概有些什么功能,是手机上的app吗?

tn529 发表于 2024-10-22 16:23

番茄炒蛋饭 发表于 2024-10-19 18:11
高手,我开发的HI-Player也深度支持ROON

有windows版本吗

derekchen0866 发表于 2024-10-22 17:17

zhidongky2 发表于 2024-10-19 15:28
楼主,roon里面的华语流行音乐多吗

roon只是播放平台,本身没有音乐资源。目前roon有内置qobuz,tidal,kkbox三家音乐网站的端口,但需要用户自己去这三家网站订阅,通过内置端口登录,才能调用资源进行播放

zhidongky2 发表于 2024-10-22 22:23

derekchen0866 发表于 2024-10-22 17:17
roon只是播放平台,本身没有音乐资源。目前roon有内置qobuz,tidal,kkbox三家音乐网站的端口,但需要用 ...

岂不是又要花钱?

huangshihai 发表于 2024-10-23 11:14

看到高手的操作赏心悦目,FLOW

pp46318 发表于 2024-10-25 10:40

楼主可否给详细讲下cue,对脚本不是很懂

发烧的悟净 发表于 2024-10-25 17:19


楼主可否给详细讲下cue,对脚本不是很懂
import re
from typing import List, Dict

def parse_cue(file_path: str) -> Dict]]:
    """
    解析CUE文件并提取信息,返回一个字典,其中包含专辑和音轨信息。
   
    Args:
      file_path (str): CUE文件的路径。
      
    Returns:
      Dict]]: 包含专辑和音轨信息的字典。
    """
    # 用于存储专辑和音轨信息的字典
    cue_data = {
      "album": None,
      "tracks": []
    }
   
    with open(file_path, "r", encoding="utf-8") as file:
      track_data = {}
      
      for line in file:
            line = line.strip()
            if line.startswith("TITLE"):
                title = re.findall(r'"(.+?)"', line)
                if "TRACK" not in line:
                  cue_data["album"] = title if title else ""
                else:
                  track_data["title"] = title if title else ""
            
            elif line.startswith("PERFORMER"):
                performer = re.findall(r'"(.+?)"', line)
                if "TRACK" not in line:
                  cue_data["performer"] = performer if performer else ""
                else:
                  track_data["performer"] = performer if performer else ""
            
            elif line.startswith("INDEX 01"):
                index_time = line.split()[-1]
                track_data["index"] = index_time
               
                # 将该音轨添加到cue_data
                cue_data["tracks"].append(track_data)
                track_data = {}# 重置track_data以便解析下一个音轨
               
    return cue_data

# 示例使用
cue_file = "sample.cue"
parsed_data = parse_cue(cue_file)
print(parsed_data)
注:示例代码,不可执行

思路:
文件读取:打开指定的CUE文件,并逐行读取内容。

专辑信息提取:

检查每行是否以TITLE或PERFORMER开头来提取专辑的标题和演奏者信息。
如果TITLE或PERFORMER出现在非音轨的行中(即没有TRACK关键字),则将信息视为专辑信息而非音轨信息。
音轨信息提取:

遇到TRACK关键字时,准备解析一个新的音轨。
对于音轨的TITLE、PERFORMER和INDEX信息,分别提取标题、演奏者和开始时间(格式为mm:ss:ff)。
每个音轨信息保存在字典track_data中。
数据存储:

当解析到INDEX 01时,认为该音轨信息已完整,将track_data添加到主字典cue_data中的tracks列表中,并重置track_data字典以准备下一个音轨的解析。
返回结果:解析完成后,返回包含专辑和音轨信息的cue_data字典。

这个解析器能够提取常见的专辑和音轨信息,适用于CUE文件的基础解析。

发烧的悟净 发表于 2024-10-25 17:22

pp46318 发表于 2024-10-25 10:40
楼主可否给详细讲下cue,对脚本不是很懂

楼主可否给详细讲下cue,对脚本不是很懂import re
from typing import List, Dict

def parse_cue(file_path: str) -> Dict]]:
    """
    解析CUE文件并提取信息,返回一个字典,其中包含专辑和音轨信息。
   
    Args:
      file_path (str): CUE文件的路径。
      
    Returns:
      Dict]]: 包含专辑和音轨信息的字典。
    """
    # 用于存储专辑和音轨信息的字典
    cue_data = {
      "album": None,
      "tracks": []
    }
   
    with open(file_path, "r", encoding="utf-8") as file:
      track_data = {}
      
      for line in file:
            line = line.strip()
            if line.startswith("TITLE"):
                title = re.findall(r'"(.+?)"', line)
                if "TRACK" not in line:
                  cue_data["album"] = title if title else ""
                else:
                  track_data["title"] = title if title else ""
            
            elif line.startswith("PERFORMER"):
                performer = re.findall(r'"(.+?)"', line)
                if "TRACK" not in line:
                  cue_data["performer"] = performer if performer else ""
                else:
                  track_data["performer"] = performer if performer else ""
            
            elif line.startswith("INDEX 01"):
                index_time = line.split()[-1]
                track_data["index"] = index_time
               
                # 将该音轨添加到cue_data
                cue_data["tracks"].append(track_data)
                track_data = {}# 重置track_data以便解析下一个音轨
               
    return cue_data

# 示例使用
cue_file = "sample.cue"
parsed_data = parse_cue(cue_file)
print(parsed_data)
注:示例代码,不可执行

思路:
文件读取:打开指定的CUE文件,并逐行读取内容。

专辑信息提取:

检查每行是否以TITLE或PERFORMER开头来提取专辑的标题和演奏者信息。
如果TITLE或PERFORMER出现在非音轨的行中(即没有TRACK关键字),则将信息视为专辑信息而非音轨信息。
音轨信息提取:

遇到TRACK关键字时,准备解析一个新的音轨。
对于音轨的TITLE、PERFORMER和INDEX信息,分别提取标题、演奏者和开始时间(格式为mm:ss:ff)。
每个音轨信息保存在字典track_data中。
数据存储:

当解析到INDEX 01时,认为该音轨信息已完整,将track_data添加到主字典cue_data中的tracks列表中,并重置track_data字典以准备下一个音轨的解析。
返回结果:解析完成后,返回包含专辑和音轨信息的cue_data字典。

这个解析器能够提取常见的专辑和音轨信息,适用于CUE文件的基础解析。

pp46318 发表于 2024-10-26 09:06

发烧的悟净 发表于 2024-10-25 17:22
注:示例代码,不可执行

思路:


非常感谢楼主耐心详细的解答。不过还是有个问题,这个具体要怎么操作呢?

hlgwo 发表于 2025-1-12 20:53

请问能远程帮助设一下吗?请看站内短信

skylineLab 发表于 2025-1-13 00:23

zhidongky2 发表于 2024-10-19 15:28
楼主,roon里面的华语流行音乐多吗

1、 咸鱼25买一个学习版本roon不能用流媒体,但是可以播本地的
2. 淘宝200出头买个百度音乐资源网盘,还帮忙找专辑的,把那些东西下载到自己的NAS我买的那个太多了,就调了14个T ,古典华语欧美 日本全有了

3. NAS 做roon core,家里手机 电脑数播直接用roon 非常方便   折下来也没多少钱

不知怎么改 发表于 2025-1-15 21:56

zhidongky2 发表于 2024-10-19 15:28
楼主,roon里面的华语流行音乐多吗

不多 qobuz华语版权都不齐 我听的日语版权也有缺qq音乐是最多的

不知怎么改 发表于 2025-1-15 21:57

zhidongky2 发表于 2024-10-19 15:28
楼主,roon里面的华语流行音乐多吗

主要roon非常方便 用了就回不去了 我直接冲了终生版

902letter 发表于 2025-2-10 12:13

我也觉得CUE自动分轨那个功能最实用,具体脚本代码怎么实现?是在windows下面写吗
页: [1] 2
查看完整版本: 使用 Roon 听音乐,搭建智能化资源管理系统的幸福体验