c\#음성 채 팅 실현 실전 예시

1.음성 채 팅 의 전문 점 은 바로 실시 간 음성 이 고 인터넷 을 바탕 으로 음성 정 보 를 신속하게 전달 하 는 기술 로 각종 소 셜 네트워크 서비스 에 보편적으로 응용 되 고 장점 은 주로 다음 과 같은 몇 가지 가 있다.
(1)실효 성:영상 생방송 은 대역 폭 문제 로 인해 지연 이 높 은 문제 가 발생 할 수 있 지만 음성 방송 은 상대 적 으로 좋 고 지연 이 낮 으 며 제/한 시간 에 청중 과 상호작용 을 할 수 있어 실효 성 이 강하 다.
(2)프라이버시 성:이 점 은 어디 에 나타 나 는가.예 를 들 어 아나운서 가 자신의 얼굴 을 드 러 내 고 싶 지 않 거나 동 영상 이 없 으 면 아나운서 가 안심 할 수 있 기 때문에 음성 생방송 의 프라이버시 성 이 더욱 강하 다 는 것 이다.
(3)콘 텐 츠 의 질 이 높다.음성 방송 은'비 주 얼'이 아니 라 좋 은 콘 텐 츠 만 사용 자 를 끌 어 들일 수 있 기 때문에 음성 방송 은 상대 적 으로 콘 텐 츠 의 질 이 높다.
(4)원가 절감:음성 생방송 은 영상 생방송 에 비해 대역 폭 데이터 등 이 많이 싸 고 원가 가 많이 낮 아 지 며 더욱 실속 이 있다.
2.음성 채 팅 의 주요 절차:오디 오 수집,압축 코드,네트워크 전송,디 코딩 복원,오디 오 재생,아래 그림 과 같이

다음은 코드 의 측면 에서 이 몇 가지 절 차 를 상세 하 게 설명 하 겠 습 니 다.
(1)오디 오 수집,마이크 장치 데이터 읽 기

private readonly WaveIn _waveIn;
_waveIn = new WaveIn();
_waveIn.BufferMilliseconds = 50;
_waveIn.DeviceNumber = 0;
_waveIn.DataAvailable += OnAudioCaptured;
_waveIn.StartRecording();
(2)오디 오 데이터 압축 코드 는 흔히 볼 수 있 는 압축 형식 이 비교적 많다.예 를 들 어 mp3,acc,speex 등 이다.여 기 는 speex 를 예 로 들 자.

private readonly WideBandSpeexCodec _speexCodec;
_speexCodec = new WideBandSpeexCodec();
_waveIn.WaveFormat = _speexCodec.RecordFormat;

void OnAudioCaptured(object sender, WaveInEventArgs e)
{
   byte[] encoded = _speexCodec.Encode(e.Buffer, 0, e.BytesRecorded);
   _audioClient.Send(encoded);
}
(3)네트워크 전송,실시 간 전송 udp 프로 토 콜 의 천연 적 인 장점 확보

using SAEA.Sockets;
using SAEA.Sockets.Base;
using SAEA.Sockets.Model;
using System;
using System.Net;

namespace GFF.Component.GAudio.Net
{
  public class AudioClient
  {
    IClientSocket _udpClient;

    BaseUnpacker _baseUnpacker;

    public event Action<Byte[]> OnReceive;

    public AudioClient(IPEndPoint endPoint)
    {
      var bContext = new BaseContext();

      _udpClient = SocketFactory.CreateClientSocket(SocketOptionBuilder.Instance.SetSocket(SAEASocketType.Udp)
        .SetIPEndPoint(endPoint)
        .UseIocp(bContext)
        .SetReadBufferSize(SocketOption.UDPMaxLength)
        .SetWriteBufferSize(SocketOption.UDPMaxLength)
        .Build());

      _baseUnpacker = (BaseUnpacker)bContext.Unpacker;

      _udpClient.OnReceive += _udpClient_OnReceive;
    }

    private void _udpClient_OnReceive(byte[] data)
    {
      OnReceive?.Invoke(data);
    }

    public void Connect()
    {
      _udpClient.Connect();
    }

    public void Send(byte[] data)
    {
      _udpClient.SendAsync(data);
    }

    public void Disconnect()
    {
      _udpClient.Disconnect();
    }

  }
}
(4)서버 리 트 윗,클 라 이언 트 udp 사용,서버 여기 도 udp 로 리 트 윗

using SAEA.Sockets;
using SAEA.Sockets.Base;
using SAEA.Sockets.Interface;
using SAEA.Sockets.Model;
using System;
using System.Collections.Concurrent;
using System.Net;
using System.Threading.Tasks;

