音乐文件下载和元数据刮削思路

前言 个人音乐服务Navidrome搭建之后,必然会碰到高质量的音乐文件来源和歌曲元数据的问题,这里说一下个人解决办法。我是以腾讯音乐为基础,从腾讯下载mp3音乐文件,然后将腾讯音乐的元数据写入到mp3里,偶尔碰到在腾讯里没有版权的音乐,会在网易音乐里搜索有没有,使用网易音乐的音乐元数据,实在没有就没有办法了。 过程中会使用的一些开源服务,两个已经都不更新,一直用得挺好就没有找其他替代了。 QQMusicApi: 腾讯音乐API服务,需要部署在自有的服务器或者本机都可以,需要的时候启动,使用之前需要设置账号信息和更新登陆的Cookie。 需要会员,不提供无会员下载320的音乐 NeteaseCloudMusicApi: 网易音乐API服务,可以实现在Vercel部署使用。 请支持正版音乐!!!有需要更新音乐的时候,会购买一个的腾讯音乐会员,登陆后提取Cookie发送到QQMusicApi服务,后面使用到QQMusicApi的服务都是在登陆之后的操作。网易音乐我只是使用元数据,暂时没有购买过会员。 腾讯音乐会员可以官方购买,或者某些APP里兑换会员服务,或者是闲鱼、淘宝都可以的,哪个便宜搞哪个 整体使用Python代码实现的下面过程,因为不具备通用性,这里只说一下怎么使用的思路。 音乐来源 专辑: 如你在腾讯音乐找到周杰伦的《J III MP3 Player》,看到浏览器的URL:https://y.qq.com/n/ryqq/albumDetail/002MAeob3zLXwZ,最后的002MAeob3zLXwZ就是专辑的albummid,接下来调用QQMusicApi的获取专辑内的歌曲接口,可以获取到专辑歌曲清单的json数据。 歌单: 腾讯音乐提供了榜单和歌单,都可以QQMusicApi的获取榜单详情和获取歌单详情,根据个人喜好可以找对应的日常更新。 网易音乐也有提供排行榜和歌单,可以调用NeteaseCloudMusicApi的获取歌单所有歌曲。 Apple Music有每周热门100首和城市排行榜的歌单,找到对应歌单返回歌曲链接,分析请求参数和header信息,后续需要更新音乐的时候,重新访问地址获取Cookie里的authorization,更新到请求代码,处理返回的json数据就可以获取歌单信息了。 Spotify榜单,找自己想更新的对应榜单,同样也是看返回歌曲的链接,分析请求参数和header信息,处理返回的json数据就可以获取歌单信息,当然每次更新歌曲时候也需要更新authorization参数。 歌手: 在腾讯音乐里找歌手的singermid,调用QQMusicApi的 获取热门歌曲,修改参数page能够获取歌手的歌曲清单。 单曲: 在腾讯音乐找对应单曲的songmid,调用QQMusicApi的 单个获取,可以获取包含了很多的歌曲信息,包括歌手、专辑、语种、曲风等,但是不包含歌词。 匹配歌曲 腾讯音乐直接有对应的songmid字段,可以跳过这个步骤。 对于网易、Apple Music、Spotify里获取歌曲清单,基本都会包含歌曲id(songmid)、歌名(songname)、歌手信息等,然后遍历歌单数据拼接查询关键词:歌手名称 - 歌名,如周杰伦 - 晴天,然后调用QQMusicApi的 搜索接口获取返回搜索的数据,具体接口参数详细见链接。对返回的结果第一条数据进行,看歌名和歌手名称是否一致,如果一致就搜索成功,然后找到返回结果的mid就是腾讯音乐的songmid,基本上成功率能达到90%以上,如果没有找到需要手动在浏览器里调用接口自己找一下返回的数据看看(推荐使用firefox,查看json数据方便)。 举例: 网易音乐: 周杰伦 - 晴天,songmid=186016 腾讯音乐:周杰伦 - 晴天,songmid=0039MnYb0qxYhV 根据找到的ID,可以放到一个ID对照文件里,每次搜索之前加载对应的对照表,先通过ID查找一下,是否存在,如果不存在则调用QQMusicApi的 搜索接口,找到了对应的腾讯音乐的songmid,再把ID对应关系写会对照文件,可以加快歌单的更新速度,因为大量是已经下载好的歌曲。 对照表文件示意: 186016 0039MnYb0qxYhV 2133271060 2133271060 nt 对照的文件,我做一个特殊处理,如果在腾讯音乐没有找到的音乐,可以在网易音乐里搜索,采用网易音乐的元数据文件。 如果确实没有找到元数据,我可能就不会放到Navidrome里了。 歌曲信息 腾讯音乐的歌曲信息调用QQMusicApi的 单个获取 网易音乐的歌曲信息调用NeteaseCloudMusicApi的获取歌曲详情 同样这里把获取到的歌曲详情json文件保存到文件系统,按照一定的目录结构组织起来,加快歌曲信息获取速度,先找缓存,再调用接口。 下载歌曲 只试过腾讯会员的下载音乐,网易音乐需要大家尝试。 下载之前,检查本地是否已经下载好了音乐文件,存在就可以跳过。 调用调用QQMusicApi的 下载链接接口获取音乐文件地址,可以传入音质的参数,获取不同音质的音乐文件。 请求音乐文件地址,保存到本地。由于有时会出错,可以在代码里加入重试下载的次数。 歌曲专辑 如果需要更新音乐文件元数据,一般包括:歌曲信息、专辑信息、封面、歌词。 腾讯音乐的歌曲专辑调用QQMusicApi的 获取专辑信息 网易音乐的歌曲专辑调用NeteaseCloudMusicApi的获取专辑内容 同样这里把获取到的歌曲专辑json文件保存到文件系统,按照一定的目录结构组织起来,加快歌曲专辑获取速度,先找缓存,再调用接口。 歌曲封面 歌曲的封面,如果属于专辑的歌曲,获取专辑的封面,如果属于单曲,获取歌手的封面。 腾讯音乐:https://y.gtimg.cn/music/photo_new/T002R300x300M000${mid}.jpg?max_age=2592000 mid参数替换为专辑的id或者歌手的id 网易音乐,如果歌曲信息里al.picUrl存在,直接使用里面的封面地址,否则需要调用NeteaseCloudMusicApi的获取歌手详情,使用data.artist.cover里的歌手封面地址。 下载的封面 对于获取的封面建议也做缓存,以专辑ID、歌手ID为文件名,按照一定的目录结构组织起来,加快歌曲封面获取速度,先找缓存,再调用接口。 ...

