Main/Assets/Code/Logic/Chat/ChatSystem_voice.cs
2025-01-25 04:38:09 +08:00

325 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//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
{
/// <summary>
/// UIEntergameForm的逻辑处理类
/// </summary>
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<int, byte[]> _voiceDataDic = new Dictionary<int, byte[]>();
private Dictionary<string, string> _voiceKeyToVoiceData = new Dictionary<string, string>();
#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
}
}