namespace GFF.Component.GAudio.Net
{
  public class AudioServer
  {
    IServerSocket _udpServer;

    ConcurrentDictionary<string, IUserToken> _cache;

    public AudioServer(IPEndPoint endPoint)
    {
      _cache = new ConcurrentDictionary<string, IUserToken>();

      _udpServer = SocketFactory.CreateServerSocket(SocketOptionBuilder.Instance.SetSocket(SAEASocketType.Udp)
        .SetIPEndPoint(endPoint)
        .UseIocp<BaseContext>()
        .SetReadBufferSize(SocketOption.UDPMaxLength)
        .SetWriteBufferSize(SocketOption.UDPMaxLength)
        .SetTimeOut(5000)
        .Build());
      _udpServer.OnAccepted += _udpServer_OnAccepted;
      _udpServer.OnDisconnected += _udpServer_OnDisconnected;
      _udpServer.OnReceive += _udpServer_OnReceive;
    }

    public void Start()
    {
      _udpServer.Start();
    }

    public void Stop()
    {
      _udpServer.Stop();
    }

    private void _udpServer_OnReceive(ISession currentSession, byte[] data)
    {
      Parallel.ForEach(_cache.Keys, (id) =>
      {
        try
        {
          _udpServer.SendAsync(id, data);
        }
        catch { }
      });
    }

    private void _udpServer_OnAccepted(object obj)
    {
      var ut = (IUserToken)obj;
      if (ut != null)
      {
        _cache.TryAdd(ut.ID, ut);
      }
    }

    private void _udpServer_OnDisconnected(string ID, Exception ex)
    {
      _cache.TryRemove(ID, out IUserToken _);
    }
  }
}
(5)디 코딩 복원,클 라 이언 트 는 서버 에서 받 은 데 이 터 를 약 정 된 압축 형식 에 따라 압축 을 풀 어 오디 오 데이터 로 복원 합 니 다.

private readonly BufferedWaveProvider _waveProvider;
_waveProvider = new BufferedWaveProvider(_speexCodec.RecordFormat);

private void _audioClient_OnReceive(byte[] data)
{
   byte[] decoded = _speexCodec.Decode(data, 0, data.Length);
   _waveProvider.AddSamples(decoded, 0, decoded.Length);
}
(6)오디 오 를 재생 하고 디 코딩 된 오디 오 데 이 터 를 재생 장치 로 재생 합 니 다.

 private readonly IWavePlayer _waveOut;
 _waveOut = new WaveOut();
 _waveOut.Init(_waveProvider);
 _waveOut.Play();
3.테스트 가 실 행 됩 니 다.음성 채 팅 의 몇 가지 관건 적 인 문제점 을 분석 한 후에 절차 에 따라 코드 를 밀봉 한 다음 에 사례 로 효 과 를 테스트 하 는 것 입 니 다.
클 라 이언 트 가 단추 이벤트 에 봉 인 됨:

GAudioClient _gAudioClient = null;

private void toolStripDropDownButton2_ButtonClick(object sender, EventArgs e)
{
  if (_gAudioClient == null)
  {
    ClientConfig clientConfig = ClientConfig.Instance();
    _gAudioClient = new GAudioClient(clientConfig.IP, clientConfig.Port + 2);
    _gAudioClient.Start();
  }
  else
  {
    _gAudioClient.Dispose();
    _gAudioClient = null;
  }
}
서버 가 main 함수 에 봉 인 됨:

ConsoleHelper.WriteLine("          ...", ConsoleColor.DarkBlue);
_gAudioServer = new GAudioServer(filePort + 1);
ConsoleHelper.WriteLine("          ...", ConsoleColor.DarkBlue);
ConsoleHelper.WriteLine("         ...", ConsoleColor.DarkBlue);
_gAudioServer.Start();
ConsoleHelper.WriteLine("          ", ConsoleColor.DarkBlue);
모든 것 이 준비 되 어 있 으 니 지금 F5 를 뛰 어 보 세 요.

 위의 붉 은 테두리 에서 보 듯 이 Hello World 에 해당 하 는 Hello 를 몇 마디 외 쳤 습 니 다.큰 공 은 초보 적 으로 이 루어 졌 습 니 다~
원문의 저자:https://www.cnblogs.com/yswenli/p/14353482.html
나 를 환영 하 는 github:https://github.com/yswenli/GFF
본문 에 어떤 문제 와 건의 가 있 는 지 발견 하면 언제든지 교 류 를 환영 합 니 다~
이상 은 c\#음성 채 팅 을 실현 하 는 실전 예제 의 상세 한 내용 입 니 다.c\#음성 채 팅 에 관 한 자 료 는 우리 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기