//using MoPhoGames.USpeak.Core;
using System.Collections.Generic;
using Thousandto.Code.Center;
using Thousandto.Core.Asset;
using Thousandto.Core.Base;
using UnityEngine;
namespace Thousandto.Code.Logic
{
///
/// UIEntergameForm的逻辑处理类
///
public partial class ChatSystem
{
public const int MAX_RECORD_DURATION = 15; //最长录音时间
public int VoiceIndex; //接收到的语音序列,从0开始增加
public int LocalVoiceIndex; //本人发送的语音,发送时就计算序列
public MyAction _action; //回调
public MonoBehaviour Coro; //用于启动协程,每次打开聊天窗的时候赋值
private bool _recording; //是否正在录音
private float MinLenght = 1.0f; //最短有效录音
private int _audioLength; //录音时长
private AudioClip _audioClip;
private byte[] _compressedRecordData;
//通常的无损音质的采样率是44100,即每秒音频用44100个float数据表示,但是语音只需8000(通常移动电话是8000)就够了
//不然音频数据太大,不利于传输和存储
public const int SamplingRate = 8000;
public AudioSource ChatAudioSource;
private Dictionary _voiceDataDic = new Dictionary();
private Dictionary _voiceKeyToVoiceData = new Dictionary();
#region 录音操作
public void StartRecord()
{
_audioLength = 0;
_compressedRecordData = null;
_recording = true;
StopPlayingAudio();
SuspendAllSound();
//GameCenter.UniSoundSystem.SuspendSystem();
//按钮按下开始录音
//Microphone.End(null);//这句可以不需要,但是在开始录音以前调用一次是好习惯
//string[] micDevices = Microphone.devices;
//for (int i = 0; micDevices != null && i < micDevices.Length; ++i)
//{
// UnityEngine.Debug.LogError("话筒: " + micDevices[i]);
//}
_audioClip = null;
//_audioClip = Microphone.Start(null, false, MAX_RECORD_DURATION, SamplingRate);
}
//是否正在录音
public bool IsRecording()
{
return _recording;
}
public void EndRecord()
{
/*
//按钮弹起结束录音
int audioLength;//录音的长度,单位为秒,ui上可能需要显示
int lastPos = Microphone.GetPosition(null);
if (Microphone.IsRecording(null))
{
//录音小于10秒
audioLength = lastPos / SamplingRate;//录音时长
}
else
{
audioLength = MAX_RECORD_DURATION;
}
Microphone.End(null);//此时录音结束,clip已可以播放了
ResumeAllSound();
//GameCenter.UniSoundSystem.ResumeSystem();
if (audioLength < MinLenght) return;//录音小于2秒就不处理了
int samples = 0;
_compressedRecordData = null;// USpeakAudioClipCompressor.CompressAudioClip(_audioClip, out samples, BandMode.Narrow);
//_audioClip = null;
_audioLength = audioLength;
_recording = false;
*/
}
public void SuspendAllSound()
{
if (GameCenter.GameSetting.GetSetting(GameSettingKeyCode.EnableBGMusic) != 0)
{
AudioPlayer.SetVolume(AudioTypeCode.Music, 0f);
}
if (GameCenter.GameSetting.GetSetting(GameSettingKeyCode.EnableSound) != 0)
{
AudioPlayer.SetVolume(AudioTypeCode.Sfx, 0f);
AudioPlayer.SetVolume(AudioTypeCode.Ambient, 0f);
AudioPlayer.SetVolume(AudioTypeCode.Speech, 0f);
AudioPlayer.SetVolume(AudioTypeCode.UI, 0f);
}
}
public void ResumeAllSound()
{
if (GameCenter.GameSetting.GetSetting(GameSettingKeyCode.EnableBGMusic) != 0)
{
float v = (float)GameCenter.GameSetting.GetSetting(GameSettingKeyCode.BGMusicVolume)/100f;
AudioPlayer.SetVolume(AudioTypeCode.Music, v);
}
if (GameCenter.GameSetting.GetSetting(GameSettingKeyCode.EnableSound) != 0)
{
float v = (float)GameCenter.GameSetting.GetSetting(GameSettingKeyCode.SoundVolume) / 100f;
AudioPlayer.SetVolume(AudioTypeCode.Sfx, v);
AudioPlayer.SetVolume(AudioTypeCode.Ambient, v);
AudioPlayer.SetVolume(AudioTypeCode.Speech, v);
AudioPlayer.SetVolume(AudioTypeCode.UI, v);
}
}
public void SendRecord(ChatInfo info)
{
if (_recording)
{
EndRecord();
}
LocalVoiceIndex = ++VoiceIndex;
addVoiceDataToCache(LocalVoiceIndex, _compressedRecordData);
string content = byteToString(_compressedRecordData);
MSG_Chat.ChatReqCS req = new MSG_Chat.ChatReqCS();
req.chattype = info.ChatType;
req.recRoleId = info.Receiver;
req.condition = content;
req.voiceLen = _audioLength;
req.chatchannel = info.Channel;
req.Send();
//UnityEngine.Debug.LogError("录音时长:" + _audioLength);
//UnityEngine.Debug.LogError("录音数据长度:" + _compressedRecordData.Length);
}
#endregion
#region 语音播放操作
//是否有语音在播放
public bool IsAudioPlaying()
{
if (ChatAudioSource != null)
{
return ChatAudioSource.isPlaying;
}
return false;
}
//关闭正在播放的语音
public void StopPlayingAudio()
{
if (ChatAudioSource != null && ChatAudioSource.isPlaying)
{
ChatAudioSource.Stop();
}
}
// method
public bool PlayAudio(byte[] data, AudioSource audioSrc)
{
if (audioSrc == null)
{
return false;
}
audioSrc.clip = null;
AudioClip clip = null;// USpeakAudioClipCompressor.DecompressAudioClip(data, 0, 1, false, BandMode.Narrow, 1.0f);
// play test
audioSrc.clip = clip;
audioSrc.Play();
SuspendAllSound();
//GameCenter.UniSoundSystem.SuspendSystem();
return true;
}
#endregion
#region 窗体事件
public void OnFormClose()
{
//关闭窗体时,关闭语音,并且恢复背景声音
if (IsAudioPlaying())
{
StopPlayingAudio();
}
ResumeAllSound();
//GameCenter.UniSoundSystem.ResumeSystem();
}
#endregion
#region 私有功能函数
//添加聊天数据到缓存中保存
private void addVoiceDataToCache(int index, byte[] data)
{
//超30个就remove
if (_voiceDataDic.Count >= 30)
{
var itor = _voiceDataDic.Keys.GetEnumerator();
itor.MoveNext();
int key = itor.Current;
_voiceDataDic.Remove(key);
//在_voiceKeyToVoiceData中去移除对应的key
var itor2 = _voiceKeyToVoiceData.GetEnumerator();
string keyStr = "" + key;
while (itor2.MoveNext())
{
if (itor2.Current.Value == keyStr)
{
_voiceKeyToVoiceData.Remove(itor2.Current.Key);
break;
}
}
}
else
{
if (_voiceDataDic.ContainsKey(index))
{
_voiceDataDic[index] = data;
}
else
_voiceDataDic.Add(index, data);
}
}
private string byteToString(byte[] voiceData)
{
char[] charArray = new char[voiceData.Length];
for (int i = 0; i < voiceData.Length; ++i)
{
charArray[i] = (char)voiceData[i];
}
string str = new string(charArray);
return str;
}
private byte[] stringToBytes(string str)
{
char[] charArray = str.ToCharArray();
byte[] data = new byte[charArray.Length];
for (int i = 0; i < charArray.Length; ++i)
{
data[i] = (byte)charArray[i];
}
return data;
}
#endregion
#region 协议请求
public void ReqVoiceData(string key, MyAction action)
{
_action = action;
if (_voiceKeyToVoiceData.ContainsKey(key))
{
int voiceIndexKey = int.Parse(_voiceKeyToVoiceData[key]);
if (_voiceDataDic.ContainsKey(voiceIndexKey))
{
PlayAudio(_voiceDataDic[voiceIndexKey], ChatAudioSource);
if (_action != null)
_action();
return;
}
}
MSG_Chat.ChatGetContentCS reqVoice = new MSG_Chat.ChatGetContentCS();
reqVoice.key = key;
reqVoice.Send();
}
#endregion
#region 协议返回
public void GS2U_ChatGetContentSC(MSG_Chat.ChatGetContentSC result)
{
byte[] voiceData = stringToBytes(result.voice);
//有保存,重置数据
if (_voiceKeyToVoiceData.ContainsKey(result.voiceKey))
{
int index = int.Parse(_voiceKeyToVoiceData[result.voiceKey]);
addVoiceDataToCache(index, voiceData);
}
PlayAudio(voiceData, ChatAudioSource);
if (_action != null)
_action();
//CoroutinePool.AddTask(playAudioIE(obj, this));
}
public void TestOnChatVoiceReceive(int channel, int voiceID, int length)
{
//Audio: m_param1 = key; m_param2 = length m_param3 = ""
ChatNode node = new ChatNode();
node.ChannelID = channel;
node.Param1 = "" + voiceID;
node.Param2 = "" + length;
node.Param3 = null;
}
#endregion
}
}