十月 27, 2024 · 1 分钟 · 91 字 · Byter ·  Music ·  Metadata

Matplotlib绘图中文乱码解决方法

使用python的matplotlib的库生成图片时,中文字体可能会现实乱码(方块),因为matplotlib默认的字体不支持显示中文。 检查Matplotlib环境 查看matplotlib字体配置文件路径 import matplotlib print(matplotlib.matplotlib_fname()) 返回matplotlibrc 文件路径,如: /usr/local/lib/python3.9/site-packages/matplotlib/mpl-data/matplotlibrc 可以得到 ttf 字体文件的路径: /usr/local/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf 查看matplotlib缓存目录 import matplotlib print(matplotlib.get_cachedir()) 返回的缓存路径,如: /home/xxx/.cache/matplotlib TTF字体文件获取 从Windows系统获取字体 # 如微软雅黑 c:\windows\fonts\msyh.ttc 网络搜索TTF中文字体 配置Matplotlib使用中文字体 方法1: 使用font_manager模块加载字体使用 from matplotlib.font_manager import FontProperties import matplotlib.pyplot as plt font = FontProperties(fname='下载的ttf文件路径', size=12) plt.plot([1, 2, 3], [4, 5, 6]) plt.title('中文标题', fontproperties=font) plt.show() 适合于简单的使用plt场景 方法2: 设置matplotlib字体参数 拷贝字体文件到matplotlib的 ttf 字体文件的路径下 删除matplotlib缓存目录下的json文件 查看字体的Family Name from matplotlib import font_manager for font in font_manager.fontManager.ttflist: print(font.fname,font.name) 输出如下数据: /usr/local/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/ttf/msyh.ttc Microsoft YaHei Family Name 为Microsoft YaHei。 注意,没有输出新加入的字体,需要删除缓存目录下的json文件。 4. 使用示例 import matplotlib.pyplot as plt import matplotlib # 指定默认字体 plt.rcParams['font.family'] = 'Microsoft YaHei' # 或其他支持中文的字体 plt.rcParams['axes.unicode_minus'] = False # 解决负号'-'显示为方块的问题 plt.plot([1, 2, 3], [4, 5, 6]) plt.title('中文标题') plt.show()

