小言_互联网的博客

桌面精灵制作记录

250人阅读  评论(0)

前言

2014年时,想做一个会跳舞的,当在敲代码的时候驱动跳舞激励程序员、可以聊天的、可以语音聊 的桌面精灵

上个最后效果图 没gif

 

接入聊天AI

市面上的人工智能回答很多产品。比较流行的好用的有:

1.微软小娜和微软小冰,似乎是微软小娜比较好,微软小冰还处于比较基础的日常聊天,但回复内容多样,会有词语接龙、数绵羊、读心术、颜值测试和一些天气交通的日常功能等功能,而且调侃功能丰富,当年被微信封杀,却在微博刚上线的时候引发一波热潮。而相对的win10自带的微软小娜功能丰富。

2.小黄鸡。SimSimi是一款来自韩国的聊天机器人应用,以吉祥物“小鸡鸡”自居。SimSimi机器人的界面非常可爱,深受女生欢迎,最近网络上还刮起了一阵和SimSimi机器人对话的旋风。也尝试过接入,但其原本是用python写的,用Json进行应答传输,接入比较麻烦。

也尝试过小黄鸡
小黄鸡的消息上传需要编写xml或Json  对于xml或Json的处理   对于小黄鸡调用API的学习

3.图灵机器人。功能比较完善的一个自动回复机器人,是国人出品的,这次接入了这个。
图灵机器人官网:http://www.tuling123.com/

效果图

图灵机器人接入关键代码


  
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using System.Net;
  9. using System.IO;
  10. using Newtonsoft.Json;
  11. using UnityEditor;
  12. using UnityEngine;
  13. namespace 聊天机器人
  14. {
  15.      public partial  class Form1 : MonoBehaviour
  16.     {
  17.         SpeechVoiceSpeakFlags SpFlags = SpeechVoiceSpeakFlags.SVSFlagsAsync;
  18.         SpVoice Voice =  new SpVoice();
  19.          public  string usay;
  20.          public  string jijisay =  "";
  21.         HttpWebResponse Response = null;
  22.          public string ConnectTuLing(string p_strMessage)
  23.         {
  24.              string result = null;
  25.              try  {
  26.                 String APIKEY =  "c32ccaa805b6441be76bc18074f12e51";
  27.                 String _strMessage = p_strMessage;
  28.                 String INFO = Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(_strMessage));
  29.                 String getURL =  "http://www.tuling123.com/openapi/api?key=" + APIKEY +  "&info=" + INFO;
  30.                 HttpWebRequest MyRequest = (HttpWebRequest)HttpWebRequest.Create(getURL);
  31.                 HttpWebResponse MyResponse = (HttpWebResponse)MyRequest.GetResponse();
  32.                 Response = MyResponse;
  33.                  using (Stream MyStream = MyResponse.GetResponseStream())
  34.                 {
  35.                      long ProgMaximum = MyResponse.ContentLength;
  36.                      long totalDownloadedByte =  0;
  37.                     byte[] by =  new byte[ 1024];
  38.                      int osize = MyStream.Read(by,  0, by.Length);
  39.                     Encoding encoding = Encoding.UTF8;
  40.                      while (osize >  0)                    {
  41.                         totalDownloadedByte = osize + totalDownloadedByte;
  42.                         result += encoding.GetString(by,  0, osize);
  43.                          long ProgValue = totalDownloadedByte;
  44.                         osize = MyStream.Read(by,  0, by.Length);                    }                }
  45.                 JsonReader reader =  new JsonTextReader( new StringReader(result));
  46.                  while (reader.Read())                {
  47.                      if (reader.Path ==  "text")                    {
  48.                         result = reader.Value.ToString();
  49.                         Debug.Log(reader.Value);
  50.                         jijisay = reader.Value.ToString();                    }                }            }
  51.              catch (Exception)            {                 throw;            }
  52.              return result;        }
  53.          private void btn_send_Click()        {
  54.              string returnMess = ConnectTuLing(usay);
  55.              try             {
  56.                 SpeechVoiceSpeakFlags SpFlags = SpeechVoiceSpeakFlags.SVSFlagsAsync;
  57.                 SpVoice Voice =  new SpVoice();
  58.                  if (chkSaveToWavFile.Checked)                {
  59.                     SaveFileDialog sfd =  new SaveFileDialog();
  60.                     sfd.Filter =  "All files (*.*)|*.*|wav files (*.wav)|*.wav";
  61.                     sfd.Title =  "Save to a wave file";
  62.                     sfd.FilterIndex =  2;
  63.                     sfd.RestoreDirectory =  true;
  64.                      if (sfd.ShowDialog()== DialogResult.OK)                     {
  65.                         SpeechStreamFileMode SpFileMode = SpeechStreamFileMode.SSFMCreateForWrite;
  66.                         SpFileStream SpFileStream =  new SpFileStream();
  67.                         SpFileStream.Open(sfd.FileName, SpFileMode,  false);
  68.                         Voice.AudioOutputStream = SpFileStream;
  69.                         Voice.Speak(txtSpeakText.Text, SpFlags);
  70.                         Voice.WaitUntilDone( 5);
  71.                         SpFileStream.Close();                    }                }
  72.                  else                {                    Voice.Speak(txtSpeakText.Text, SpFlags);                }            }            
  73. catch(Exception error) { MessageBox.Show( "Speak error""SimpleTTS", MessageBoxButtons.OK, MessageBoxIcon.Error);    }    }
  74.                void OnGUI(){             if (GUI.Button ( new Rect ( 1001008050),  "点击"))
  75.                 btn_send_Click ();
  76.             usay = GUI.TextArea ( new Rect ( 05035050), usay);
  77.             GUI.TextField ( new Rect ( 020035050), jijisay);        }
  78.     }
  79. }

