1. 程式人生 > 其它 >【一天一個小知識10/20】Unity安卓獲取麥克風並錄音儲存。

【一天一個小知識10/20】Unity安卓獲取麥克風並錄音儲存。

2021-10-20

10:42:16

#region 模組資訊
// **********************************************************************
// Copyright (C) 2019 jiamiantech
// Please contact me if you have any questions
// File Name:             Recording
// Author:                romantic
// WeChat||QQ:            at853394528 || 853394528 
// **********************************************************************
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class Recording : MonoBehaviour
{
    public Text ShowTimeHint;//剩餘時間的文字提示
    public Button voiceBtn;
    float tirecordingTimemer = 0;//錄音時長限制
    private string[] devices;
    public  AudioSource aud;
    // Use this for initialization
    void Start()
    {
        devices = Microphone.devices;
        if (devices.Length != 0)
        {
            ShowTimeHint.text = "裝置有麥克風:" + devices[0];
        }
        else
        {
            ShowTimeHint.text = "裝置沒有麥克風";
        }
        AddTriggersListener(voiceBtn.gameObject, EventTriggerType.PointerDown, (t) =>
        {
            Debug.Log("開始說話");
            StartCoroutine("KeepTime");
            //引數一:裝置名字,null為預設裝置;引數二:是否迴圈錄製;引數三:錄製時間(秒);引數四:音訊率
            aud.clip = Microphone.Start(devices[0], false, 15, 6000);

        });
        AddTriggersListener(voiceBtn.gameObject, EventTriggerType.PointerUp, (t) =>
        {
            Debug.Log("結束說話");
            StopCoroutine("KeepTime");
            Microphone.End(devices[0]);
            //直接播放
            aud.Play();
            string byteStr = AudioToByte(aud);
            Debug.Log(byteStr);
            //傳輸給伺服器
            //GameManager.GetInstance.tcpClient.SendMeToServer(ProtoType.T_S_Voice, byteStr);
        });
    }
    //把錄好的音段轉化為base64的string。測試過不轉base64直接用byte[]也是可以的
    public string AudioToByte(AudioSource audio)
    {
        float[] floatData = new float[audio.clip.samples * audio.clip.channels];
        audio.clip.GetData(floatData, 0);
        byte[] outData = new byte[floatData.Length];
        Buffer.BlockCopy(floatData, 0, outData, 0, outData.Length);
        return Convert.ToBase64String(outData);
    }


    //把base64的string轉化為audioSource
    public void ByteToAudio(AudioSource audioSource, string str)
    {
        byte[] bytes = Convert.FromBase64String(str);
        float[] samples = new float[bytes.Length];
        Buffer.BlockCopy(bytes, 0, samples, 0, bytes.Length);
        audioSource.clip = AudioClip.Create("RecordClip", samples.Length, 1, 6000, false);
        audioSource.clip.SetData(samples, 0);
        audioSource.Play();
    }

    IEnumerator KeepTime()
    {
        for (tirecordingTimemer = 15; tirecordingTimemer >= 0; tirecordingTimemer -= Time.deltaTime)
        {
            if (tirecordingTimemer <= 15)
            {
                ShowTimeHint.text = "你還可以錄 " + (int)tirecordingTimemer + " 秒";
                if (tirecordingTimemer < 1)
                {
                    ShowTimeHint.text = "時間到";
                    Microphone.End(devices[0]);
                }
            }
            yield return 0;
        }
    }

    //新增按鈕監聽型別
    private void AddTriggersListener(GameObject obj, EventTriggerType eventID, UnityAction<BaseEventData> action)
    {
        EventTrigger trigger = obj.GetComponent<EventTrigger>();
        if (trigger == null)
        {
            trigger = obj.AddComponent<EventTrigger>();
        }

        if (trigger.triggers.Count == 0)
        {
            trigger.triggers = new List<EventTrigger.Entry>();
        }

        UnityAction<BaseEventData> callback = new UnityAction<BaseEventData>(action);
        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = eventID;
        entry.callback.AddListener(callback);
        trigger.triggers.Add(entry);
    }
}