搭建自己的密码库Vaultwarden

个人从21年开始使用Vaultwarden一直到现在,项目持续在更新,热度不减。在此之前一直用的是1Password,比较下来Vaultwarden的功能没有比1Password差的,值得推荐大家使用。 什么是Vaultwarden Vaultwarden 是一个用 Rust 编写的非官方 Bitwarden 服务器实现。它与官方 Bitwarden 客户端兼容,非常适合不希望运行官方资源密集型服务的自托管部署。 Vaultwarden 面向个人、家庭和小型组织。开发主要对大型组织有用的功能(例如单点登录、目录同步等)并不是优先考虑的事项,尽管实现这些功能的高质量 PR 会受到欢迎。 以下是 Bitwarden 、1Password、Vaultwarden 密码管理器解决方案之间的主要异同: Bitwarden 1Password Vaultwarden 官网 https://bitwarden.com/ https://1password.com/ https://github.com/dani-garcia/vaultwarden 价格 个人: - 免费:2个用户 2个集合 - 高级:10$/年 2个用户 2个集合 - 家庭:40$/年 6个用户 无限集合 商业: - 团队:4$/用户/月 无限用户 - 企业:6$/用户/月 无限用户 个人: - 个人:2.99$/月 - 家庭:4.99$/月 5个家庭账号 商业: - 团队:19.95$/用户/月 10用户 - 商业:7.99$/用户/月 无限用户 免费 端点支持 Windows、macOS、Linux、iOS、watchOS、Android Windows、macOS、Linux、iOS、watchOS、Android 浏览器插件 Chrome、火狐、Safari 等 Chrome、火狐、Safari 等 Chrome、火狐、Safari 等 密码库选项 Bitwarden Azure 云(美国、欧盟)、客户数据中心 1密码云(美国、加拿大、德国) 自有 安全共享 单一密码、密码组、信用卡、文件 单一密码、密码组、信用卡、文件 单一密码、密码组、信用卡、文件 3rd 方网站和应用程序 MFA 选项 Bitwarden 验证器 1密码 一次性密码,双重 Vaultwarden 验证器 部署准备 准备VPS主机 Docker环境 以Debian系统为例,参考Install using the apt repository 安装,总结下来的安装命令如下: # Add Docker's official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc # Add the repository to Apt sources: echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update # Install the Docker packages sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 推荐Nginx反代 参考nginx网站代理典型配置 配置Vaultwarden 1. 创建Vaultwarden工作目录 创建主目录 首先,在服务器上创建一个用于存放Vaultwarden相关文件的主目录。例如: ...

Docker的网络代理配置

