1
+ < ?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> < html xmlns ="http://www.w3.org/1999/xhtml "> < head > < meta http-equiv ="Content-Type " content ="text/html; charset=UTF-8 " /> < title > 27.2. 阿里云</ title > < link rel ="stylesheet " type ="text/css " href ="docbook.css " /> < meta name ="generator " content ="DocBook XSL Stylesheets Vsnapshot " /> < meta name ="keywords " content ="Android, Google Play " /> < link rel ="home " href ="index.html " title ="Netkiller Android 手札 " /> < link rel ="up " href ="cloud.html " title ="第 27 章 云服务 " /> < link rel ="prev " href ="cloud.html " title ="第 27 章 云服务 " /> </ head > < body > < a xmlns ="" href ="//www.netkiller.cn/ "> Home</ a > | < a xmlns ="" href ="//netkiller.github.io/ "> 简体中文</ a > | < a xmlns ="" href ="http://netkiller.sourceforge.net/ "> 繁体中文</ a > | < a xmlns ="" href ="/journal/index.html "> 杂文</ a >
3
+ | < a xmlns ="" href ="https://github.com/netkiller "> Github</ a > | < a xmlns ="" href ="https://zhuanlan.zhihu.com/netkiller "> 知乎专栏</ a > | < a xmlns ="" href ="https://www.facebook.com/bg7nyt "> Facebook</ a > | < a xmlns ="" href ="http://cn.linkedin.com/in/netkiller/ "> Linkedin</ a > | < a xmlns ="" href ="https://www.youtube.com/user/bg7nyt/videos "> Youtube</ a > | < a xmlns ="" href ="//www.netkiller.cn/home/donations.html "> 打赏(Donations)</ a > | < a xmlns ="" href ="//www.netkiller.cn/home/about.html "> About</ a > < div class ="navheader "> < table width ="100% " summary ="Navigation header "> < tr > < th colspan ="3 " align ="center "> 27.2. 阿里云</ th > </ tr > < tr > < td width ="20% " align ="left "> < a accesskey ="p " href ="cloud.html "> 上一页</ a > </ td > < th width ="60% " align ="center "> 第 27 章 云服务</ th > < td width ="20% " align ="right "> </ td > </ tr > </ table > < hr /> </ div > < table xmlns =""> < tr > < td > < iframe src ="//ghbtns.com/github-btn.html?user=netkiller&repo=netkiller.github.io&type=watch&count=true&size=large " height ="30 " width ="170 " frameborder ="0 " scrolling ="0 " style ="width:170px; height: 30px; " allowTransparency ="true "> </ iframe > </ td > < td > < iframe src ="//ghbtns.com/github-btn.html?user=netkiller&repo=netkiller.github.io&type=fork&count=true&size=large " height ="30 " width ="170 " frameborder ="0 " scrolling ="0 " style ="width:170px; height: 30px; " allowTransparency ="true "> </ iframe > </ td > < td > < iframe src ="//ghbtns.com/github-btn.html?user=netkiller&type=follow&count=true&size=large " height ="30 " width ="240 " frameborder ="0 " scrolling ="0 " style ="width:240px; height: 30px; " allowTransparency ="true "> </ iframe > </ td > < td > </ td > < td > < a href ="https://zhuanlan.zhihu.com/netkiller "> < img src ="/images/logo/zhihu-card-default.svg " height ="25 " /> </ a > </ td > < td valign ="middle "> < a href ="https://zhuanlan.zhihu.com/netkiller "> 知乎专栏</ a > </ td > < td > </ td > < td > </ td > < td > </ td > < td > </ td > </ tr > </ table > < div class ="section "> < div class ="titlepage "> < div > < div > < h2 class ="title " style ="clear: both "> < a id ="aliyun "> </ a > 27.2. 阿里云</ h2 > </ div > </ div > </ div >
4
+
5
+ < div class ="section "> < div class ="titlepage "> < div > < div > < h3 class ="title "> < a id ="id962 "> </ a > 27.2.1. CosyVoice 语音合成</ h3 > </ div > </ div > </ div >
6
+
7
+ < pre class ="programlisting ">
8
+
9
+ package cn.netkiller.conference.ai.aliyun;
10
+
11
+ import android.media.AudioFormat;
12
+ import android.media.AudioManager;
13
+ import android.media.AudioTrack;
14
+
15
+ import com.alibaba.dashscope.audio.tts.SpeechSynthesisResult;
16
+ import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;
17
+ import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;
18
+ import com.alibaba.dashscope.common.ResultCallback;
19
+
20
+ import java.io.FileNotFoundException;
21
+ import java.util.concurrent.CountDownLatch;
22
+
23
+ import cn.aigcsst.conference.ai.aigc.AigcSpeechSynthesizer;
24
+
25
+ public class AliyunCosyVoiceSpeechSynthesizer implements AigcSpeechSynthesizer {
26
+ private static final String TAG = AliyunCosyVoiceSpeechSynthesizer.class.getSimpleName();
27
+
28
+ int sampleRate = 44100;
29
+ int channelConfig = AudioFormat.CHANNEL_OUT_MONO;
30
+ int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
31
+
32
+ int buffersize = AudioTrack.getMinBufferSize(16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_MP3);
33
+ private final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, AudioFormat.CHANNEL_OUT_MONO,
34
+ AudioFormat.ENCODING_MP3, buffersize, AudioTrack.MODE_STREAM);
35
+
36
+ public synchronized void playTrack(byte[] buffer) {
37
+ if (audioTrack != null && audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
38
+ audioTrack.write(buffer, 0, buffer.length);
39
+ }
40
+ }
41
+
42
+ @Override
43
+ public void stopSpeechRecognizer() {
44
+
45
+ }
46
+
47
+ @Override
48
+ public void startSpeechRecognizer() throws FileNotFoundException {
49
+
50
+
51
+ String textToSynthesize = "想不到时间过得这么快!昨天和你视频聊天,看到你那自豪又满意的笑容,我的心里呀,就如同喝了一瓶蜜一样甜呢!真心为你开心呢!";
52
+
53
+ SpeechSynthesisParam param =
54
+ SpeechSynthesisParam.builder()
55
+ .model("cosyvoice-v1")
56
+ .voice("loongstella")
57
+ .apiKey("sk-56c7bc69e1c2407b9244e0895f603afe")
58
+ .build();
59
+ System.out.println("init params done");
60
+
61
+ // Start the player
62
+ audioTrack.play();
63
+
64
+ class ReactCallback extends ResultCallback<SpeechSynthesisResult> {
65
+ public final CountDownLatch latch = new CountDownLatch(1);
66
+ // final File file = new File("result.mp3");
67
+ // final FileOutputStream fos = new FileOutputStream(file);
68
+
69
+ ReactCallback() throws FileNotFoundException {
70
+ }
71
+
72
+ @Override
73
+ public void onEvent(SpeechSynthesisResult message) {
74
+ // Write Audio to player
75
+ if (message.getAudioFrame() != null) {
76
+ // audioPlayer.write(message.getAudioFrame());
77
+ // fos.write(message.getAudioFrame().array());
78
+ playTrack(message.getAudioFrame().array());
79
+ }
80
+ }
81
+
82
+ @Override
83
+ public void onComplete() {
84
+ audioTrack.stop();
85
+ audioTrack.release();
86
+ System.out.println("synthesis onComplete!");
87
+ latch.countDown();
88
+ }
89
+
90
+ @Override
91
+ public void onError(Exception e) {
92
+ System.out.println("synthesis onError!");
93
+ e.printStackTrace();
94
+ }
95
+
96
+ public void waitForComplete() throws InterruptedException {
97
+ latch.await();
98
+ }
99
+ }
100
+ // Create a speech synthesizer
101
+ ReactCallback callback = new ReactCallback();
102
+ SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, callback);
103
+
104
+ // Start the synthesizer with Text
105
+ System.out.printf("start synthesizer : %s \n", textToSynthesize);
106
+ synthesizer.call(textToSynthesize);
107
+ try {
108
+ callback.waitForComplete();
109
+ } catch (InterruptedException e) {
110
+ throw new RuntimeException(e);
111
+ }
112
+ System.out.println("[Metric] requestId: " + synthesizer.getLastRequestId() + ", first package delay ms: " + synthesizer.getFirstPackageDelay());
113
+ }
114
+
115
+ @Override
116
+ public void say(String text) {
117
+
118
+ }
119
+ }
120
+
121
+
122
+ </ pre >
123
+ </ div >
124
+ </ div > < script xmlns ="" type ="text/javascript " id ="clustrmaps " src ="//cdn.clustrmaps.com/map_v2.js?u=r5HG&d=9mi5r_kkDC8uxG8HuY3p4-2qgeeVypAK9vMD-2P6BYM "> </ script > < div class ="navfooter "> < hr /> < table width ="100% " summary ="Navigation footer "> < tr > < td width ="40% " align ="left "> < a accesskey ="p " href ="cloud.html "> 上一页</ a > </ td > < td width ="20% " align ="center "> < a accesskey ="u " href ="cloud.html "> 上一级</ a > </ td > < td width ="40% " align ="right "> </ td > </ tr > < tr > < td width ="40% " align ="left " valign ="top "> 第 27 章 云服务 </ td > < td width ="20% " align ="center "> < a accesskey ="h " href ="index.html "> 起始页</ a > </ td > < td width ="40% " align ="right " valign ="top "> </ td > </ tr > </ table > </ div > < script xmlns ="">
125
+ ( function ( i , s , o , g , r , a , m ) { i [ 'GoogleAnalyticsObject' ] = r ; i [ r ] = i [ r ] || function ( ) {
126
+ ( i [ r ] . q = i [ r ] . q || [ ] ) . push ( arguments ) } , i [ r ] . l = 1 * new Date ( ) ; a = s . createElement ( o ) ,
127
+ m = s . getElementsByTagName ( o ) [ 0 ] ; a . async = 1 ; a . src = g ; m . parentNode . insertBefore ( a , m )
128
+ } ) ( window , document , 'script' , '//www.google-analytics.com/analytics.js' , 'ga' ) ;
129
+
130
+ ga ( 'create' , 'UA-11694057-1' , 'auto' ) ;
131
+ ga ( 'send' , 'pageview' ) ;
132
+
133
+ </ script > < script xmlns ="" async ="async ">
134
+ var _hmt = _hmt || [ ] ;
135
+ ( function ( ) {
136
+ var hm = document . createElement ( "script" ) ;
137
+ hm . src = "https://hm.baidu.com/hm.js?93967759a51cda79e49bf4e34d0b0f2c" ;
138
+ var s = document . getElementsByTagName ( "script" ) [ 0 ] ;
139
+ s . parentNode . insertBefore ( hm , s ) ;
140
+ } ) ( ) ;
141
+ </ script > < script xmlns ="" async ="async ">
142
+ ( function ( ) {
143
+ var bp = document . createElement ( 'script' ) ;
144
+ var curProtocol = window . location . protocol . split ( ':' ) [ 0 ] ;
145
+ if ( curProtocol === 'https' ) {
146
+ bp . src = 'https://zz.bdstatic.com/linksubmit/push.js' ;
147
+ }
148
+ else {
149
+ bp . src = 'http://push.zhanzhang.baidu.com/push.js' ;
150
+ }
151
+ var s = document . getElementsByTagName ( "script" ) [ 0 ] ;
152
+ s . parentNode . insertBefore ( bp , s ) ;
153
+ } ) ( ) ;
154
+ </ script > </ body > </ html >
0 commit comments