본문 바로가기

카테고리 없음

SiCi Remote Controller 연동방법

사용툴 : Unity3d (C#)

 

 

 

1. 소켓 연결

private bool _socket;
ArrayList byteBufferList = new ArrayList();
ArrayList connectionList = new ArrayList();

try
{
    // 소켓 연결 설정 (IP ADDRESS, PORT NUMBER, ...) IP 주소는 숫자와 and .(dot) 둘이 같이 넣어줘야함(ex : 192.168.0.38)
    _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    IPAddress remoteIPAddress = IPAddress.Parse(serverIP);
    IPEndPoint remoteEndPoint = new IPEndPoint(remoteIPAddress, portNumber);
            
    // 소켓 연결 함수
    _socket.Connect(remoteEndPoint);
}
catch (Exception)
{
    // IP ADDRESS, PORT NUMBER가 잘못 입력 되었을 경우 ...
}

// 소켓이 정상적으로 연결되었다면 connectionList에 담는다.
connectionList.Add(_socket);
byteBufferList.Add(new ArrayList());

 

2. 데이터 전송

// Remote Controller에 해당 데이터 버튼 생성
byte[] checkData = new byte[100];
checkData = System.Text.Encoding.UTF7.GetBytes("보낼데이터");
_socket.Send(checkData);

// Example1 : Remote Controller의 버튼을 초기화 하고 싶을 때에는 "reset"을 보내준다.
// byte[] checkData = new byte[100];
// checkData = System.Text.Encoding.UTF7.GetBytes("reset");
// _socket.Send(checkData);

// Example2 : 만일 영상도 함께 보내는 경우라면 아래 코드를 통해 보내야함
// Message를 전송 할 때에는 영상을 잠시 보내지 않는다.
//_isCheckWebcamPlay = false;
//yield return new WaitForSeconds(0.1f);
// byte[] checkData = new byte[100];
// checkData = System.Text.Encoding.UTF7.GetBytes("데이터보낸다");
// _socket.Send(checkData);
// 종료 확인 메시지 전송
// checkData = SiCiUtil.EncodingString("end");
// _socket.Send(checkData);
// yield return new WaitForSeconds(0.1f);
// 정지되었던 영상 정상화
// if (_isWebcam)
// {
    //_isCheckWebcamPlay = true;
    //StartCoroutine(SendCameraSecond(_cameraSendSpeed));
// }



3. 데이터 수신
if (null != _socket && true == _socket.Connected)
{
    ArrayList con = new ArrayList(connectionList);
    Socket.Select(con, null, null, 1000);

    // 연결된 소켓들에 대하여 데이터를 읽어 옴
    foreach (Socket soc in con)
    {
        ArrayList buf = (ArrayList)byteBufferList[connectionList.IndexOf(soc)];

        // 실제 byte 배열을 받는 함수 (receiveBytes에 데이터가 저장되고 read변수에 길이가 저장된다.)
        int read = soc.Receive(receiveBytes);

        for (int i = 0; i < read; i++)
            buf.Add(receiveBytes[i]);

        // 전달받은 byte를 string으로 변환
        string str = System.Text.Encoding.UTF7.GetString((byte[])buf.ToArray(typeof(byte)));
        Debug.Log("Received Message : " + str);

        if (str == "#reset#")
        {
            // 이벤트 받아오기 버튼이 눌러졌을 경우 여기로 옴
            buf.Clear();
            return;
        }
        else
        {
            // 누른 버튼의 번호가 전송 됨 (1 부터 시작)
            return;
        }
    }
}

 

// 영상도 함께 사용 할 경우

4. 영상 정보 얻기

private string deviceName;
WebCamTexture wct;

private bool _isCheckWebcamPlay = false;
private bool _isCheckWebcam = false;
private bool _isWebcam = false;
    
private float _cameraSendSpeed = 0.1f;

// Webcam 얻어오는 부분
try
{
    // WebCamTexture를 이용하여 연결된 device 목록을 가져온다.
    WebCamDevice[] devices = WebCamTexture.devices;
    deviceName = devices[0].name;

    // 만일 카메라가 여러개라면 전면 카메라를 선택한다.
    // 후면 카메라 선택하고 싶을 경우에는 아래 부분 주석 처리.
    // ----------------------------------------------------------
    for (int i = 0; i < devices.Length; i++)
    {
        if (devices[i].isFrontFacing)
            deviceName = devices[i].name;
    }
    // ----------------------------------------------------------

    // 카메라의 해상도 설정
    // 넥서스7 기준으로 QCIF(176x144), QVGA(320x240), FULL HD(1280x768)만 설정 가능
    // ex) 50x100 으로 해당 값을 설정하여도 QCIF로 나오게 된다.
    // 따라서 해상도를 낮추고 싶을 경우에는 따로 함수를 만들어서 사용 해야한다.
    wct = new WebCamTexture(deviceName, 1280, 768, 12);
            
    // 영상을 재생할 Plane을 찾아서 넣어준다.
    transform.FindChild("Plane").renderer.material.mainTexture = wct;
    wct.Play();
}
catch (Exception)
{
    // 에러 처리
    return;
}

// 카메라 관련 변수 셋팅
_isCheckWebcamPlay = true;
_isCheckWebcam = true;
_isWebcam = true;

// 소켓을 통해 영상을 보내줌
if (_isCheckWebcam)
    StartCoroutine(SendCameraSecond(_cameraSendSpeed));

 

5. 영상 전송

// 영상 전달
IEnumerator SendCameraSecond(float sendTime)
{
    Debug.Log("SendCameraSecond");
    // 영상이 시작한다는 뜻으로 #CameraStart# Message 전달
    byte[] checkData = System.Text.Encoding.UTF7.GetBytes("#CameraStart#");
    _socket.Send(checkData);

    yield return new WaitForSeconds(2f);
    while (_isCheckWebcamPlay)
    {
        SendCamera();
        yield return new WaitForSeconds(sendTime);
    }
}
        
private void SendCamera()
{
    try
    {
        // 카메라 영상을 받아옴
        Color32[] cols = wct.GetPixels32();

        // 소켓을 통해 전송 할 byte array (80x48x3) width : 80, height : 48, rgb 값 (alpha제외)
        byte[] bytes = new byte[11520];

        // ex) 화질 축소하는 부분
        // 처음부터 1280x768로 설정하고 화질을 낮춘 이유는 넥서스7에서 QCIF, QVGA로 설정 할 경우
        // 화면이 확대되어 나오는 현상이 있어서 FULL HD 화질로 설정 후 줄이게 되었음
        // 1280 / 16 = 80, 768 / 16 = 48
        int idx = 0;
        for (int i = 0; i < 768; i = i + 16)
        {
            for (int j = 0; j < 1280; j = j + 16)
            {
                bytes[idx] = cols[i * 1280 + j].r;
                bytes[idx + 1] = cols[i * 1280 + j].g;
                bytes[idx + 2] = cols[i * 1280 + j].b;

                idx += 3;
            }
        }

        // Socket이 null이 아니라면 전송
        if (_socket == null)
            ShutDown();
        else
            _socket.Send(bytes);
    }
    catch (Exception)
    {
        // 오류 처리
    }
}

 

 

Sample Project 사용법

 

1. 

 

2.

 

3.

 

4.

 

5.

 

6.

 

7.

 

8.

 

 

 

 

RemoteController 실행파일 (링크)

 

Example 실행파일 (링크)

 

Example 프로젝트파일 (링크)