因为网络原因拉取docker官方镜像经常失败或者速度非常慢,可以考虑通过代理服务器拉取镜像。 配置加速器 vim /etc/docker/daemon.json { "registry-mirrors": [ "https://hub-mirror.c.163.com", "https://mirror.baidubce.com" ] } 注意,一定要保证该文件符合 json 规范,否则 Docker 将不能启动。 之后重新启动服务 sudo systemctl daemon-reload sudo systemctl restart docker docker pull代理 在执行docker pull时,是由守护进程dockerd来执行。 因此,代理需要配在dockerd的环境中。 而这个环境,则是受systemd所管控,因此实际是systemd的配置 mkdir -p /etc/systemd/system/docker.service.d vim /etc/systemd/system/docker.service.d/proxy.conf 在这个proxy.conf文件(可以是任意*.conf的形式)中,添加以下内容: [Service] Environment="HTTP_PROXY=http://192.168.112.57:7890" Environment="HTTPS_PROXY=http://192.168.112.57:7890" Environment="NO_PROXY=localhost,127.0.0.1" 之后重新启动服务 systemctl daemon-reload systemctl restart docker Container代理 用户级代理 vim ~/.docker/config.json { "proxies": { "default": { "httpProxy": "http://192.168.112.57:7890", "httpsProxy": "http://192.168.112.57:7890", "noProxy": "localhost,127.0.0.1" } } } 这种方法默认在所有配置修改后启动的容器生效 容器级代理 容器的网络代理,也可以直接在其运行时通过-e注入http_proxy等环境变量。docker-compose的是要配置environment 格式如下: web: environment: HTTP_PROXY: 'http://192.168.112.57:7890' HTTPS_PROXY: 'http://192.168.112.57:7890' NO_PROXY: 'localhost,127.0.0.1' docker build代理 虽然docker build的本质,也是启动一个容器,但是环境会略有不同,用户级配置无效。 在构建时,需要注入http_proxy等参数 ...

十月 6, 2024 · 1 分钟 · 97 字 · Byter ·  Docker

2024-09 跑步日记

2024-09 运动次数: 14 运动距离: 145.18 km 运动时长: 14:04:05 平均距离: 10.37 km 平均心率: 145 bpm 平均配速: 5:48 / km 2024-09-01 时间: 2024-09-01 07:17:45 距离: 10.04 km 时长: 1:00:00 配速: 5:58 / km 心率: 149 bpm ...

九月 29, 2024 · 2 分钟 · 242 字 · Jogger ·  跑步

Hugo集成ECharts支持鼠标点击链接

先看看效果展示,实现鼠标点击提示框链接进入跑步详情页面,整体效果 跑步总结。 为了实现提示框可以点击,来回折腾浪费了很长时间,记录下来以备不时之需。 在ECharts的示例编辑里的tooltip配置项内容: "tooltip": { "triggerOn": "click", "enterable": true, "formatter":function (params) { if (params.value[1] <= 3) { return ''; } else { return ( '<a href="/posts/run/' + params.value[2] + '/" target="_blank\">' + params.value[0].slice(-5) + '</a> <br>' + Number(params.value[1]).toFixed(2) + 'km ' ); } } } Hugo编译时报如下错误: Error: error building site: "xx/content/posts/run/run_stats.md:135:1": "xx/layouts/_default/_markup/render-codeblock-echarts.html:6:37": execute of template failed: template: _default/_markup/render-codeblock-echarts.html:6:37: executing "_default/_markup/render-codeblock-echarts.html" at <transform.Unmarshal>: error calling Unmarshal: "_stream.json:5:1": unmarshal failed: invalid character 'u' in literal false (expecting 'a') Hugo编译时会使用transform.Unmarshal校验json内容,formmater的参数内容不符合规范内容。 ...

九月 15, 2024 · 2 分钟 · 263 字 · Byter ·  ECharts ·  Hugo

ECharts 通过组件 visualMap 指定渲染数据某一维度

先看看效果展示,将原来markdown的表格样式展示修改为热力图展示,整体效果 跑步总结。 最初我的需求是,将一年的跑步数据能够像github的提交贡献图进行展示。 日历可以使用ECharts的日历热力图 安装跑步距离显示为不同颜色,与示例的颜色渐变有所区别 可以通过跑步数据进入跑步详情页面 下来说一下我碰到的几个问题。 热力图支持 由于原来使用的是echarts在线定制模式下载的js文件,进入ECharts在线定制 。 图表中增加选择热力图Heatmap 坐标系增加选择日历Calendar 组件增加选择视觉映射VisualMap 颜色分段显示 "visualMap": { "show": false, "type": "piecewise", "pieces": [ { "gte": 15, "color": "#E49A52" }, { "gte": 10, "lt": 15, "color": "#83C67B" }, { "gte": 3, "lt": 10, "color": "#6B9CF0" }, { "lt": 3, "color": "transparent" } ] } type参数设置为piecewise,分段型视觉映射组件 pieces参数可以使用 lt(小于,less than),gt(大于,greater than),lte(小于等于 less than or equals),gte(大于等于,greater than or equals)来表达边界 按照指定维度渲染图形 在ECharts在线示例编辑器中,测试没有问题,后面程序自动生成了结果集,结果集示例如下: ...

