//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 } }