代码DEMO
团子提供必要的代码DEMO,包含数种语言的实现,方便开发者快速上手使用。
如何与团子通信
以下为如何与团子通信的代码DEMO。
该接口将返回你发送的请求体内容,来验证你的请求体、请求头和token是否正确。
该片段为最基本的和团子通信的写法,如需要其他的API请求,只需要替换请求地址、请求体和请求头,举一反三即可。
JavaScript
// 需要的依赖:axios(网络请求库), md5(MD5摘要算法实现库)
const axios = require('axios')
const md5 = require('md5')
// 替换为自己的appKey、secret
const appKey = '***'
const secret = '***'
function buildToken(appKey, secret) {
const timestamp = Date.now()
return appKey + "$$" + timestamp + "$$" + md5(secret + timestamp)
}
const request = axios.post(
'https://api.tuanziai.com/echo',
{"test": "my-test-string"},
{
headers: {
"token": buildToken(appKey, secret),
"Content-Type": "application/json"
}
}
)
request.then(response => {
// 输出为:
//Response: { code: 0, message: 'success', data: 'my-test-string' }
console.log('Response:', response.data)
})
Java
// 需要的依赖:okhttp(网络请求库), commons-codec(MD5摘要算法实现库)
import org.apache.commons.codec.digest.DigestUtils;
import java.io.IOException;
import okhttp3.*;
public class DangoDemo {
private static final String APP_KEY = "***";
private static final String SECRET = "***";
private static String buildToken(String appKey, String secret) {
long timestamp = System.currentTimeMillis();
return appKey + "$$" + timestamp + "$$" + DigestUtils.md5Hex(secret + timestamp);
}
public static void main(String[] args) throws IOException {
OkHttpClient client = new OkHttpClient();
// 构建请求体,这里直接拼写了一个JSON字符串,也可以使用其他JSON库来构建请求体
String json = "{\"test\": \"my-test-string\"}";
RequestBody body = RequestBody.create(json, MediaType.parse("application/json"));
// 构建请求
okhttp3.Request request = new Request.Builder()
.url("https://api.tuanziai.com/echo")
.header("token", buildToken(APP_KEY, SECRET))
.header("Content-Type", "application/json")
.post(body)
.build();
// 发送请求
try (Response response = client.newCall(request).execute()) {
// 输出为:
// Response: {"code":0,"message":"success","data":"my-test-string"}
System.out.println("Response: " + response.body().string());
}
}
}
Groovy
// 需要的依赖:spring-web(网络请求库,也可以用okHttp,参考java版本写法)
import groovy.json.JsonOutput
import groovy.transform.CompileStatic
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
import org.springframework.web.client.RestTemplate
@CompileStatic
class GDangoDemo {
static String APP_KEY = "***"
static String SECRET = "***"
private static String buildToken(String appKey, String secret) {
def timestamp = System.currentTimeMillis()
return appKey + "\$\$" + timestamp + "\$\$" + (secret + timestamp).md5()
}
static void main(String[] args) {
def headers = new HttpHeaders()
headers.add("token", buildToken(APP_KEY, SECRET))
headers.add("Content-Type", "application/json")
def body = new RestTemplate().postForObject(
"https://api.tuanziai.com/echo",
new HttpEntity(JsonOutput.toJson(["test": "my-test-string"]), headers),
String,
)
// 输出为:
// Response: {"code":0,"message":"success","data":"my-test-string"}
println("Response: " + body)
}
}
Python
# 需要的依赖:requests
import requests
import hashlib
import time
# 替换为自己的appKey、secret
APP_KEY = '***'
SECRET = '***'
def build_token(app_key, secret):
timestamp = int(time.time() * 1000) # 毫秒级时间戳
sign_str = secret + str(timestamp)
md5_sign = hashlib.md5(sign_str.encode()).hexdigest()
return f"{app_key}$${timestamp}$${md5_sign}"
# 发送POST请求
response = requests.post(
url='https://api.tuanziai.com/echo',
json={"test": "my-test-string"},
headers={"token": build_token(APP_KEY, SECRET), "Content-Type": "application/json"}
)
# 输出为:
# Response: {'code': 0, 'message': 'success', 'data': 'my-test-string'}
print('Response:', response.json())
创建通道并上传歌曲
这里给出创建上传通道、上传歌曲文件到阿里云OSS、并开始处理歌曲的代码DEMO,以伴奏人声提取功能为例。
额外需要注意的是,这里只做了最精简的封装,并没有考虑网络请求的重试、异常处理、以及一些边界情况,请开发者根据自己的实际情况进行完善。
JavaScript
// 需要的依赖:axios(网络请求库), md5(MD5摘要算法实现库),fs(Node环境下的文件系统模块,如果浏览器环境需要file对象代替)
const axios = require('axios')
const md5 = require('md5')
const fs = require('fs')
const appKey = '**'
const secret = '**'
function buildToken(appKey, secret) {
const timestamp = Date.now()
return appKey + '$$' + timestamp + '$$' + md5(secret + timestamp)
}
// 简单的封装一个请求函数,方便后续调用
function postToDango(url, body) {
return axios.post(url, body, {
headers: {
'token': buildToken(appKey, secret),
'Content-Type': 'application/json'
}
})
}
async function uploadToDango(filePath) {
// 第一步:创建上传通道
const {url, form, channel} = (await postToDango('https://api.tuanziai.com/vocal-remover/upload/channel', {
"uploadVersion": 2,
"style": 29,
"filename": "test.mp3",
"config": {
"separateBackingVocals": false
}
})).data.data
// 第二步:使用返回的url和form字段上传文件到OSS
// 当前代码为Node环境,如果是浏览器环境,可以使用file对象和FormData来上传。
await axios.postForm(
url, //无需关心上传到哪里,直接使用团子返回的url字段
{
...form, // 无需关心团子提供的form都有什么键值,直接“一股脑”将form字段展开作为请求体的一部分
file: fs.createReadStream(filePath) //在form的最后添加一个file字段,值为要上传的文件
}
)
// 第三步:通知团子上传完成,并获取musicId
const musicId = (await postToDango(`https://api.tuanziai.com/vocal-remover/upload/${channel}/result`)).data.data
return musicId
}
uploadToDango('d:\\test\\real.wav').then(musicId => {
// 输出为:
// 上传成功,音乐ID: f81be254ec5242d29be254ec52c2d2e2
// 之后就可以使用这个音乐ID去请求处理结果了,具体接口文档请参考开放平台文档
console.log('上传成功,音乐ID:', musicId)
})
Java
// 需要的依赖:okhttp(网络请求库), commons-codec(MD5摘要算法实现库),fastjson(JSON解析库)
import org.apache.commons.codec.digest.DigestUtils;
import java.io.File;
import java.io.IOException;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import okhttp3.*;
public class DangoDemo {
private static final String APP_KEY = "**";
private static final String SECRET = "**";
private static final OkHttpClient client = new OkHttpClient();
private static String buildToken() {
long ts = System.currentTimeMillis();
return APP_KEY + "$$" + ts + "$$" + DigestUtils.md5Hex(SECRET + ts);
}
// 通用请求方法:url, body(可为null), 是否返回JSON对象
private static JSONObject postToDango(String url, Object body) throws IOException {
Request.Builder builder = new Request.Builder().url(url).header("token", buildToken());
if(body == null) {
body = "";
} else {
body = JSON.toJSONString(body);
}
builder.post(RequestBody.create((String)body, MediaType.parse("application/json")));
try (Response resp = client.newCall(builder.build()).execute()) {
return JSONObject.parseObject(resp.body().string());
}
}
public static String uploadToDango(String filePath) throws IOException {
// 1. 创建通道
JSONObject req = new JSONObject();
req.put("uploadVersion", 2);
req.put("style", 29);
req.put("filename", "test.mp3");
req.put("config", new JSONObject().put("separateBackingVocals", false));
JSONObject createUploadChannelResultBody = postToDango("https://api.tuanziai.com/vocal-remover/upload/channel", req);
createUploadChannelResultBody = createUploadChannelResultBody.getJSONObject("data");
JSONObject form = createUploadChannelResultBody.getJSONObject("form");
String url = createUploadChannelResultBody.getString("url");
String channel = createUploadChannelResultBody.getString("channel");
// 2. 上传文件
MultipartBody.Builder formBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
form.entrySet().forEach(entry -> {
formBuilder.addFormDataPart(entry.getKey(), entry.getValue().toString());
});
formBuilder.addFormDataPart("file", new File(filePath).getName(), RequestBody.create(new File(filePath), MediaType.parse("application/octet-stream")));
client.newCall(new Request.Builder().url(url).post(formBuilder.build()).build()).execute();
// 3. 获取结果(返回纯字符串)
JSONObject getChannelResultBody = postToDango("https://api.tuanziai.com/vocal-remover/upload/" + channel + "/result", null);
String musicId = getChannelResultBody.getString("data");
return musicId;
}
public static void main(String[] args) throws IOException {
String musicId = uploadToDango("d:\\test\\real.wav");
// 输出为:
// 上传成功,音乐ID: f81be254ec5242d29be254ec52c2d2e2
// 之后就可以使用这个音乐ID去请求处理结果了,具体接口文档请参考开放平台文档
System.out.println("上传成功,音乐ID: " + musicId);
}
}
Groovy
// 需要的依赖:spring-web(网络请求库,也可以用okHttp,参考java版本写法)
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import groovy.transform.CompileStatic
import org.springframework.core.io.FileSystemResource
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
import org.springframework.util.LinkedMultiValueMap
import org.springframework.web.client.RestTemplate
@CompileStatic
class GDangoDemo2 {
static String APP_KEY = "***"
static String SECRET = "***"
private static String buildToken(String appKey, String secret) {
def timestamp = System.currentTimeMillis()
return appKey + "\$\$" + timestamp + "\$\$" + (secret + timestamp).md5()
}
private static Map postToDango(String url, Map body = null) {
def headers = new HttpHeaders()
headers.add("token", buildToken(APP_KEY, SECRET))
headers.add("Content-Type", "application/json")
def entity = new HttpEntity(JsonOutput.toJson(body ?: []), headers)
def response = new RestTemplate().postForObject(url, entity, String)
return new JsonSlurper().parseText(response as String) as Map
}
static String uploadToDango(String filePath) {
// 1. 创建通道
def channelResponse = postToDango("https://api.tuanziai.com/vocal-remover/upload/channel", [
"uploadVersion": 2,
"style": 29,
"filename": "test.mp3",
"config": [
"separateBackingVocals": false
]
]).data as Map
// 2. 上传文件
def uploadOSSBody = new LinkedMultiValueMap()
for(def entry : (channelResponse.form as Map).entrySet())
uploadOSSBody.add(entry.key, entry.value)
uploadOSSBody.add("file", new FileSystemResource(filePath))
new RestTemplate().postForObject(channelResponse.url as String, new HttpEntity(uploadOSSBody, new HttpHeaders()), String)
// 3. 获取结果(返回纯字符串)
String musicId = postToDango("https://api.tuanziai.com/vocal-remover/upload/${channelResponse.channel}/result").data as String
return musicId
}
static void main(String[] args) {
def musicId = uploadToDango("d:\\test\\real.wav")
// 输出为:
// 上传成功,音乐ID: f81be254ec5242d29be254ec52c2d2e2
// 之后就可以使用这个音乐ID去请求处理结果了,具体接口文档请参考开放平台文档
println("上传成功,音乐ID: " + musicId)
}
}
Python
# 需要的依赖:requests
import requests
import hashlib
import time
import os
APP_KEY = '***'
SECRET = '***'
def compute_token(app_key, secret):
timestamp = int(time.time() * 1000)
return f"{app_key}$${timestamp}$${hashlib.md5((secret + str(timestamp)).encode()).hexdigest()}"
def post_to_dango(url, body=None):
headers = {
'token': compute_token(APP_KEY, SECRET),
'Content-Type': 'application/json'
}
resp = requests.post(url, json=body, headers=headers)
resp.raise_for_status()
data = resp.json()['data']
return data
def upload_to_dango(file_path):
# 第一步:创建上传通道
channel_data = post_to_dango('https://api.tuanziai.com/vocal-remover/upload/channel', {
"uploadVersion": 2,
"style": 29,
"filename": os.path.basename(file_path), # 使用实际文件名
"config": {
"separateBackingVocals": False
}
})
url = channel_data['url']
form = channel_data['form']
channel = channel_data['channel']
# 第二步:使用返回的url和form字段上传文件到OSS
with open(file_path, 'rb') as f:
upload_resp = requests.post(url, data=form, files={'file': (os.path.basename(file_path), f, 'audio/wav')})
upload_resp.raise_for_status()
# 第三步:通知团子上传完成,等待处理结果
music_id = post_to_dango(f'https://api.tuanziai.com/vocal-remover/upload/{channel}/result')
return music_id
if __name__ == '__main__':
music_id = upload_to_dango('d:\\test\\real.wav')
# 输出为:
# 上传成功,音乐ID: f81be254ec5242d29be254ec52c2d2e2
print('上传成功,音乐ID:', music_id)