2024-08 跑步日记

2024-08 运动次数: 12 运动距离: 109.93 km 运动时长: 11:02:18 平均距离: 9.16 km 平均心率: 150 bpm 平均配速: 6:01 / km 2024-08-01 时间: 2024-08-01 07:38:34 距离: 7.05 km 时长: 44:15 配速: 6:16 / km 心率: 143 bpm ...

八月 30, 2024 · 1 分钟 · 210 字 · Jogger ·  跑步

跑步记录自动生成Markdown发布博文

通过yihong0618大佬的running_page实现跑步记录自动生成博文,自动发布的工作核心如下图所示。 graph TB subgraph APP [APP Type] direction LR Garmin ~~~ Nike Nike ~~~ Keep end subgraph run [running_page] direction LR laps_drawer --> running_page running_page --> id1[(data.db)] end APP --> running_page id1[(data.db)] -->|gen_svg gen_md|obsidian obsidian --> |maestral|Hugo 首先简单介绍一下yihong0618大佬的running_page功能,支持Nike、Strava、佳明(佳明中国)及 Keep 等自动备份 GPX 数据,生产静态的网页数据,打造个人跑步主页。它是这样工作。 接下来介绍我是怎么使用,我平时是使用Garmin(佳明)手表,数据会通过APP上传到佳明中国。使用步骤如下: 通过running_page使用Garmin-CN to Garmin功能实现数据同步到本地,还实现了一个很棒的功能将数据同步到佳明全球。这个时候你可以通过在Strava里配置,实现将佳明全球的数据同步到你的Strava账号下。 python3 run_page/garmin_sync_cn_global.py $garmin_cn_secret $garmin_secret 生成跑步路线svg和对应的md文件,示例20240317(21.12 km),参考running_page的功能,自己编写的一个生成跑步路线的laps_drawer(示例代码),通过调用gen_svg(示例代码)实现跑步路线的svg文件,然后再统计了一些跑步的统计信息,生产跑步记录md文件。 # gen_svg.py 文件放到running_page工程下的run_page目录,参数参考说明,程序会自动将生成到$blog_path下,需要看代码修改一些相对位置 # laps_drawer.py 文件放到running_page工程下的run_page/gpxtrackposter目录 python3 run_page/gen_svg.py --from-db --title "Running Maps" --type laps --athlete $athlete --track-color "#6B9CF0" --special-color "#83C67B" --special-color2 "#E49A52" --special-distance 10 --special-distance2 15 --min-distance 0.5 --use-localtime --only-run --background-color "#1A1A1A" --animation-time 20 --no-background --blog-dir $blog_path 生成跑步总结统计数据,示例跑步总结,参考running_page的功能,提取跑步信息,结合EChart生成跑量和趋势图。这里也是自己编写的一个python程序gen_md(示例代码)。 # gen_md.py 文件放到running_page工程下的run_page目录,参数参考说明,程序会自动将生成到$blog_path下,需要看代码修改一些相对位置 python3 run_page/gen_md.py --from-db --use-localtime --only-run --min-distance 0.5 --track-color "#6B9CF0" --special-color "#83C67B" --special-color2 "#E49A52" --blog-dir $blog_path Obsidian可以查看生成的md文件,根据文件的位置再调整python程序的相对路径。 通过maestral将新生成的文件自动同步到服务器,然后Hugo编译发布成静态页面。

八月 17, 2024 · 1 分钟 · 110 字 · Byter ·  Garmin ·  Run

2024-07 跑步日记

2024-07 运动次数: 15 运动距离: 136.90 km 运动时长: 13:35:35 平均距离: 9.13 km 平均心率: 148 bpm 平均配速: 5:57 / km 2024-07-01 时间: 2024-07-01 06:59:02 距离: 4.55 km 时长: 27:58 配速: 6:09 / km 心率: 134 bpm ...

七月 28, 2024 · 2 分钟 · 258 字 · Jogger ·  跑步