#!/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 - < 结论: 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); }); '