| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- #!/bin/bash
- set -e
- B_URL='http://dashscope-a717.oss-cn-beijing.aliyuncs.com/1d/c2/20260712/9f107364/2b785586-afa2-445d-b4b3-5bb3a9939781.wav?Expires=1783879166&OSSAccessKeyId=LTAI5tPxpiCM2hjmWrFXrym1&Signature=cw%2BT4is4ceG0uxc7k7IWE8O9e0c%3D'
- curl -sS -m 30 -o /tmp/aliyun-B-slow.wav "$B_URL"
- ls -la /tmp/aliyun-B-slow.wav
- ffmpeg -i /tmp/aliyun-B-slow.wav -f null - 2>&1 | grep -E 'Duration|Stream' | head -2
- echo
- echo '=== C: A + ffmpeg atempo=0.78 后处理(模拟播放器减速) ==='
- ffmpeg -i /tmp/aliyun-A.mp3 -filter:a 'atempo=0.78' -y /tmp/aliyun-C-atempo.mp3 2>&1 | tail -1
- ffmpeg -i /tmp/aliyun-C-atempo.mp3 -f null - 2>&1 | grep Duration | head -1
- echo
- echo '=== 对比 ==='
- A_SEC=$(ffmpeg -i /tmp/aliyun-A.mp3 -f null - 2>&1 | grep Duration | head -1 | sed 's/Duration: //; s/,.*//' | awk -F: '{print ($1*3600+$2*60+$3)}')
- B_SEC=$(ffmpeg -i /tmp/aliyun-B-slow.wav -f null - 2>&1 | grep Duration | head -1 | sed 's/Duration: //; s/,.*//' | awk -F: '{print ($1*3600+$2*60+$3)}')
- C_SEC=$(ffmpeg -i /tmp/aliyun-C-atempo.mp3 -f null - 2>&1 | grep Duration | head -1 | sed 's/Duration: //; s/,.*//' | awk -F: '{print ($1*3600+$2*60+$3)}')
- python3 - <<EOF
- A=$A_SEC; B=$B_SEC; C=$C_SEC
- print(f"A 阿里云 1.0x 默认: {A:.2f}s")
- print(f"B 阿里云 Instruct 语速较慢: {B:.2f}s ({B/A:.3f}x)")
- print(f"C 阿里云 1.0x + atempo=0.78:{C:.2f}s ({C/A:.3f}x)")
- print()
- print(f"B vs C 差异: {abs(B-C)/A*100:.2f}%")
- if abs(B-C)/A < 0.05:
- print("=> 结论: B ≈ C, 阿里云 Instruct 语速控制也是后处理变速(类似 Edge TTS)")
- else:
- print("=> 结论: B 与 C 显著不同, 阿里云 Instruct 是真正的模型级慢速生成")
- EOF
- echo
- echo '=== 顺便看看波形是不是真不同(语谱图) ==='
- ffmpeg -i /tmp/aliyun-A.mp3 -lavfi showspectrumpic=s=1024x512 /tmp/aliyun-A-spec.png 2>&1 | tail -1
- ffmpeg -i /tmp/aliyun-B-slow.wav -lavfi showspectrumpic=s=1024x512 /tmp/aliyun-B-spec.png 2>&1 | tail -1
- ffmpeg -i /tmp/aliyun-C-atempo.mp3 -lavfi showspectrumpic=s=1024x512 /tmp/aliyun-C-spec.png 2>&1 | tail -1
- ls -la /tmp/aliyun-*-spec.png
- echo
- echo '=== 把三个 mp3 上传到 OSS 让你试听 ==='
- cp /data/ai/audio/server/.env /tmp/dashscope.env 2>/dev/null
- cd /data/ai/audio/server && node -e '
- const OSS = require("ali-oss").default || require("ali-oss");
- require("dotenv").config({ path: "/data/ai/audio/server/.env" });
- const c = {
- region: "oss-cn-shanghai",
- accessKeyId: process.env.OSS_ACCESS_KEY_ID,
- accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
- bucket: process.env.OSS_BUCKET_NAME,
- internal: true,
- endpoint: process.env.OSS_INTERNAL_ENDPOINT,
- };
- const client = new OSS(c);
- const fs = require("fs");
- const files = {
- "aliyun-A-default": "/tmp/aliyun-A.mp3",
- "aliyun-B-instruct-slow": "/tmp/aliyun-B-slow.wav",
- "aliyun-C-atempo-postprocess": "/tmp/aliyun-C-atempo.mp3",
- };
- (async () => {
- for (const [name, path] of Object.entries(files)) {
- const key = `audio/voice-samples/aliyun-${name}.mp3`;
- await client.put(key, fs.readFileSync(path));
- console.log("uploaded:", key);
- }
- const PUB = process.env.OSS_ENDPOINT;
- for (const name of Object.keys(files)) {
- console.log(`https://${process.env.OSS_BUCKET_NAME}.${PUB}/audio/voice-samples/aliyun-${name}.mp3`);
- }
- })().catch(e => { console.error(e); process.exit(1); });
- '
|