4.也试过很多ACG的自动回复机器人。像伪春菜,白丝魔理沙。但仔细玩就会发现这些与上面的不同,他们没有强大的数据库,也没有自然语言分析和模糊分析处理,只是对应内容进行回复,只有学习功能,需要玩家自己调教,显得非常的不智能。

 

 

语音与文字相互转换

想可以和AI聊天,AI可以说话

1.微软Speech.DLL 下的 TTS 和 STT引擎

Text-to-speech一般分为两个步骤:
1) 文本处理。
这一步做的事情是把文本转化成音素序列,并标出每个音素的起止时间、频率变化等信息。
作为一个预处理步骤,它的重要性经常被忽视,但是它涉及到很多值得研究的问题,比如拼写相同但读音不同的词的区分、缩写的处理、停顿位置的确定,等等。
2) 语音合成。
狭义上这一步专指根据音素序列(以及标注好的起止时间、频率变化等信息)生成语音,广义上它也可以包括文本处理的步骤。
这一步主要有三类方法:
a) 拼接法,即从事先录制的大量语音中,选择所需的基本单位拼接而成。这样的单位可以是音节、音素等等;为了追求合成语音的连贯性,也常常用使用双音子(从一个音素的中央到下一个音素的中央)作为单位。拼接法合成的语音质量较高,但它需要录制大量语音以保证覆盖率。
b) 参数法,即根据统计模型来产生每时每刻的语音参数(包括基频、共振峰频率等),然后把这些参数转化为波形。参数法也需要事先录制语音进行训练,但它并不需要100%的覆盖率。参数法合成出的语音质量比拼接法差一些。
c) 声道模拟法。参数法利用的参数是语音信号的性质,它并不关注语音的产生过程。与此相反,声道模拟法则是建立声道的物理模型,通过这个物理模型产生波形。这种方法的理论看起来很优美,但由于语音的产生过程实在是太复杂,所以实用价值并不高。

测试代码


  
  1. using UnityEngine;
  2. using System.Collections;
  3. using SpeechLib;
  4. public  class WinSpeech : MonoBehaviour {    
  5.     SpeechVoiceSpeakFlags SpFlags = SpeechVoiceSpeakFlags.SVSFlagsAsync;
  6.     SpVoice Voice =  new SpVoice();
  7.      void OnGUI(){
  8.          if(GUI.Button( new Rect( 200, 5, 80, 50), "Speech"))        {
  9.             Voice.Speak( "你好", SpFlags);
  10.         }
  11.     }
  12. }

2.飞讯SDK

3.Kinect
(含Kinect的语音识别功能) 之后转换成信息(错误率可能很高)
再转给小黄鸡...
识别语音之后3D模型要做的事情
[Kinect speech的使用]
Kinect v2 SDK包
额外下载 == Microsoft speech SDK + MSKinectLangPack_enUS.msi.

 

窗口制作

