implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.code.gson:gson:2.10'
implementation 'com.github.bumptech.glide:glide:4.0.0-RC1'
-
+ implementation 'com.github.xfans:VoiceWaveView:1.0.2'//音频动效
// implementation "org.java-websocket:Java-WebSocket:1.5.1"
implementation 'com.arthenica:mobile-ffmpeg-full:4.4'
// implementation 'com.squareup.okhttp3:okhttp:4.9.1'
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
- android:theme="@style/Theme.PolymerizeSdk"
+ android:theme="@style/AppTheme.NoActionBar"
android:usesCleartextTraffic="true"
tools:targetApi="31">
+ <activity
+ android:name=".DoubaoMainActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
<activity
android:name=".VoiceChatActivity"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
- <intent-filter>
+ <!--<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
+ </intent-filter>-->
</activity>
</application>
package com.zhixun.android.sdk.polymerizesdk;
+
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
-import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import androidx.annotation.NonNull;
-import com.zhixun.android.sdk.polysdk.authentication.AuthMsgSendHandler;
+import com.zhixun.android.sdk.polysdk.util.SobLog;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
public class AudioPlayer {
private AudioTrack audioTrack;
private int bufferSize;
private final int MSG_PLAY = 101;
+ private final int MSG_PLAY_OVER = 102;
private String TAG = "AudioPlayer";
private List<byte[]> playList = new ArrayList<>();
+ private boolean isPlaying = false;
private Handler audioHandler;
- private AudioLooperThread audioLooperThread;
- class AudioLooperThread extends Thread {
+ private Queue<byte[]> queueMsg = new ConcurrentLinkedQueue<byte[]>();//线程安全到队列
+ private class AudioLooperThread extends Thread {
+
+ @Override
public void run() {
+ super.run();
Looper.prepare();
- audioHandler = new Handler(){
+ audioHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
- switch (msg.what){
+ switch (msg.what) {
case MSG_PLAY:
- Log.i(TAG,"play---111---");
- byte[] data = (byte[]) msg.obj;
+ isPlaying = true;
+ audioHandler.removeMessages(MSG_PLAY_OVER);
+ Log.i(TAG, "play---111---");
+ byte[] data = queueMsg.poll();
+ if(data==null){
+ audioHandler.sendEmptyMessageDelayed(MSG_PLAY_OVER, 1000);
+ return;
+ }
if (audioTrack != null) {
audioTrack.play();
int length = data.length;
- while (length > 0&&audioTrack != null) {
- int written = audioTrack.write(data, 0, length);
- length -= written;
+ while (length > 0 && audioTrack != null&&isPlaying) {
+ try {
+ int written = audioTrack.write(data, 0, length);
+ length -= written;
+ } catch (Exception e) {
+ Log.e(TAG, "play---Exception---" + e.getMessage());
+ }
+
}
- Log.i(TAG,"play---end---");
+ Log.i(TAG, "play---end---");
+ }
+ if(isPlaying){
+ audioHandler.sendEmptyMessage(MSG_PLAY);
+ }
+ break;
+ case MSG_PLAY_OVER:
+ isPlaying = false;
+ if (audioPlayStateChangeListener != null) {
+ audioPlayStateChangeListener.onStateChange(isPlaying);
}
-
break;
}
}
};
Looper.loop();
-
}
+
+
}
public AudioPlayer(int sampleRate, int channelConfig, int audioFormat) {
sampleRate, channelConfig, audioFormat, bufferSize, AudioTrack.MODE_STREAM);
}
+ private AudioLooperThread audioLooperThread;
+
public AudioPlayer() {
- audioLooperThread = new AudioLooperThread();
- audioLooperThread.start();
+ init();
+ }
+
+ private void init() {
int sampleRate = 16000;
int channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
- int audioFormat = AudioFormat.ENCODING_PCM_8BIT;
+ int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
// 初始化buffer size
bufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat);
// 初始化AudioTrack
AudioFormat.ENCODING_PCM_16BIT,
bufferSize,
AudioTrack.MODE_STREAM);
+
audioTrack.setPositionNotificationPeriod(bufferSize);
- audioTrack.setPlaybackPositionUpdateListener(new AudioTrack.OnPlaybackPositionUpdateListener() {
- @Override
- public void onMarkerReached(AudioTrack track) {
- //播放完成
- Log.i(TAG,"onMarkerReached");
- }
+ audioLooperThread = new AudioLooperThread();
+ audioLooperThread.start();
- @Override
- public void onPeriodicNotification(AudioTrack track) {
- }
- });
+// AudioManager mAm = ( AudioManager ) context.getSystemService(Context.AUDIO_SERVICE);
+// mAm.setMode(AudioManager.MODE_IN_CALL);
+// mAm.setBluetoothScoOn(true);
+// mAm.startBluetoothSco();
+ }
+
+ public boolean isPlaying() {
+ return isPlaying;
+ }
+
+ public void setPlaying(boolean playing) {
+ isPlaying = playing;
}
private byte[] cacheAudio = new byte[0];
- public synchronized void play(byte[] audioData) {
- Log.i(TAG,"play---"+cacheAudio.length);
-// if(cacheAudio.length<40*1024){
-// cacheAudio = ByteTools.concatAll(cacheAudio,audioData);
-// }else {
- Message message = new Message();
- message.what = MSG_PLAY;
- message.obj = audioData;
- audioHandler.sendMessage(message);
- cacheAudio = new byte[0];
-// }
+ public synchronized void play(byte[] audioData) {
+ if (audioTrack == null) {
+ init();
+ }
+ queueMsg.add(audioData);
+ if (!isPlaying) {
+ isPlaying = true;
+ if (audioPlayStateChangeListener != null) {
+ audioPlayStateChangeListener.onStateChange(isPlaying);
+ }
+ audioHandler.sendEmptyMessage(MSG_PLAY);
+ }
}
+ public synchronized void play(String audioPath) {
+ if (audioTrack == null) {
+ init();
+ }
+ SobLog.d(TAG,"play--"+audioPath);
+ try {
+ InputStream inputStream = new FileInputStream(audioPath);
+ BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
+ byte[] data = new byte[inputStream.available()];
+ bufferedInputStream.read(data);
+ inputStream.close();
+ bufferedInputStream.close();
+ queueMsg.add(data);
+ // do something with the data
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ SobLog.d(TAG,"play--"+isPlaying);
+ if (!isPlaying) {
+ isPlaying = true;
+ if (audioPlayStateChangeListener != null) {
+ audioPlayStateChangeListener.onStateChange(isPlaying);
+ }
+
+ audioHandler.sendEmptyMessage(MSG_PLAY);
+ }
+ }
public void stop() {
+ if(!isPlaying)return;
+ isPlaying = false;
if (audioTrack != null) {
audioTrack.stop();
audioTrack.release();
audioTrack = null;
}
+ audioHandler.removeMessages(MSG_PLAY);
+ audioHandler.removeMessages(MSG_PLAY_OVER);
+ SobLog.d(TAG,"stop--");
+
+ queueMsg.clear();
+ if (audioPlayStateChangeListener != null) {
+ audioPlayStateChangeListener.onStateChange(isPlaying);
+ }
+
}
+ private AudioPlayStateChangeListener audioPlayStateChangeListener;
+
+
+ public void setAudioPlayStateChangeListener(AudioPlayStateChangeListener audioPlayStateChangeListener) {
+ this.audioPlayStateChangeListener = audioPlayStateChangeListener;
+ }
+
+ public interface AudioPlayStateChangeListener {
+ void onStateChange(boolean state);
+ }
}
private AudioRecord audioRecord;
private int bufferSize;
private boolean isRecording = false;
-
+ private Thread audioThread;
private static AudioRecorderMan sInstance;
public static AudioRecorderMan getInstance() {
if (sInstance == null) {
Log.d(TAG,"startRecording--no Permission");
return ;
}
- audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
+ audioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION,
sampleRate, channelConfig, audioFormat, bufferSize);
if (audioRecord != null) {
isRecording = true;
Log.d(TAG,"startRecording--");
- new Thread(() -> {
- audioRecord.startRecording();
- byte[] buffer = new byte[bufferSize];
- int read = 0;
- while (read>=0) {
- read = audioRecord.read(buffer, 0, bufferSize);
- Log.d(TAG,"startRecording--"+read);
- if (read < 0) {
- // 处理错误
- } else {
- // 处理buffer中的数据,这里你可以将它传输或者保存
- if(onBuffChange!=null){
- onBuffChange.onChange(buffer);
- }
+ doRecord();
+ }
+ }
+
+ private void doRecord() {
+ audioThread = new Thread(() -> {
+ audioRecord.startRecording();
+ byte[] buffer = new byte[bufferSize];
+ int read = 0;
+ while (read>=0&&audioRecord!=null) {
+ read = audioRecord.read(buffer, 0, bufferSize);
+ Log.d(TAG,"startRecording--"+read);
+ if (read < 0) {
+ // 处理错误
+ } else {
+ // 处理buffer中的数据,这里你可以将它传输或者保存
+ if(onBuffChange!=null){
+ onBuffChange.onChange(buffer);
}
}
+ }
- }, "AudioRecorderThread").start();
- }
+ }, "AudioRecorderThread");
+ audioThread.start();
}
+
public void stopRecording() {
Log.d(TAG,"stopRecording--");
isRecording = false;
+ if (audioThread != null) {
+ audioThread.interrupt();
+ audioThread = null;
+ }
+
if (audioRecord != null) {
audioRecord.stop();
audioRecord.release();
+ audioRecord = null;
}
}
--- /dev/null
+package com.zhixun.android.sdk.polymerizesdk;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import android.graphics.Color;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.VideoView;
+
+import com.zhixun.android.sdk.polymerizesdk.adapter.AiMsgAdapter;
+import com.zhixun.android.sdk.polymerizesdk.adapter.VcData;
+import com.zhixun.android.sdk.polysdk.PolymerizeAgent;
+import com.zhixun.android.sdk.polysdk.ai.VoiceChatManager;
+import com.zhixun.android.sdk.polysdk.callback.AuthCallback;
+import com.zhixun.android.sdk.polysdk.callback.IVoiceChatCallback;
+import com.zhixun.android.sdk.polysdk.callback.OnTranscriptionDataChange;
+import com.zhixun.android.sdk.polysdk.util.SobLog;
+import com.zhixun.android.sdk.polysdk.util.SpUtils;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import me.xfans.lib.voicewaveview.VoiceWaveView;
+import me.xfans.lib.voicewaveview.WaveMode;
+
+public class DoubaoMainActivity extends AppCompatActivity {
+
+
+ private String TAG = "DoubaoMainActivity";
+ private VideoView bq_video;
+ private TextView tv_state,tv_event;
+ private ImageView startBtn;
+ private AudioPlayer player = new AudioPlayer();
+ private boolean isStartTranscrip;
+// private final int MSG_DO_TTS = 101;
+ private AiMsgAdapter aiMsgAdapter;
+ private RecyclerView msg_listview;
+ private VoiceWaveView voiceWaveView;
+ private LinearLayout layout_msg;
+ private int msgPosition=-1,chatPosition = -1;
+ private String responsStr = "";
+ private String asrStr = "";
+ private boolean shwoList = false;
+ private long downTime = 0;
+ private Handler handler = new Handler(Looper.getMainLooper()){
+ @Override
+ public void handleMessage(@NonNull Message msg) {
+ super.handleMessage(msg);
+ switch (msg.what){
+
+ case 102:
+ if(isFirst){
+ String uri="android.resource://"+getPackageName()+"/"+R.raw.zhayan;
+ bq_video.setOnPreparedListener(null);
+ bq_video.destroyDrawingCache();
+ bq_video.suspend();
+ playVideo(uri);
+ handler.sendEmptyMessageDelayed(106,1000);
+ }
+ break;
+ case 103:
+ Log.i(TAG,"onRspons--103");
+ responsStr = "";
+ chatPosition = aiMsgAdapter.addData(new VcData(1,responsStr));
+ msg_listview.scrollToPosition(chatPosition);
+ break;
+ case 104:
+ Log.i(TAG,"onRspons--104");
+ chatPosition = -1;
+ responsStr = "";
+ break;
+ case 105:
+
+ String text = (String) msg.obj;
+ if(TextUtils.isEmpty(text))return;
+ Log.i(TAG,"onRspons--105"+text);
+ responsStr = responsStr+text;
+ if(chatPosition==-1){
+ chatPosition = aiMsgAdapter.addData(new VcData(1,responsStr));
+ }else {
+ aiMsgAdapter.setData(chatPosition,new VcData(1,responsStr));
+ }
+ aiMsgAdapter.notifyItemChanged(chatPosition);
+ tv_event.setText(responsStr);
+ break;
+ case 106:
+ tv_event.setVisibility(View.VISIBLE);
+ break;
+ }
+ }
+ };
+
+ private boolean isFirst = true;
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_doubao_main);
+ bq_video = findViewById(R.id.bq_video);
+ tv_state = findViewById(R.id.tv_state);
+ startBtn = findViewById(R.id.startBtn);
+ msg_listview = findViewById(R.id.msg_listview);
+ voiceWaveView = findViewById(R.id.voiceWaveView);
+ tv_event = findViewById(R.id.tv_event);
+ String uri="android.resource://"+getPackageName()+"/"+R.raw.delfult;
+
+ playVideo(uri);
+ PolymerizeAgent.getInstance().getAuthenAPI().setAIChannelKey("huoshan","",null);
+ goLogin();
+
+ startBtn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ player.stop();
+ String uri="android.resource://"+getPackageName()+"/"+R.raw.lisening;
+ if(isStartTranscrip){
+ isStartTranscrip = false;
+ AudioRecorderMan.getInstance().stopRecording();
+ PolymerizeAgent.getInstance().getAiAPI().stopTrans();
+ uri="android.resource://"+getPackageName()+"/"+R.raw.thinking;
+ voiceWaveView.stop();
+ }else {
+ isStartTranscrip = true;
+// PolymerizeAgent.getInstance().getAiAPI().cancleChat();
+ VoiceChatManager.getInstance().cancleChat();
+ PolymerizeAgent.getInstance().getAiAPI().startTrans();
+ uri="android.resource://"+getPackageName()+"/"+R.raw.lisening;
+ tv_state.setText("点击或停止说话发送");
+ voiceWaveView.start();
+ }
+ playVideo(uri);
+
+ }
+ });
+ AudioRecorderMan.getInstance().setOnBuffChange(new AudioRecorderMan.onBuffChange() {
+ @Override
+ public void onChange(byte[] data) {
+ Log.i(TAG,"Audio-onChange-"+isStartTranscrip);
+ if(isStartTranscrip){
+ Log.i(TAG,"Audio-onChange-"+data.length);
+ PolymerizeAgent.getInstance().getAiAPI().sendTransByte(data);
+// VoiceChatManager.getInstance().sendVoice(data);
+ }
+ }
+ });
+
+ PolymerizeAgent.getInstance().getAiAPI().setOnTranscriptionDataChange(new OnTranscriptionDataChange() {
+ @Override
+ public void onStartChange(int action,boolean state) {
+ if(state){
+ AudioRecorderMan.getInstance().startRecording(DoubaoMainActivity.this);
+ }
+ }
+
+ @Override
+ public void onChange(String state,String text) {
+ Log.i(TAG,"Transcription-onChange-"+state+"--"+text);
+ if(state.equals("end")){
+ PolymerizeAgent.getInstance().getAiAPI().sendChatMsg(text);
+ }
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if(state.equals("start")){
+ asrStr = "";
+ msgPosition = aiMsgAdapter.addData(new VcData(0,text));
+ tv_state.setText("点击结束说话");
+ }
+ else if(state.equals("SentenceEnd")||state.equals("end")){
+ asrStr = text;
+ tv_event.setText(asrStr);
+ if(msgPosition==-1){
+ msgPosition = aiMsgAdapter.addData(new VcData(0,asrStr));
+ }else {
+ aiMsgAdapter.setData(msgPosition,new VcData(0,asrStr));
+ }
+ }
+
+ aiMsgAdapter.notifyItemChanged(msgPosition);
+ msg_listview.scrollToPosition(msgPosition);
+ if(state.equals("end")){
+ msgPosition = -1;
+ asrStr = "";
+ }
+ }
+ });
+ }
+ });
+
+ PolymerizeAgent.getInstance().getAiAPI().setOnVoiceChatListener(new IVoiceChatCallback() {
+ @Override
+ public void OnSpeech(byte[] data) {
+ player.play(data);
+ }
+
+ @Override
+ public void OnRespond(String type, String text) {
+ Log.d(TAG,"OnRespond--"+type);
+ doRespons(type,text);
+ }
+ });
+
+ player.setAudioPlayStateChangeListener(new AudioPlayer.AudioPlayStateChangeListener() {
+ @Override
+ public void onStateChange(boolean state) {
+ if(isFirst&&!state){
+ isFirst = false;
+ return;
+ }
+ if(isFirst)return;
+ Log.d(TAG,"setAudioPlayStateChangeListener--"+state);
+
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ String uri="android.resource://"+getPackageName()+"/"+R.raw.speek;
+
+ if(state){
+ uri="android.resource://"+getPackageName()+"/"+R.raw.speek;
+ tv_state.setText("点击打断");
+ }else {
+ uri="android.resource://"+getPackageName()+"/"+R.raw.zhayan;
+ tv_state.setText("点击对话");
+// tv_event.setText("再聊点啥呢...");
+ }
+ playVideo(uri);
+ }
+ });
+ }
+ });
+
+ LinearLayoutManager layoutManager = new LinearLayoutManager(this);
+ msg_listview.setLayoutManager(layoutManager);
+ aiMsgAdapter = new AiMsgAdapter(this, new ArrayList<>());
+ msg_listview.setAdapter(aiMsgAdapter);
+ msg_listview.getItemAnimator().setChangeDuration(0);// 通过设置动画执行时间为0来解决闪烁问题
+
+
+
+ msg_listview.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ Log.d(TAG,"layout_msg--"+event.getAction());
+ switch (event.getAction()){
+ case MotionEvent.ACTION_DOWN:
+ downTime = System.currentTimeMillis();
+ break;
+ case MotionEvent.ACTION_UP:
+ long time = System.currentTimeMillis()-downTime;
+ if(time<200){
+ msg_listview.setVisibility(View.GONE);
+ bq_video.setVisibility(View.VISIBLE);
+ }
+ break;
+ }
+ return false;
+ }
+ });
+
+ bq_video.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ msg_listview.setVisibility(View.VISIBLE);
+ msg_listview.setFocusable(true);
+ bq_video.setVisibility(View.GONE);
+ }
+ });
+
+ voiceWaveView.setShowGravity(Gravity.CENTER);
+ voiceWaveView.setWaveMode(WaveMode.LEFT_RIGHT);
+ voiceWaveView.setLineWidth(3f);
+ voiceWaveView.setLineSpace(5f);
+ voiceWaveView.setLineColor(Color.parseColor("#ffffff"));
+ voiceWaveView.setDuration(100);
+// voiceWaveView.addHeader(4);
+ voiceWaveView.addHeader(4);
+ voiceWaveView.addBody(16);
+ voiceWaveView.addBody(26);
+ voiceWaveView.addBody(46);
+ voiceWaveView.addBody(26);
+ voiceWaveView.addBody(16);
+// voiceWaveView.addBody(60);
+// voiceWaveView.addBody(38);
+// voiceWaveView.addBody(14);
+// voiceWaveView.addBody(8);
+ voiceWaveView.addFooter(4);
+// voiceWaveView.addFooter(2);
+ player.play(readFile());
+
+ }
+
+ private String pwd = "RTQYOiB3zLAz5AeJSGnEPXea4qPfTY";
+ public void goLogin(){
+ pwd = SpUtils.getInstance().getStringValue("devicePwd");
+ PolymerizeAgent.getInstance().getAuthenAPI().authentication("281106010111"
+ , pwd, "4EepovakpbqhZUnUDwH42KAADYGv4UUe", new AuthCallback() {
+ @Override
+ public void onSuccess(String result) {
+ Log.i(TAG,"result--"+result);
+ }
+
+ @Override
+ public void onFail(int code,String msg) {
+ Log.i(TAG,"onFail--"+msg+"code-"+code);
+ goRegiest();
+ }
+ });
+
+ }
+
+ public void goRegiest(){
+ PolymerizeAgent.getInstance().getAuthenAPI().regiest("4EepovakpbqhZUnUDwH42KAADYGv4UUe"
+ , "281106010111", "Y1DxRdBfnzVZQrXHdrNl", new AuthCallback() {
+ @Override
+ public void onSuccess(String result) {
+ Log.i(TAG,"result--"+result);
+ pwd = result;
+ SpUtils.getInstance().saveValue("devicePwd",pwd);
+ goLogin();
+ }
+
+ @Override
+ public void onFail(int code,String msg) {
+ Log.i(TAG,"onFail--"+msg+"code-"+code);
+ }
+ });
+
+
+
+ /*ChatGPTClient.getInstance().checkAIKey("sk-proj-04ogvrZQqyaiv1OWw8OZT3BlbkFJG9Gyr8oFvRdmr3oXQNbX", new IOnKeyCheckCallback() {
+ @Override
+ public void OnKeyCheckResult(boolean result) {
+ Log.d(TAG,"result--"+result);
+ }
+ });*/
+ }
+
+
+ private void playVideo(String path){
+ bq_video.setVideoURI(Uri.parse(path));
+ bq_video.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
+ @Override
+ public void onPrepared(MediaPlayer mediaPlayer) {
+ Log.i(TAG, "init_vieofile:..main_video1...视频准备完毕,可以进行播放....." + mediaPlayer.isPlaying());
+ mediaPlayer.setVolume(0f, 0f);
+ if (!mediaPlayer.isPlaying()) {
+ mediaPlayer.start();
+ }
+ Log.i(TAG, "isFirst....." + isFirst);
+ if(!isFirst){
+ mediaPlayer.setLooping(true);
+ }
+
+
+ }
+ });
+ bq_video.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+ @Override
+ public void onCompletion(MediaPlayer mp) {
+ //结束播放
+ handler.sendEmptyMessage(102);
+ }
+ });
+
+
+ }
+
+ private void doRespons(String state,String text) {
+
+ if(state.equals("start")){
+ handler.sendEmptyMessage(103);
+ }else if(state.equals("end")){
+ handler.sendEmptyMessage(104);
+ }else {
+ Message message = handler.obtainMessage(105);
+ message.obj = text;
+ handler.sendMessage(message);
+ }
+ }
+
+ private byte[] readFile() {
+ try {
+ InputStream in = getAssets().open("first.pcm");
+ byte[] filecontent = new byte[in.available()];
+ in.read(filecontent);
+
+ SobLog.show(TAG, "readFile--" + filecontent.length);
+ in.close();
+ return filecontent;
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ SobLog.show(TAG, "readFile---" + e.getMessage());
+ return null;
+ } catch (IOException e) {
+ e.printStackTrace();
+ SobLog.show(TAG, "readFile---" + e.getMessage());
+ return null;
+ }
+ }
+}
\ No newline at end of file
private void initMedia() {
mediaPlayer = new MediaPlayer();
- mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
- mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
- @Override
- public void onCompletion(MediaPlayer mp) {
- Log.d(TAG,"play over");
- if (sourceList.size() > 0) {
- playData(sourceList.get(0));
- sourceList.remove(0);
- }
- }
- });
+ mediaPlayer.setAudioStreamType(AudioManager.STREAM_SYSTEM);
+
}
private List<FileInputStream> sourceList = new ArrayList<>();
new Thread(new Runnable() {
@Override
public void run() {
- if (mediaPlayer.isPlaying()||sourceList.size()>0) {
- try {
- File tempMp3 = File.createTempFile("temp_" + System.currentTimeMillis(), ".mp3");
-// tempMp3.deleteOnExit();
- FileOutputStream fos = new FileOutputStream(tempMp3);
- fos.write(audioSource);
- fos.close();
- FileInputStream fis = new FileInputStream(tempMp3);
- sourceList.add(fis);
- } catch (IOException ex) {
- String s = ex.toString();
- Log.d(TAG, "playData--" + s);
- ex.printStackTrace();
- }
-
- } else {
- try {
- File tempMp3 = File.createTempFile("temp_" + System.currentTimeMillis(), ".mp3");
- tempMp3.deleteOnExit();
- Log.i(TAG,"playData-11-");
- FileOutputStream fos = new FileOutputStream(tempMp3);
- fos.write(audioSource);
- fos.close();
- Log.i(TAG,"playData-22-");
- mediaPlayer.reset();
- FileInputStream fis = new FileInputStream(tempMp3);
- Log.i(TAG,"playData-33-");
- mediaPlayer.setDataSource(fis.getFD());
- mediaPlayer.prepare();
- mediaPlayer.start();
- Log.i(TAG,"playData-44-");
- } catch (IOException ex) {
- String s = ex.toString();
- Log.d(TAG, "playData-1-" + s);
- ex.printStackTrace();
- }
-
+ try {
+ File tempMp3 = File.createTempFile("temp_" + System.currentTimeMillis(), ".m4a");
+ Log.i(TAG,"playData-11-");
+ FileOutputStream fos = new FileOutputStream(tempMp3);
+ fos.write(audioSource);
+ fos.close();
+ Log.i(TAG,"playData-22-");
+ mediaPlayer.reset();
+ FileInputStream fis = new FileInputStream(tempMp3);
+ Log.i(TAG,"playData-33-");
+ mediaPlayer.setDataSource(fis.getFD());
+ mediaPlayer.prepare();
+ mediaPlayer.start();
+// tempMp3.deleteOnExit();
+ Log.i(TAG,"playData-44-");
+ } catch (IOException ex) {
+ String s = ex.toString();
+ Log.d(TAG, "playData-1-" + s);
+ ex.printStackTrace();
}
}
}
- public void playData(String path) {
+ public void playData(String path) {
stop();
initMedia();
try {
--- /dev/null
+package com.zhixun.android.sdk.polymerizesdk.adapter;
+
+
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+
+import com.zhixun.android.sdk.polymerizesdk.R;
+
+import java.util.ArrayList;
+
+public class AiMsgAdapter extends RecyclerView.Adapter<AiMsgAdapter.MyViewHoder> {
+
+ private ArrayList<VcData> msgList ;
+ private Context mContext;
+ public AiMsgAdapter(Context context, ArrayList<VcData> msgList) {
+ this.mContext = context;
+ this.msgList = msgList;
+ }
+
+ @NonNull
+ @Override
+ public MyViewHoder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = View.inflate(mContext, R.layout.layout_item_ai_msg, null);
+ MyViewHoder myViewHoder = new MyViewHoder(view);
+ return myViewHoder;
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull MyViewHoder holder, int position) {
+
+ VcData vcData = msgList.get(position);
+ String msg = vcData.getMsg();
+ if(vcData.getType()==0){
+ //问
+ holder.tvMsg.setVisibility(View.GONE);
+ holder.tvInput.setVisibility(View.VISIBLE);
+ if(!TextUtils.isEmpty(msg)&&!msg.equals("null")){
+ holder.tvInput.setText(vcData.getMsg());
+ }else {
+ holder.tvInput.setText("");
+ }
+
+ }else {
+ //回复
+ holder.tvMsg.setVisibility(View.VISIBLE);
+ holder.tvInput.setVisibility(View.GONE);
+ if(!TextUtils.isEmpty(msg)&&!msg.equals("null")){
+ holder.tvMsg.setText(vcData.getMsg());
+ }else {
+ holder.tvMsg.setText("");
+ }
+ }
+
+
+ }
+
+ @Override
+ public int getItemCount() {
+ return msgList.size();
+ }
+
+
+ private void addData(ArrayList<VcData> data){
+ msgList.addAll(data);
+ notifyDataSetChanged();
+ }
+
+ public int addData(VcData data){
+ msgList.add(data);
+ notifyDataSetChanged();
+ return msgList.size()-1;
+ }
+
+ public void setData(int position,VcData data){
+ msgList.set(position,data);
+// notifyItemChanged(position);
+ }
+
+ public ArrayList<VcData> getMsgList() {
+ return msgList;
+ }
+
+ public class MyViewHoder extends RecyclerView.ViewHolder {
+ TextView tvMsg,tvInput;
+
+ public MyViewHoder(@NonNull View itemView) {
+ super(itemView);
+ tvMsg = itemView.findViewById(R.id.tv_msg);
+ tvInput = itemView.findViewById(R.id.tv_input);
+
+
+
+ }
+
+ }
+
+}
--- /dev/null
+package com.zhixun.android.sdk.polymerizesdk.adapter;
+
+public class VcData {
+ private int type;
+ private String msg;
+
+ public VcData(int type, String msg) {
+ this.type = type;
+ this.msg = msg;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+}
--- /dev/null
+package com.zhixun.android.sdk.polymerizesdk.util;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.VideoView;
+
+
+public class FullScreenVideoView extends VideoView{
+
+
+ public FullScreenVideoView(Context context) {
+ super(context);
+// TODO Auto-generated constructor stub
+ }
+ public FullScreenVideoView(Context context, AttributeSet attrs)
+ {
+ super(context,attrs);
+ }
+ public FullScreenVideoView(Context context, AttributeSet attrs, int defStyle)
+ {
+ super(context,attrs,defStyle);
+ }
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
+ {
+ int width = getDefaultSize(0, widthMeasureSpec);
+ int height = getDefaultSize(0, heightMeasureSpec);
+ setMeasuredDimension(width , height);
+ }
+
+
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<shape android:shape="rectangle"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="#D8D8D8" />
+ <corners android:radius="10.0dip" />
+ <padding android:left="14.0dip" android:top="12.0dip" android:right="14.0dip" android:bottom="12.0dip" />
+</shape>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<shape android:shape="rectangle"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="#1CB1F4" />
+ <corners android:radius="10.0dip" />
+ <padding android:left="14.0dip" android:top="12.0dip" android:right="14.0dip" android:bottom="12.0dip" />
+</shape>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:background="@color/black">
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <RelativeLayout
+ android:id="@+id/layout_video"
+ android:layout_width="match_parent"
+ android:layout_height="160dp"
+ android:orientation="vertical"
+ android:layout_marginTop="30dp">
+
+ <VideoView
+ android:id="@+id/bq_video"
+ android:layout_width="150dp"
+ android:layout_height="140dp"
+ android:layout_centerHorizontal="true"/>
+
+ <TextView
+ android:id="@+id/tv_event"
+ android:layout_width="wrap_content"
+ android:layout_marginRight="20dp"
+ android:layout_marginLeft="20dp"
+ android:maxLines="2"
+ android:ellipsize="end"
+ android:layout_height="wrap_content"
+ android:textSize="12sp"
+ android:textColor="@color/white"
+ android:layout_gravity="center_horizontal"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="95dp"
+
+ android:visibility="gone"
+ android:text="快和我聊天吧"/>
+
+ </RelativeLayout>
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/msg_listview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/black"
+ android:visibility="gone"/>
+
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true">
+
+
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginBottom="5dp">
+ <ImageView
+ android:id="@+id/startBtn"
+ android:layout_width="wrap_content"
+ android:layout_height="45dp"
+ android:layout_centerHorizontal="true"
+ android:src="@mipmap/bg_speek"/>
+ <me.xfans.lib.voicewaveview.VoiceWaveView
+ android:id="@+id/voiceWaveView"
+ android:layout_width="wrap_content"
+ android:layout_height="45dp"
+ app:lineColor="@color/white"
+ app:waveMode="left_right"
+ android:gravity="center"
+ />
+ </RelativeLayout>
+
+
+ <TextView
+ android:id="@+id/tv_state"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="12sp"
+ android:textColor="@color/white"
+ android:layout_marginBottom="15dp"
+ android:layout_gravity="center_horizontal"
+ android:text="点击开始对话"/>
+ </LinearLayout>
+
+
+
+ </RelativeLayout>
+
+
+</LinearLayout>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingTop="15dp"
+ android:animateLayoutChanges="false"
+ android:id="@+id/item_parent">
+
+ <TextView
+ android:id="@+id/tv_msg"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="12sp"
+ android:textColor="@color/black"
+ android:lineSpacingExtra="2dp"
+ android:layout_marginLeft="15dp"
+ android:layout_marginRight="45dp"
+ android:background="@drawable/ai_input_bg_shape"/>
+
+ <TextView
+ android:id="@+id/tv_input"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_marginRight="15dp"
+ android:layout_marginLeft="45dp"
+ android:background="@drawable/ai_msg_bg_shape"
+ android:lineSpacingExtra="2dp"
+ android:textColor="@color/white"
+ android:textSize="12sp" />
+
+</RelativeLayout>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+ <!-- Customize your theme here. -->
+
+ </style>
+
+ <style name="AppTheme.NoActionBar">
+ <item name="windowActionBar">false</item>
+ <item name="windowNoTitle">true</item>
+ <item name="android:windowBackground">@color/black</item>
+ </style>
+
+</resources>
\ No newline at end of file
asrMsg = "";
} else if (reply.getEvent().equals("SentenceEnd") && reply.getStatus() == 20000000) {
asrMsg = asrMsg+reply.getResult().getResult();
-
+ if (onTranscriptionDataChange != null) {
+ onTranscriptionDataChange.onChange("SentenceEnd", asrMsg);
+ }
} else if (reply.getEvent().equals("Changed") && reply.getStatus() == 20000000) {
if (onTranscriptionDataChange != null) {
String msg = reply.getResult().getResult();
package com.zhixun.android.sdk.polysdk.ai;
import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
return sInstance;
}
+ private MsgLooperThread msgLooperThread;
+ private class MsgLooperThread extends Thread {
+ public void run() {
+ Looper.prepare();
+ handler = new Handler(Looper.myLooper()){
+ @Override
+ public void handleMessage(@NonNull Message msg) {
+ super.handleMessage(msg);
+ switch (msg.what){
+ case MSG_RECONNECT:
+ SobLog.d(TAG, "MSG_RECONNECT");
+ if (chatClient != null) {
+ chatClient.close();
+ chatClient = null;
+ }
+ isStart = false;
+ connectChat();
+ break;
+ case MSG_SENDPING:
+// SobLog.d(TAG, "MSG_SENDPING");
+ if(chatClient!=null&&chatClient.isOpen()){
+ chatClient.sendPing();
+ }
+ break;
+ }
+ }
+ };
+ Looper.loop();
+ }
+ }
private final int MSG_RECONNECT = 101;
private final int MSG_SENDPING = 102;
- private Handler handler = new Handler(){
- @Override
- public void handleMessage(@NonNull Message msg) {
- super.handleMessage(msg);
- switch (msg.what){
- case MSG_RECONNECT:
- SobLog.d(TAG, "MSG_RECONNECT");
- if (chatClient != null) {
- chatClient.close();
- chatClient = null;
- }
- isStart = false;
- connectChat();
- break;
- case MSG_SENDPING:
-// SobLog.d(TAG, "MSG_SENDPING");
- if(chatClient!=null&&chatClient.isOpen()){
- chatClient.sendPing();
- }
+ private Handler handler;
- break;
- }
- }
- };
public VoiceChatManager() {
SobLog.d(TAG, "-----VoiceChatManager---creat--");
private String chatType = "";
public void init() {
SobLog.d(TAG, "-----VoiceChatManager---init--");
+ if(msgLooperThread==null){
+ msgLooperThread = new MsgLooperThread();
+ msgLooperThread.start();
+ }
channelMap.put("aliyun","qianwen");
channelMap.put("huoshan","doubao");
channelMap.put("baidu","wenxin");
isReConnect = false;
return;
}
+ SobLog.d(TAG, "channel--" + channel);
String param = "";
if(channelMap.containsKey(channel)){
param = "&bot_type="+channelMap.get(channel);
}
String url = MyConfig.URL_VOICE_CHAT+"?is_auth=0"+"&dt="+MyConfig.TOKEN+"&platform=raisound"+param;
URI chatRri = URI.create(url);
- handler.removeMessages(MSG_RECONNECT);
+ if(handler!=null){
+ handler.removeMessages(MSG_RECONNECT);
+ }else {
+ return;
+ }
+
SobLog.d(TAG, "url--" + url);
chatClient = new JWebSocketClient(chatRri) {
@Override
* 设置通道
*/
public void checkoutChannel(IAIChannelChangeCallback channelChangeCallback) {
+ if(handler==null)return;
this.channelChangeCallback = channelChangeCallback;
-
if (chatClient != null && chatClient.isOpen()) {
ischeckoutChannel = true;
close();
} else {
ischeckoutChannel = false;
isReConnect = true;
+
handler.removeMessages(MSG_RECONNECT);
connectChat();
}
if (iVoiceChatCallback != null) {
iVoiceChatCallback.OnRespond(chatType, "");
}
- if (chatClient != null && chatClient.isOpen()) {
- close();
- }
+ }
+ if (chatClient != null && chatClient.isOpen()) {
+ close();
}
}
google()
mavenCentral()
gradlePluginPortal()
+ maven { url 'https://jitpack.io' }
}
}
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
+ maven { url 'https://jitpack.io' }
}
}