Files
admin 0593ff7e62
nginx serve /uploads direct (audio speed) / patch-nginx (push) Failing after 1m34s
数字我 Digital Me:全量入库(大文件走 Git LFS)
2026-10-10 16:24:43 +08:00

97 lines
6.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 生成天下·乐 确权留痕交付物:①确权存证清单(哈希·供时间戳/区块链存证) ②确权登记清单.csv(供著作权登记) ③人类作者性说明.md ④确权档案-全.json(逐首)。
// 落地:老板的 Downloads/天下确权留痕/ + 仓库 provenance/(git 时间戳锚点·仅哈希清单,不含母带)。
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { buildDossier, buildManifest, contentHash } from '../src/services/provenance.js';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const BACKEND = path.resolve(__dirname, '..');
const REPO = path.resolve(BACKEND, '..');
const songs = JSON.parse(readFileSync(path.join(BACKEND, 'src/data/music-library.json'), 'utf8'));
// 诗曲的公版源诗信息(shici.ts)
const shiciSrc = readFileSync(path.join(REPO, 'digital-me-web/src/data/shici.ts'), 'utf8');
const SHI = JSON.parse(shiciSrc.match(/export const SHI: Shi\[\] = (\[[\s\S]*\]);/)[1]);
const shiById = {}; for (const p of SHI) shiById[p.id] = p;
const sourceFor = (s) => {
if (!String(s.id).startsWith('shici:')) return null;
const p = shiById[s.id.slice('shici:'.length)];
return p ? { title: p.title, author: p.author, dynasty: p.dynasty, text: p.text } : null;
};
const generatedAt = new Date().toISOString();
const OWNER = '(运营主体法律全称·待填)· digitme.cn';
// ── 交付目录 ──
const OUT = 'C:/Users/solut/Downloads/天下确权留痕';
mkdirSync(OUT, { recursive: true });
const REPO_PROV = path.join(BACKEND, 'provenance');
mkdirSync(REPO_PROV, { recursive: true });
// ① 存证清单(哈希) —— 落 Downloads + 仓库锚点
const manifest = buildManifest(songs, { generatedAt });
writeFileSync(path.join(OUT, '确权存证清单.json'), JSON.stringify(manifest, null, 2), 'utf8');
writeFileSync(path.join(REPO_PROV, '确权存证清单.json'), JSON.stringify(manifest, null, 2), 'utf8');
// ② 逐首确权档案(全) —— 登记/律师用
const dossiers = songs.map((s) => buildDossier(s, { source: sourceFor(s), owner: OWNER }));
writeFileSync(path.join(OUT, '确权档案-全.json'), JSON.stringify({ generatedAt, count: dossiers.length, dossiers }, null, 2), 'utf8');
// ③ 登记清单 CSV
const esc = (v) => `"${String(v == null ? '' : v).replace(/"/g, '""')}"`;
const anchorCount = songs.filter((s) => !String(s.id).startsWith('shici:')).length;
const shiciCount = songs.length - anchorCount;
const rows = [['曲id', '标题', '家族', '词的类别', '化用来源(公版)', '著作权人', '内容哈希SHA256'].map(esc).join(',')];
for (const s of songs) {
const src = sourceFor(s);
rows.push([
s.id, s.title, s.family,
src ? '化用公版古诗(独创改写受保护)' : '完全原创词',
src ? `${src.title}·${src.author}·${src.dynasty}(公有领域)` : '—',
OWNER, contentHash(s),
].map(esc).join(','));
}
writeFileSync(path.join(OUT, '确权登记清单.csv'), '\uFEFF' + rows.join('\r\n'), 'utf8'); // BOM 便于 Excel 识别 UTF-8
// ④ 人类作者性说明.md
const narrative = `# 天下·乐 曲库 · 人类作者性与确权说明
> 生成时点:${generatedAt}
> 曲目总数:${songs.length}(完全原创词 ${anchorCount} 首 · 化用公版古诗 ${shiciCount} 首)
> 著作权人:${OWNER}
## 一、作品构成与权利定位(三块资产,强弱不同)
1. **歌词(文字作品)** —— 由平台确定创作方向、进行原创写作或对**公有领域**古诗的现代口语化用/重写,并多轮编辑定稿。**人类独创性最强,是最稳的著作权主张。**
2. **成品录音(录音制品/录音制作者权·邻接权)** —— 平台作为录音制品制作者,对**成品音频文件**依法享有复制、发行、信息网络传播权。**对“盗播/盗传我方母带文件”最能打,且基本不受 AI 独创性之争影响。**
3. **曲(音乐作品)** —— 借助 Suno(平台持最高级付费会员,其服务条款授予输出的所有权/商用权)在**人类创作方向、风格选择、编排与甄选**下生成。纯 AI 生成成分的可版权性依个案“人类独创性投入”认定,**不对外主张旋律独占**。
## 二、人类独创性投入(可版权性的证据基础)
每首歌均有以下人类智力投入,记录见《确权档案-全.json》逐首字段:
- **创作方向 / 风格 brief**:由人确定题材、情绪、世界级音乐流派方向;
- **歌词创作与化用改写**:原创歌词;或对公版古诗做结构重组、口语化重写(化用部分为独创表达);
- **生成指令(prompt)**:投喂 Suno 的详细创作指令(配器/节奏/编曲/音色),为人类创作意图的具体化;
- **甄选**:从多版本生成结果中人工甄选定稿、淘汰其余;
- **编排与截取决策**:三版本(纯配乐/男声/女声)、正常版/1分钟版的编排与截取。
## 三、来源合法性(反向侵权自查结论)
- 化用的古诗**全部为公有领域**(诗词篇作者最晚为龚自珍,卒于 1841 年,远逾“作者卒后 50 年”保护期);经核查**无近现代(作者卒于 1976 年及以后)在保护期内的诗人作品**,不存在使用他人在保护期作品的情形。
- 完全原创词不涉及第三方作品。
## 四、确权动作(按此清单执行)
1. **存证(现在做·最快)**:对《确权存证清单.json》做一次**可信时间戳/区块链存证**(如联合信任时间戳/至信链/蚂蚁链/司法链),即以最小成本固定全库“在先创作”时点;masterHash 为全库汇总指纹。
2. **登记(分批)**:按《确权登记清单.csv》,优先登记**变现主打 + 最易被盗**曲目的**歌词(文字作品)**与**成品录音(录音制品)**;曲以弱证据心态登记。
3. **权利来源留存**:保存 Suno 最高级会员凭证 + 生成时点的 ToS 版本快照 + 每首生成记录(补权属链)。
4. **技术配套(已做/待补)**:母带私有存储 + 会员短效签名 URL(已做);**取证水印**(按会员打唯一隐式水印,泄漏可追人)待补。
> ⚠ 法律定性以知识产权律师意见为准。AIGC 可版权性在中国为个案裁量、尚未定论;本材料用于把“谁、何时、拥有什么、有何人类投入”固化为证据,不等于对“曲”能取得独占版权。
`;
writeFileSync(path.join(OUT, '人类作者性说明.md'), narrative, 'utf8');
console.log('确权留痕已生成:');
console.log(' 曲目', songs.length, '(原创词', anchorCount, '· 化用公版', shiciCount, ')');
console.log(' masterHash', manifest.masterHash_SHA256);
console.log(' → Downloads/天下确权留痕/:确权存证清单.json · 确权登记清单.csv · 人类作者性说明.md · 确权档案-全.json');
console.log(' → 仓库 provenance/确权存证清单.json(git 时间戳锚点)');