1.unity shader
使用传统的CustomChromakey方法 + 窗口化和置顶(DLL)
相当于抠色的功能的,取像素点颜色,判断颜色是否在阀值内,进行除去


  
  1. Shader "Custom/ChromakeyTransparent" {
  2. Properties {
  3. _MainTex ( "Base (RGB)", 2D) = "white" {}
  4. _TransparentColourKey ( "Transparent Colour Key", Color) = ( 0, 0, 0, 1)
  5. _TransparencyTolerance ( "Transparency Tolerance", Float) = 0.01
  6. }
  7. SubShader {
  8. Pass {
  9. Tags { "RenderType" = "Opaque" }
  10. LOD 200
  11. CGPROGRAM
  12. #pragma vertex vert
  13. #pragma fragment frag
  14. #include "UnityCG.cginc"
  15. struct a2v
  16. {
  17. float4 pos : POSITION;
  18. float2 uv : TEXCOORD0;
  19. };
  20. struct v2f
  21. {
  22. float4 pos : SV_POSITION;
  23. float2 uv : TEXCOORD0;
  24. };
  25. v2f vert(a2v input)
  26. {
  27. v2f output;
  28. output.pos = mul (UNITY_MATRIX_MVP, input.pos);
  29. output.uv = input.uv;
  30. return output;
  31. }
  32. sampler2D _MainTex;
  33. float3 _TransparentColourKey;
  34. float _TransparencyTolerance;
  35. float4 frag(v2f input) : SV_Target
  36. {
  37. // What is the colour that *would* be rendered here?
  38. float4 colour = tex2D(_MainTex, input.uv);
  39. // Calculate the different in each component from the chosen transparency colour
  40. float deltaR = abs(colour.r - _TransparentColourKey.r);
  41. float deltaG = abs(colour.g - _TransparentColourKey.g);
  42. float deltaB = abs(colour.b - _TransparentColourKey.b);
  43. // If colour is within tolerance, write a transparent pixel
  44. if (deltaR < _TransparencyTolerance && deltaG < _TransparencyTolerance && deltaB < _TransparencyTolerance)
  45. {
  46. return float4( 0.0f, 0.0f, 0.0f, 0.0f);
  47. }
  48. // Otherwise, return the regular colour
  49. return colour;
  50. }
  51. ENDCG
  52. }
  53. }
  54. }

2.vs窗口设置

3.代码设置

UpdateLayeredWindow可以设置使得窗口透明 https://baike.baidu.com/item/UpdateLayeredWindow

关键代码:


  
  1. Win32.BLENDFUNCTION blendFunc = new Win 32.BLENDFUNCTION();
  2. blendFunc.AlphaFormat = Win 32.AC_SRC_ALPHA;
  3. Win32.UpdateLayeredWindow(..blendFunc..);

 

 跳舞鼓励功能 

我希望每当我敲打键盘的时候 桌面精灵能根据我敲键盘速度 模型会进行跳舞。

1.代码控制动画


  
  1. public Image PowerFilled;
  2.     void Start () {        Slow ();    }
  3.     void OnGUI() {
  4.         Event e = Event.current;
  5.          if (e.isKey) {
  6.              if( Time.timeScale <  1)
  7.                  Time.timeScale =  Time.timeScale +  0.05F;
  8.             GUI.Box ( new Rect ( 5508050),e.keyCode.ToString ());
  9.         }
  10.         GUI.Box ( new Rect ( 558050),  Time.timeScale.ToString ());        
  11.     }
  12.     void Slow (){
  13.          if( Time.timeScale >  0.05)
  14.         {
  15.          Time.timeScale =  Time.timeScale -  0.02F;
  16.             PowerFilled.fillAmount = (float)( Time.timeScale/ 1F);
  17.         Invoke ( "Slow"0.1F);
  18.         }
  19.     } 


当我离开键盘,跳舞速度便慢慢地下降下来~但我发现 当我切换到别的应用程序之后 桌面精灵程序便不会继续监听我的键盘输入,失去了桌面精灵的意义。所以写了个Hook

2.HOOK使用:全局键盘钩子

如是我便使用了全局键盘钩子HOOK.
但这个只能在unity里使用 而不能发布exe
因为我写的这个功能 360告诉我是病毒 。。严重警告然后删了
我写之前都没意识到这件事。。
我是打算写一个桌面精灵而已
然后只要我不断打代码 她就会开始跳舞 当我afk的时候她就慢慢停下来
我觉得很好玩。。实现起来的过程很难 花了我很多时间去写。。
终于写了出来。。结果被360删了。。。
之后我意识到,我这个程序,因为是桌面精灵 所以一直处于后台运行状态
不单后台运行 它还监听了我的键盘输入
细思极恐。。
这就是盗窃密码的病毒啊
后台运行,任务栏不显示,进程的名字改了,还监听键盘。。我都做到了,虽然她是个桌面精灵。。。。。。
实际上这是我的毕设

so,以后可能会有程序猿说发个游戏或者应用给你们测试一下,其实他可能给你发了一个键盘监听程序。
键盘监听在unity里始终不太好用。因为种种原因
种种原因就不解释了 太长。因为系统防御还算是有的。

 

 

---------end---------

 

 


转载:https://blog.csdn.net/u014528558/article/details/117173279
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场