VNC를 들어보신 적이 있으신가요?


VNC에 관해서는 위키백과에 이렇게 나와있군요.

VNC(Virtual Network Computing, 가상 네트워크 컴퓨팅)는 컴퓨터 환경에서 RFB 프로토콜을 이용하여 원격으로 다른 컴퓨터를 제어하는 그래픽 데스크톱 공유 시스템이다. 자판마우스 이벤트를 한 컴퓨터에서 다른 컴퓨터로 전송시켜서 네트워크를 거쳐 그래픽 화면을 갱신하는 방식을 제공한다.

VNC와 RFB는 미국과 다른 국가들에서 RealVNC Ltd.의 등록 상표이다

https://ko.wikipedia.org/wiki/VNC


쉽게 말해서 그냥 원격에서 컴퓨터를 조작하기 위한 수많은 기술중 하나인겁니다.


마이크로소프트는 여기에 대응하는 RDP라는 프로토콜을 만들었고 우리가 익히 아는 TeamViewer나 SplashTop같은 프로그램도 RFB를 변형하거나 자체적으로 프로토콜을 만들어서 서비스합니다.


보통 사람들에겐 VNC아이콘보다 이 아이콘이 더 친숙할지도 모르겠다. 이 아이콘의 정체는 Teamviewer의 아이콘



하지만 Teamviewer든 SplashTop이든 VNC든 RDP든 모두 공통적인 문제가 있는데 바로 반응속도가 더럽게 느리다는 것입니다.


VNC를 써본 사람들은 하나같이 이야기하는 것이 마우스 클릭하고 1초 프로그램 실행되는 것 보는데 1초 실수로 클릭을 하면 딜레이가 걸려서 한참뒤에 반응이 오니 관리하는 것 외에는 영 쓸만한 것이 못 된다고 하더군요.


그게 어쩔 수 없던것이 VNC가 사용하는 RFB프로토콜은 JPG로 캡쳐한뒤에 네크워크로 보내고 이를 다시 화면에 띄우는 옛날 웹캡이 쓰던 MJPEG방식과 거의 흡사한 방식을 사용합니다. 문제는 JPG인코딩이 CPU를 통해서 하기 때문에 그렇게 빠르지 않고 이를 디코딩하는 것도 사실 그렇게 빠르지 않다는 것입니다.


JPG가 빠르지 않다고? 하시는 분들은 DSLR에서 RAW이미지를 JPG로 인코딩할 때 생각보다 저장시간이 걸린다는 것을 생각해주셔야 합니다. (사진쪽 종사자들은 포토샵에서 결과물 뽑아낼 때 생각보다 시간이 걸린다는 것을 알고있지요. 이쪽 종사자들은 JPG로 뽑지 않고 보통 비손실 압축인 PNG로 뽑긴합니다만...) 우리가 흔히 사용하는 모니터가 60Hz인 점을 생각해주세요. 제가 위에서 말한 JPG인코딩-디코딩이 최소 1/60초안에 끝나야 합니다. 사실 요즘 CPU에 640x480정도의 해상도라면 그 정도는 충분히 가능하지만 데스크탑의 해상도가 점점 더 좋아지는 관계로 VNC의 속도는 예나지금이나 큰 차이가 나지를 않습니다. 그래서 TurboVNC라는 libjpeg-turbo를 사용하는 서버와 클라이언트가 나왔지만 서버와 클라이언트 둘 다 TurboVNC를 사용하지 않으면 다른 것이 하나도 없는 상황이 됩니다.


이런 복잡한 상황을 한큐에 해결할 수 있는 물건이 오픈소스로 공개되었으니 그것이 바로 JSMPEG-VNC입니다.

https://github.com/phoboslab/jsmpeg-vnc


어느정도 성능인지는 한번 보시지요.



Mac에서 Windows용 게임을 하고 있습니다. 심지어 클라이언트도 따로 없이 브라우저를 이용합니다.


그럼 jsmpeg는 뭔가 했더니 같은 곳에서 만들어낸 Javascript기반 MPEG동영상 재생 웹소켓입니다. 쉽게말해서 별도의 코덱따윈 갖다버리고 자바스크립트로 직접 MPEG를 디코딩하는 수준에 이른 것이지요. 요즘 브라우저는 asm.js를 위시해서 자바스크립트를 네이티브로 컴파일해서 사용하니까 직접 웹소켓으로 작업이 가능해진 것입니다.


예상도 못한 수준의 물건이 나왔는데요. 크기도 엄청 작은데 수준은 장난이 아닙니다. 서버 실행도 간단한데요.

jsmpeg-vnc.exe "desktop"


이렇게 하면 데스크탑 전체가 실행되며


jsmpeg-vnc.exe -s 크기 "cursor"


이렇게 하면 마우스를 따라 화면이 캡쳐됩니다.


동영상 마지막에보면 스마트폰으로 조작을 하는 모습을 볼 수 있는데 하이브리드 앱형태로 만들거나 웹페이지를 모바일에 맞게 만들어서 사용하면 똑같이 만들어 쓸 수 있습니다. 예전에 제가 소개했던 Liquidsky와 비슷하게 쓸 수 있는 것이지요.


그런데 현재 링크에 걸린 서버프로그램은 오직 Windows만 지원합니다. 하지만 이런 좋은 원격제어 프로그램을 Windows에서만 쓰긴 아깝지요. Linux도 원격제어 수요는 상당히 많기 때문에(보통 SSH와 터미널 작업으로 때우기는 하지만) 이쪽은 없나 살펴봤습니다.


있네요.

https://github.com/thesauri/jsmpeg-vnc-linux


Cusor를 따라가는 기능은 아직 포팅이 되지 않았지만 사실 그건 중요하지 않고 desktop 전체를 캡쳐하는 것은 포팅이 되었다고 합니다.


Windows의 그래픽 API를 X11로 포팅했다고 합니다.


이런 것을 찾아냈으니 한 번 해봐야겠는데요.


....그건 자고 일어나서 주말에 한번 해보지요.


build-essential

libavcodec-dev

libavutil-dev

libx11-dev

zlib1g-dev

libswscale-dev

libwebsockets-dev

libxtst-dev


이 패키지가 필요한 듯 합니다. 해당 프로젝트 관리자가 설명이 좀 부족합니다...


컴파일이 제대로 안 되네요...


일단 메일을 날려봐야겠습니다.


,

채팅봇이란 물건이 있습니다. 일종의 인공지능 대화상대인데 특정 대화방(채팅룸)에서 특정 키워드가 나오면 해당 키워드에 맞는 대답을 해주는 물건입니다.


이미 잘 이용되는 물건으로는 간단하게는 심심이가 있고 Youtube와 TwitchTV에서 사용하는 NightBot, MooBot등이 있고 인공지능 대화용으로 만들어진 MS의 테이(Tay)나 구글의 채팅봇도 있습니다. 카카오톡을 통해 알려주는 채팅봇도 있습니다.


사실 인공지능까지는 아니더라도 간단하게 유튜브나 TwitchTV등에서 방송하는 사람들을 도와주는 봇들은 이미 많이 쓰이고 있지요. 이들의 조상은 IRC에 플러그인 방식으로 사용되어서 해당 채팅방에서 물을 흐리는 몇몇 또라이들을 추방하거나 욕설등을 가려주는 등 IRC의 심판으로 쓰였던 그런 물건이 시초라고 보고 있습니다. 여기에 몇가지 키워드를 더 추가해서 특정 키워드가 나오면 대신 대답을 해주거나 간단한 대화기능을 넣는 등 발전을 했고 이후 지금의 시리같은 인공지능 기술과 음성인식 기술이 접목되어 굉장히 편리해졌지요.


지금 많이 이용되는 채팅봇 혹은 전자비서의 조상은 IRC의 플러그인들로 부터 시작되었다고 본다. 사진은 IRC클라이언트 중 제일 유명한 mIRC의 로고



이런 쪽에 제가 관심을 갖게 된 원인은 한 때 유명했지만 지금은 그저그런 Twitch Plays Pokemon때문이었습니다.

Twitch Plays Pokemon은 말 그대로 TwitchTV방송의 채팅을 통해 직접 게임을 움직여서 게임을 하는 특이한 방송이었습니다. 지금은 시들하지만 처음에는 방송을 보려는 사람들로 붐볐었습니다. 문제는 그만큼 컨트롤이 산으로 갔다는 것이지만...


당시 이슈가 되었던 Twitch Plays Pokemon 방송. 사공들의 수많은 채팅들을 봇이 읽어들여서 게임을 하는 그런 방송이었다.


해당 방송의 방식은 아주 간단합니다. 사람들이 채팅방에 특정 키워드(right, left, up, down, a, b, start, select 등)을 치면 게임과 함께 연동되는 봇이 해당 명령에 맞는 기능을 게임에 전달하여 움직이게 하는 것입니다.


이것이 가능했던 이유는 TwitchTV의 채팅이 기존의 IRC를 그대로 이용하기 때문이었습니다. TwitchTV는 채팅방식을 공개된 IRC프로토콜을 이용하되 약간의 보안을 적용해서 사용했기 때문에(그나마 그 보안도 알려진 방식입니다.) 기존의 IRC봇을 만들기 쉬웠습니다. 실제로 여기에 쓰인 플러그인과 비슷하게 구현된 소스코드도 공개되어 있지요.


https://github.com/hzoo/TwitchPlaysX

https://github.com/sunshinekitty/TwitchPlaysPokemon


위 github가 해당 플러그인을 구현한 소스코드입니다. IRC를 기반으로 키보드 혹은 마우스 명령을 내릴 수 있게 되어있지요.


채팅을 할 수 있는 방송은 TwitchTV만 있는 것은 아니지요. Twitch외에도 Youtube가 있고 국내에서는 DaumTV팟도 있습니다. (아프리카TV는 너무 구식이기 때문에 예외로 합시다.)


1. 실시간 방송이 가능하고

2. 동시에 채팅도 할 수 있으며

3. 여러명이 달려들어도 서버상태가 괜찮다면

이런 류의 봇을 직접 만들 수 있지 않을까?


라는 생각이 들더군요.


네, 사실은 안일한 생각이었습니다. 대다수 서비스는 IRC기반이 아닌 다른 방식을 사용하고 있었고 해당 프로토콜을 알아내는 것은 굉장히 어려웠습니다. TwitchTV가 알려진 방식을 사용한 특이 케이스였던 것입니다.


그런데 Youtube는 API를 통해 채팅봇을 만들 수 있게끔 공개가 되어있었고 실제로 NightBot이란 봇이 이미 만들어져 있었습니다. 즉, Youtube는 충분히 이러한 봇제작이 가능하다는 의미였지요.

https://developers.google.com/youtube/v3/live/docs/liveChatMessages/list


"그래! 그럼 나도 ChatBot이란 것을 한 번 만들어보자!"라는 생각으로 시작을 해봤습니다.


결과는...당연하게도 참패.


YoutubeAPI는 생각보다 요구하는 것이 너무 많았습니다. 저는 그저 채팅 내용을 읽어들인다음 키워드분석을 하는 것을 원했는데 해당 채팅방의 전반적인 것을 다 API로 세팅하게 만들어져 있더군요. 전반적인 IRC봇이 그렇기는 하지만 위의 TwitchPlaysPokemon의 소스코드는 그렇게 복잡하게 만들어지지는 않았습니다.


즉, 예상을 뛰어넘는 수준의 설정을 요구했던 것입니다. 


처음에는 그냥 장난으로 시작한 것인데 이런식으로 흘러가다간 올해안에 ChatBot은 커녕 비슷한 것도 만들기 어렵겠다는 생각이 들었습니다. 하지만 세상은 넓고 꼼수는 많습니다. 그리고 그 꼼수는 간단한 아이디어부터 시작되었습니다.


"Youtube나 TwitchTV나 웹페이지에서 채팅이 가능하다."


특히 Youtube는 어딘가의 방송시스템 처럼 클라이언트를 설치하지 않고 웹브라우저에서 볼 수 있게 만들어져 있습니다. 그렇다는 것은 웹페이지 분석을 하면 채팅의 키워드를 읽을 수 있다는 의미입니다!


Youtube는 편의를 위해 채팅창만 따로 빼서 쓸 수 있게 할 수 있는데 즉, 채팅페이지를 따로 찾을 필요없이 해당 채팅창만 분석, 확인하면 채팅창으로 올라오는 키워드를 읽을 수 있다는 의미가 됩니다. 게다가 해당 페이지의 주소를 긁어내는 것도 어려운 일이 아닙니다. 당장 위 스크린샷만 봐도 창 주소를 바로 읽을 수 있게 되어있습니다. 그리고 저 페이지주소는 어떤 웹브라우저를 사용해도 똑같습니다. (어딘가의 무언가와 다르게 말입니다.)


그렇다면 소스보기를 통해 채팅창의 코드 분석이 가능하다는 의미이므로 어떤 Element(요소)가 채팅 메시지 요소인지 확인하는 작업이 필요했습니다. 해당 작업에는 크롬의 개발자도구가 유용하게 쓰였습니다. 분석 시작 15분만에 코드를 찾아냈으니까요. 하지만 이후는 노가다로 귀결된 것은 어쩔 수 없었습니다.


채팅 메시지는 해당 페이지에서 content라는 이름으로 찾으면 (아이디)+(메시지)형태의 리스트로 되어있었고 author-name이라는 이름으로 찾으면 채팅창에 떠있는 아이디를 리스트형태로 찾을 수 있었습니다. 그렇다면 두 리스트를 이용해서 메시지만 뽑아낼 수 있다는 의미이기도 하지요.


그런데 채팅은 실시간으로 이루어지는데 새로운 메시지는 어떻게 아냐고요? 위 작업을 그냥 계속 하면 됩니다. 그리고 이전 리스트와 새 리스트를 비교한 다음 추가된 것만 뽑으면 되는 것이지요.


그런데 이걸 만들까요? Selenium이란 우리가 실제로 사용하는 웹브라우저에 덧붙여서 사용하는 웹 자동화 모듈이 있는데 이것을 Youtube채팅페이지를 띄워서 해당 요소를 찾으면 되는 것입니다.


(http://www.seleniumhq.org/projects/webdriver/)


Chrome, Firefox, Safari 등 유명 웹브라우저와 함께 PhantomJS란 따로 UI를 제공하지 않지만 WEB접속을 해주는 Selenium을 위한 웹브라우징 엔진도 지원합니다. 저는 Firefox에 Selenium을 설치한 후 읽어들이기로 했습니다.


그리고 문장처리는 Python으로 처리를 했습니다. Selenium의 예제는 JAVA로 되어있지만 Python이 문자열 처리는 월등하기 때문에(대신 느린것은 어쩔 수 없지요.) Python Wrapper를 찾았더니 있더군요. pip로 쉽게 설치 할 수 있었습니다.


sudo pip install selenium

혹은

sudo pip3 install selenium


만약 pip(Python2)나 pip3(Python3)가 없으시면 우분투의경우 저장소에서 설치할 수 있습니다. 아무래도 2017년 현재에는 Python3가 낫겠지요.


그리고 WebDriver를 설치해야 하는데

Firefox는 https://github.com/mozilla/geckodriver/releases

여기서 geckodriver를

Chrome은 https://sites.google.com/a/chromium.org/chromedriver/

여기서 파일을 다운로드 받은 다음 /usr/bin에 넣어주시면 알아서 활성화가 됩니다.

PhantomJS는 그냥 PhantomJS를 저장소에서 설치하시면 알아서 활성화가 되므로 상관이 없습니다.


from selenium import webdriver
driver = webdriver.Firefox()
#Firefox가 싫음 PanthomJS나 Chrome도 상관없다.

#Youtube chat room's page URL
driver.get(' 유튜브 채팅창 URL')
driver.implicitly_wait(10) 


요렇게 코드를 작성하고 실행하면 웹브라우저가 하나 실행되면서 Webdriver를 통해 자동화가 가능하게 됩니다.


위 코드 다음

id_msg = driver.find_elements_by_xpath('//*[@id="content"]')
id_l = driver.find_elements_by_xpath('//*[@id="author-name"]')


이렇게 하면 id_msg란 리스트에는 content항목인 요소들이 들어가고 id_l이란 리스트에는 author-name이란 이름의 요소들이 들어가게 됩니다. xpath란 것은 W3C에서 요소들을 쉽게 쓸 수있도록 XML형태로 만든 규약인데 자세한 것은 따로 찾아보시길 추천드립니다.


그리고

print (id_msg[0].text)

print (id_l[0].text)

이렇게 하시면 해당 채팅창의 제일 첫 메시지의 아이디와 문장이 콘솔창에 뜨는 것을 알 수 있습니다!!!!


즉, 채팅창의 메시지를 읽어들이는데에 성공한 것이지요. 그렇다면 문자열을 조작하고 Tokenizer를 통해 단어별로 자른다음 키워드를 분석하면 봇을 충분히 만들 수 있겠지요?


일단 오늘은 Youtube의 채팅창의 내용을 읽어들이는 것까지만 하고 나머지는 넘어가도록 하겠습니다.


다음 예시는 위의 방식을 이용해서 Youtube의 채팅창의 내용을 콘솔창에 계속 띄우는 소스코드입니다.


https://colorscripter.com/s/h7ME3n7

,

라즈베리파이나 오래된 PC를 에뮬레이터 머신으로 만들어줄 수 있는 Lakka란 프로젝트가 있습니다. RetroArch란 온갖 게임콘솔과 아케이드를 에뮬레이터 해주는 프로그램을 이용한 것인데요. 다른 것은 모두 배제하고 최소한의 OS(Libreelec 기반)와 RetroArch만 올려서 만든 배포판입니다.



http://www.lakka.tv/


2017년 현재 RetroArch는 상당한 수준의 인터페이스와 엄청난 지원 범위를 자랑하고 있어서 오래된 PC나 저렴한 라즈베리파이에 게임패드를 연결한 다음 Lakka만 올려서 게임기로 만드는 경우가 늘고 있습니다.




그런데말입니다.

RetroArch의 PSP코어(통칭 lr-ppsspp라고 합니다.)가 옵션이 상당히 부실합니다. PPSSPP의 소스코드를 이용해서 에뮬레이팅은 상당수준이지만 PPSSPP자체가 아직 완전하지 않아서 게임마다 설정을 다르게 줘야하고 이런 저런 삽질을 동원해야하는데 RetroArch는 다른 콘솔머신도 지원해야하다보니 크게 신경을 못 쓰는 것이 현실입니다.


즉, 통합 에뮬레이터로는 훌륭하지만 특정 기기의 성능은 그리 좋지 못하다는 의미지요. 특히 PSP의 명작이라 할 수 있는 DJMAX시리즈의 경우에는 링크디스크나 IO문제로 PPSSPP의 많은 설정과 기능을 요구합니다. 하지만 RetroArch의 PSP코어에는 이런 기능이 없습니다. 그래서 RetroArch의 PSP게임을 굴리면 완벽하게 돌아가지가 않지요. 게다가 RetroArch는 Adhoc을 이용한 온라인 기능도 부실합니다.


그래서 생각한것이 아에 RetroArch같은 통합에뮬레이터 시스템이 아닌 PPSSPP만 올려서 PSP 전용콘솔머신을 하나 만들자!라고 생각했습니다. 그래서 삽질을 시작했습니다. PSP게임외에 다른 콘솔은 Lakka에서도 아무 문제없이 굴러가니까 그 쪽은 그냥 Lakka를 쓰면 될테니까요.


PPSSPP 그 자체도 인터페이스는 상당히 편리하게 되어있고 패드만으로도 모든 옵션을 선택할 수 있게 잘 만들어져 있습니다.


다른 에뮬레이터와 다르게 상당히 예쁘게 잘 만들어져 있다. 디자인이 현대적이라고 해야할까.


그래서 이참에 백라이트 나간 노트북을 부셔서(!) 콘솔머신을 하나 만들기로 했습니다.

그래서 다음과 같은 계획을 하나 짰습니다.



1. 하드웨어는 백라이트 나간 오래된 노트북으로 하고 이것을 TV에 연결해서 쓸 수 있도록 한다.


2. 게임은 PPSSPP만을 올려서 PSP게임만 지원하게 한다.


3. 컨트롤러는 오로지 게임패드로 (다행히 PPSSPP가 게임패드만으로 굴릴 수 있다.)


4. FTP서버를 하나 만들어서 게임을 FTP로 전송할 수 있게 한다. (SMB도 생각했지만 FTP가 더 안정적이었습니다.


5. 라이브모드만 지원하되 Persistent모드로 만들어서 넣자. (설정 저장을 위해)


6. 어차피 나만 쓸 거 보안은 신경 끄자.



여기서 제일 중요하게 여긴것은 1번과 6번입니다. 사실 보안까지 신경쓰기 시작하면 취미로 하는 것이 일거리가 되기 때문에 처음부터 신경을 껐습니다.


세로로 세우기 위해서 다이소 도마꽂이에 꽂았는데 딱 맞는다. 도마꽂이가 랩톱 세우는데 최고였다.


그렇게 오늘 저의 게임기가 되어주실 노트북은 인텔 코어2듀오 콘로 2.4GHz 메모리 2GB 저장용량 250GB의 제품입니다. GPU는 자그마치 인텔 내장 그래픽. 백라이트가 나가서 액정을 그냥 떼버렸고 안테나는 외부에 노출 시켰습니다.


어차피 TV뒤쪽 공간에 밀어넣을 예정이니 모양은 상관없습니다.


그리고 상세한 제작 과정은 다음과 같습니다.


1. OS는 Customize(https://github.com/kamilion/customizer) 로 우분투 Mini-remix(http://www.ubuntu-mini-remix.org/)를 기반으로 한다.


1.1 Customizer를 리눅스 PC에 설치한다. (따로 설명하지 않겠습니다.)

1.2 Customizer-gui에서 ISO선택을 누르고 우분투 Mini-remix이미지를 선택한다.


1.3 소스 수정버튼을 누르고 한국서버를 선택한 다음 multiverse와 universe를 추가한다.


1.4 세팅 탭에서 위치(?)를 ko_KR.UTF8을 선택해서 한국어기반을 갖출 수 있도록 한다.

1.5 나머지는 터미널 버튼을 누른다음 명령으로 때운다. (sudo apt-get update 등등)


2. Customizer에서의 터미널 창에서 최대한 다른 것은 배제해야 하므로 다음 명령으로 기반만 갖춘다.


sudo apt-get install xorg alsa alsa-utils mesa-utils jstest-gtk fonts-nanum

sudo apt-get install --no-install-recommeds pulseaudio pulseaudio-utils slim wicd networkmanager openbox


이렇게 함으로서

소리가 나고(pulseaudio, alsa)

그래픽가속을 하고(xorg mesa)

네트워크에 접속을하며(wicd networkmanager)

최소한의 GUI세션에 접속을 할 수 있게 됩니다.(slim openbox)


물론 기반만 갖추었고 설정은 하나~~~도 안 했기 때문에 건드릴 것이 많지요.


3. PPSSPP는 그냥 PPA를 등록한다음 설치

sudo add-apt-repository ppa:ppsspp/stable
sudo apt-get update

sudo apt-get install ppsspp-qt


add-apt-repository에서 에러가 날 텐데요. PPA등록전에

sudo apt-get install python-software-properties software-properties-common


이 명령을 먼저 내려서 PPA등록용 스크립트들을 설치하도록 합시다. 왠지 쓸데없는 것이 설치된 듯하지만 귀찮은 것보단 이게 더 낫습니다.


4. 게임 이미지 전송용 FTP서버를 설치한다. 어떤 것을 설치해도 상관은 없지만 vsFTPD를 설치하겠습니다.


sudo apt-get install vsftpd


4.1 vsFTPd 설정

 sudo nano /etc/vsftpd.conf


다른 것은 기본값 혹은 마음대로 해도 되는데


write_enable=YES


이 옵션 만큼은 무조건 이렇게 해놓는다.


4.2 자신 있으면 SAMBA를 설치해도 되는데 나는 귀찮으니 PASS


5. slim을 설정해서 자동 로그온이 되도록 하자. slim은 데스크톱 관리자로 우분투의 lightdm보다 더 가볍고 세션 관리가 쉽기 때문에 선택


sudo nano /etc/slim.conf


제일 아래줄에 이렇게 적는다.

auto_login    yes
default_user  ubuntu


여기서 defulat_user는 Customizer에서 설정한 라이브유저 이름이다.(기본이 ubuntu라 그냥 여기서도 ubuntu)


6. openbox의 autostart를 만들어서 PPSSPP와 네트워크 관리자 등이 자동으로 실행되게 만들자.


sudo nano /etc/skel/.config/openbox/autostart


여기에 쉘스크립트 형태로 만들면 로그온 할때마다 자동으로 스크립트 형태로 실행된다.

sudo usermod -a -G audio $USER
sudo usermod -a -G video $USER
wicd-gtk &
start-pulse-audio-x11 &
xterm &
ppsspp --fullscreen
sudo shutdown -h now


다른 프로그램은 뒤에 &이 붙어있는데 (wicd-gtk는 무선랜 접속을 위함 만약 무선랜이 필요없으면 지워도 됨) ppsspp --fullscreen 뒤엔 없는 이유는 그 아래 명령어가 ppsspp가 종료될 때까지 실행되지 않도록 하기 위함이다.


보면 알겠지만 sudo shutdown -h now는 시스템 종료 명령어이다. 즉, PPSSPP의 실행이 끝나면 자동으로 시스템이 꺼진다는 것! 물론 xterm이나 wicd-gtk가 같이 실행되고 있으므로 Alt-Tab키를 눌러서 빠져 나올 수는 있다. 하지만 PPSSPP가 꺼지면 시스템 종료로 이어진다는 것!


7. 이제 라이브 ISO파일을 만들자!

터미널에 exit를 쳐서 빠져나오고

Customizer에서 ISO다시빌드 버튼을 누르면 시간이 지난뒤에 /home 폴더에 Ubuntu~~.iso파일이 하나 만들어졌을 것이다. 일단 궁금하니 VirtualBox나 Qemu같은 가상머신으로 테스트해보자. 부팅후에 PPSSPP가 실행되고 PPSSPP를 끄면 시스템이 꺼질 것이다. 이것이 잘 만들어졌다면 큰 그림은 완성


8. 이제 디스크를 준비합니다.

머신에 넣을 HDD를 USB to HDD기기로 USB장치로 인식되게 하셔야 합니다. (즉, 노트북에서 HDD를 꺼낸다음 연결합니다.) USB to SATA장비는 2만원에서 4만원 정도 합니다.


대충 이런형태의 물건이다. 저기 있는 SATA포트에 HDD를 연결하고 전원을 넣은다음 USB를 연결하면 PC가 외장하드로 인식한다.

Gparted를 실행!


보통은 /dev/sdb 혹은 제일 뒤쪽에 있는 것이 USB-HDD이니 해당 디스크를 선택한다.


그리고 파티션을 3개로 쪼개는데 포맷은 모두 ext4로 한다. 첫번째 파티션을 호환성을 위해 FAT32로 해도 상관은 없지만 ext4가 안정성은 더 높다.


예시로 든 것이므로 굳이 똑같이 따라할 필요는 없다. 다만 home-rw 파티션을 넉넉히 해주는 것이 중요하다. 게임 이미지가 저장될 공간이기 때문.


이 때 제일 처음 파티션은 ISO크기보다 약간 큰 정도면 되고(즉, ISO내의 내용물이 들어갈 자리) 두번째 파티션은 레이블을 casper-rw로 하고 40GB이상으로 잡는다. 나머지 파티션은 레이블을 home-rw로 하고 모든 용량을 투입하도록 하자.


2017. 5. 29 추가

파티션을 나눌 때 약 메모리 용량의 2배 크기 정도의 스왑파티션을 만들어두자. 가끔 메모리 부족으로 PPSSPP가 튕기는 경우가 있는데 PPSSPP가 종료되면 autostart 스크립트가 작동하면서 시스템이 종료되어버린다. 스왑을 잡아두면 이런 경우가 현저히 줄어들게 된다. 즉, 일종의 보험인 셈.


9. Unetbootin설치 및 실행


sudo apt-get install unetbootin

위 명령으로 unetbootin을 설치하고 실행하자. 아직 USB-HDD는 연결을 끊었다가 다시 연결하도록 하자.


위 스크린샷 처럼 Diskimage 라디오 버튼을 누르고 오른쪽의 ...버튼을 누른다음 아까 만든 ISO를 선택한다. 아래의 Drive는 제일 오른쪽 숫자가 1이 되는 장치를 선택한다.

(/dev/sdb1 혹은 /dev/sdc1 같이)


왜냐하면 아까 편집한 파티션의 제일 처음(아무런 레이블도 안 붙였던 ISO크기 정도의 파티션)이 바로 시스템 파티션이기 때문


그리고 Space used to preserve files across reboots라고 있는데 이것을 1MB라고 해 놓는다. 이 옵션이 바로 Persistent Live옵션의 필수다.


10. 아직 끝나지 않았다! 부트 옵션 수정!!!!!


USB-HDD내용물을 보면 1번 파티션에 ISO의 내용물이 거의 그대로 들어갔음을 알 수 있을 것이다. 여기서 몇가지 작업을 더 하도록 하자.


syslinux.cfg 파일을 관리자 권한으로 열자.


제일 위에 Timeout 100 이라고 쓰인 부분이 있다. 확 줄이자. 100초는 너무 길다. 한 5초?


그리고 부트옵션 중 Default 아래에

append  file=/cdrom/preseed/ubuntu.seed boot=casper

요렇게 써있는 부분이 있다.

여기에 몇가지 내용을 더 붙이자.


append  file=/cdrom/preseed/ubuntu.seed boot=casper lang=ko_KR keymap=kr net.ifnames=0 biosdevname=0

이렇게 해주면 무조건 한국어로케일로 부팅하게 된다. 그리고 무선랜의 인터페이스 이름이 wlan0로 만들어져서 다른 시스템에서도 wicd가 똑같이 작동 할 수 있게 된다.


그리고 casper-rw란 1MB짜리 파일이 보일 텐데 이건 그냥 삭제한다.


권한이 어쩌고 하면그냥 관리자 권한으로 밀어버리면 된다.


11. HDD를 다시 PC에 넣고 부팅


가상머신에서처럼 똑같이 작동한다면 시스템 구축에 성공한것이다. 이제 게임생활을 시작하자...가 아니라 네트워크 접속을 해서 게임 이미지를 밀어넣어야 할 시간이다.




12. 키보드를 이용해서 Alt-Tab키를 눌러 wicd-gtk를 띄우자. 일단 네트워크에 접속을 해야 뭘 밀어넣던지 말던지 할 것이 아닌가. (유선랜의 경우에는 별다른 문제없이 그냥 바로 접속 될것이다.)


네트워크에 접속이 완료되면 아래에 Wicd 창 아래에 IP주소가 뜬다. 이것을 가지고 다른 PC를 이용해서 FTP로 밀어넣으면 된다.


FTP프로그램은 파일질라가 제일 좋은데 다른 클라이언트들이 접속이 끊어지면 파일 전송도 같이 끊어버리는 반면 파일질라는 재접속을 해서라도 파일 전송을 끝내주기 때문에 굉장히 안정적입니다.


호스트에 게임머신의 IP를 넣고 사용자명에 아까 라이브 유저(기본값: ubuntu)를 적고 연결을 하면 그냥 연결이 됩니다. 왼쪽 로컬 사이트에서 PSP게임 이미지를 찾은 다음 그냥 업로드를 하면 끝입니다. 업로드 되는 곳은 /home/ubuntu(라이브유저이름)입니다.


13. 이제 실행해 볼까?


아쉽지만 소리 문제가 있을 수 있습니다. 난 HDMI를 통해 소리가 나오길 원했는데 엉뚱하게 노트북 스피커로 나오면(...)


Alt-Tab을 눌러서 xterm창을 띄웁시다.

pacmd set-card-profile 0 output:hdmi-stereo


이렇게 치면 HDMI로 소리가 나오게 될 겁니다. 우분투는 HDMI연결 여부를 확인하고 알아서 스위칭을 해주는데 이쪽은 그런 기능따윈 만들어 넣지도 않았으니 그냥 수동으로 해주는 것입니다.


게임패드를 USB포트에 연결하면 알아서 연결이 될 것이고 PPSSPP상에서 설정을 약간 하면 이후로는 키보드가 필요없을 것입니다. 가끔 게임 이미지 밀어넣을때정도?


이제 마음껏 게임을 해볼까요??후후...


개인적으로 XBOX패드보다는 PS패드가 이 시스템에는 더 잘 어울린다고 생각합니다.

PSP말고 다른 콘솔도 하고 싶으시다고요? 그럼 그냥 LAKKA쓰세요.

,

스프링 노트형 자작 케이스를 쓰고 있었는데 4년째되니 낡아서 여기저기 벗겨지고 난리가 났다

이게 After



저는 2012년에 싼 가격에 구입한 넥서스7 태블릿이 있습니다. 사실 그동안 써먹은 것을 생각하면 돈값은 정말 톡톡히 했습니다. 지금은 LiquidSky 접속단말로 써서 게임용으로 잘 써먹고 있지요.


그런데 여기에 제가 써오던 케이스가 너무 낡어서 모습이 영 아니더군요. 이 케이스도 사실 직접 만든 건데 너무 오래된 나머지 여기저기 해진 모습입니다. (제일 위 사진)


그래서 새로운 옷을 넥서스7에 입히기로 했고 그 결과가 바로 위의 사진입니다.


잘 모르겠지요? 사실 저는 이런 케이스를 선호하는 편이라 그렇습니다. 그런데 찾아보니 우리나라에는 쓸만한 케이스가 없군요. 나온지 한참 지난 모델이라 그런지 알리익스프레스나 아마존을 뒤져야 합니다. 귀찮습니다.


그래서 이번에도 새로 만들기로 했습니다. 대신 보통 케이스처럼 끼우는 것이 아닌 그냥 무식하게 양면테이프...


이번에 새로 만든 케이스의 준비물부터 알려드릴게요.

교보문고 핫트랙스에서 산 이번 준비물 레포트패드 A5하나 3M 탈부착식(나중에 뗄때 고생하기 싫으면 이걸로 할 것) 양면테이프 사실 실리콘 양면테이프라고 괜찮은게 있는데 아무리 찾아봐도 안 나온다...


저는 다이어리형 혹은 하드커버형 케이스를 좋아해서 하드커버가 달린 물건을 준비했습니다.


일명 레포트패드인데요. 레포트용지를 아래 사진처럼 넣어서 쓰는 케이스입니다. 교보문고 핫트랙스에 가보니 이런 물건을 팔고 있더군요. A5크기와 비슷하고 가격도 싼 편입니다. 12000원 정도


여기에 넥서스7을 붙일 수 있는 양면테이프가 필요합니다. 대신 일반적인 양면테이로는 택도 없고 탈부착이 가능한 "강력"양면 테이프가 필요합니다. 3M이라면 당연히 있는데 어떤 가게는 이런 테이프를 취급을 안 합니다. 오프라인을 애용하신다면 잘 찾아봐 주셔야 합니다.


이 양면 테이프는 케이스에 태블릿을 붙이는 역할을 합니다. 넥서스7이 대략 300g~400g 하므로 테이프 설명을 보고 한계 무게를 확인해야 합니다. (저 물건은 1kg을 버틴다고 합니다. 딱 맞지요.) 안 그러면 태블릿 무게에 케이스가 박살 날 수도 있습니다.


보너스로 들어온 레포트 용지. 나도 잘 안 쓰니 그냥 누구 가져다 줘야겠다.


A5크기가 넥서스7에 가장 흡사한 규격이더군요. 그래서 A5 규격을 샀습니다.


오른쪽의 저 부분은 볼펜 꽂이입니다. 태블릿이니 볼펜을 꽂을 일은 없지만 볼펜형 터치펜이라면 가능하겠지요. 3000원이면 구입가능하니 볼펜형 터치펜을 하나 사서 끼워넣어야겠습니다.


그리고 태블릿을 어느 위치에 고정 할 것인지 확인봤습니다.

이리저리 해봐도 저 위치가 가장 나았습니다.



붙이기전에 3M 강력 탈부차 양면 테이프 사진 한 장입니다.



그래서 이번 양면테이프는 어떤 식으로 붙일 것인지 확인을 했습니다. 6개인데 그냥 대충 붙여도 될 것 같았습니다.


저 돌기는 나중에 뗄 때 편하라고 3M에서 만든건데 보기가 영 안 좋아서 그냥 가위로 잘라내 버렸다.


테이프 작업 전에 확인




그냥 일반 레포트패드 케이스에 양면테이프로 태블릿을 붙였을 뿐인데 테블릿의 분위기가 확 바뀝니다. 상당히 마음에 드는군요. 태블릿 케이스를 이렇게 팔아도 될 것 같습니다. 요즘 충무로가니 레포트패드부터 다이어리까지 이런 물건이 엄청 나오던데요. 케이스만 구할 수 있으면 이런 식으로 만들어 쓸 수 있을 겁니다. 아니면 안 보는 양장본 책 껍데기도 좋고요. (물론 안 볼 정도로 가치가 떨어질 책이 있을 까 싶지만...)


일단 외부가 인조 가죽이라 상당히 고급스럽더군요. 양면 테이프와 케이스 값 합해서 23000원 정도 들었는데 앞으로도 태블릿케이스가 망가지면 이렇게 만들어야겠습니다. 참고로 아이패드 미니도 대충 이런 사이즈랍니다. 그러니까 넥서스7 케이스 못 구하면 아이패드 미니 케이스 사다가 아이패드 고정 틀 떼 버리고 이렇게 붙여버리는 것도 방법입니다.

,

NeptuniaRB1_Ko_Ep_ALL_171119.7z


훨씬더 개선된 패치는 이쪽으로...

http://schwarzer.tistory.com/21?category=802769




첨부된 파일은 Neptools(https://github.com/u3shit/neptools) 에다가 제가 약간 손을 댄 Hyperdimension Neptunia Re;birth1 파일을 넣은 한국어화 툴 킷입니다.



8장까지는 그럭저럭 번역을 했습니다만 이후로는 굳이 왜 하나 싶어서 버려둔 파일입니다.


현재 아이템 명과 이것저것 해 놓긴 했습니다. 몇몇 메시지에 대해서 그럭저럭 수준으로만 했습니다.


폰트 수정 계획 없습니다. 피드백이 없었기에 대사창 바탕체 그대로 갈 겁니다.


마음에 안 들면 아래에 설명을 했기에 본인들이 직접 하면 됩니다.


캐릭터 이름이 영문으로 나온다면 게임을 새로 시작하셔야 합니다. 세이브 파일에 캐릭터 이름이 기록되는 듯 합니다.


이 툴 킷은 스팀판에서만 확인했지만 GOG.com 판에서도 문제가 없다고 합니다. 개인적으로 스팀판은 문제가 많으므로 GOG.com에서 구매하셔야 편합니다.




이 게임이 출시된지도 좀 됐고 이제 슬슬 한국어 화 방법을 풀어도 될 것 같아서(이미지도 가능 하지만 그건 나중에 하고) 글을 올립니다.


일단 해당 압축 파일을 Neptunia re;birth1이 설치된 곳에 풀어버리면 한국어화 준비는 끝입니다. 일단 일본어 폰트의 일부를 한글 1023자로 교체했고(폰트가 좀 더럽습니다.) txt파일을 한국 로케일에서 읽기 쉽게 utf8로 저장했습니다.


~~.txt.utf 라는 형태로 되어있는 파일이 UTF8 형태로 저장된 파일입니다.

이 파일을 수정하고

~~.txt.utf.ko

라는 파일 이름으로 저장하면 번역작업은 끝이납니다.

그리고 준비된 to_cp932_utf_ko.py 스크립트를 실행하면 번역된 txt파일이 만들어 집니다.


그러니까... Neptools/SYSTEM/database 폴더의 경우



파일명에 .utf로 끝나는 파일을 연 뒤에(.txt 아닙니다! 이건 나중에 바뀔 파일!)



영문을 한국어로 번역하고



파일-다른 이름으로 저장을 누른 다음 ~~.ko를 붙입니다. (아래 로케일에 UTF-8주목!)



그리고 아래 to_cp932_txt_ko.py 파이썬 스크립트를 실행하면 번역된 문장이 게임에서 나오게 될 겁니다.


대사가 저장된 곳인 /GAME/event/script의 경우에는 각 숫자로 된 폴더안에 파일을 위랑 똑같이 작업한 다음(.utf 파일 열고 수정한 뒤에 utf 뒤에 .ko를 붙여서 저장)

위 이미지에 있는 to_cp932_txt_ko.py 파이썬 스크립트를 실행하시면 됩니다.


옆에 있는 곁다리 스크립트는 제가 사용한 것인데 뜯어보시려면 뜯어보세요. 좀 더럽긴 합니다만....


일단 이렇게 툴킷을 공개합니다. 재미삼아 이렇게 할 수 있구나 하실 수 있을 겁니다. 특히 to_cp932_txt_ko.py  이 스크립트를 자세히 보시면 한글을 한자로 바꾸는 것을 알 수 있는데 사실 폰트 파일의 일부를 원래 일본어 한자의 글자를 한글 폰트로 대체한 것이기 때문입니다.


,

리눅스에서 PC게임하는 방법은 대략 몇가지로 나뉩니다.


1. 리눅스용 게임하기

제일 확실하지만 제일 선택권이 없는 방법이지요. 리눅스용 게임이 많이 나왔지만 아직도 상당수 PC게임은 Windows만을 지원하고 있습니다. 그리고 국내제작 게임은 100% Windows에서만 돌아갑니다.


2. Wine으로 게임하기

그동안 제가 많이 써먹었고 지금도 많이 써먹고 있지요. Wine을 통하면 최소한 리눅스에서 Native하게 돌아가는 듯한 느낌이 듭니다. 그리고 얼마전 소개했었는데 리눅스에서 DirectX9지원이 되기 시작해서 퍼포먼스가 상당히 개선되었습니다. DirectX9 이후 게임이거나 DirectX9으로 돌리면 잘 안 되는 게임은 CSMT방식으로 굴리면 거의 Windows수준의 성능이 뽑히니 이 또한 문제가 없습니다. 하지만 아직도 일부 게임에선 라이브러리를 설치하거나 추가 삽질을 해줘야하는 문제가 있고 이를 컴퓨터로 게임밖에 할 줄 모르는 사람들에게 알려주기에는 그렇게 추천해 줄만한 방법은 아닙니다.


3. VM을 설치하기

VMware나 VirtualBox에서 게임을 굴리면 확실하게 돌아간다는 보장이 있습니다. 다만 가상머신을 쓰기 때문에 이미 성능이 반토막이 난다는게 문제입니다. 그리고 VM의 그래픽가속 드라이버는 아직도 갈길이 먼 수준이라 OpenGL 렌더링은 몰라도 D3D는 포기하는 것이 좋습니다.


4. Windows컴퓨터에서 스트리밍

무식하면서도 어찌보면 확실합니다.

그냥 게임용 Windows컴퓨터를 하나 장만하는 겁니다. 참 쉽죠?


이중에서 4.의 방법을 쉽고 단단하게 만든 솔루션이 바로 LiquidSky란 물건입니다.

https://liquidsky.tv/

특이사항으로는 클라우드 시스템에 Windows 가상머신을 하나 만들고 여기에 접속해서 게임을 하는 겁니다. 그리고 시간당 요금을 받는 방식인데 우리나라 PC방요금과 거의 비슷한 수준입니다. 그리고 Windows 데스크탑하나를 빌려주는 형식이 꼭 PC방과 거의 닮았지요.


제일 왼쪽은 시간 종량방식(시간당 0.5~1달러수준) 가운데는 매달 14.99달러씩 가져가면서 80시간(고성능 구동시 40시간)기본 제공 필요시 추가 구매 오른쪽은 매달 39.99달러에 무제한이용(!) 대략 PC방 요금생각하면 쉽다. 만약 하드코어 게이머라면 제일 Unlimited를 질러도 크게 문제 없다!

아직은 Beta단계라 불안정한 면도 있지만 협력업체가 아주 후덜덜합니다.

서버시장 1위 IBM

소프트웨어 괴물 Microsoft

(안드로이드)모바일에 관해서 거의 도가 터버린 Samsung


덕분에 Beta라고 해도 Beta가 아닌 것 같습니다. 요금을 받는 수준인데 Beta라 보는 것도 웃기긴 하네요.


홈페이지에서는 클라이언트로 Android, Windows, Mac, Linux를 지원한다고 합니다. 그런데 Linux는 말이 좋아 Linux클라이언트지 사실은 Wine으로 굴리는 클라이언트입니다. 그런데 그게 또 잘 돌아갑니다. Wine에 무슨짓을 한건지는 잘 모르겠지만 뭐 굴러만 가면 좋은거죠 뭐.


일단 가입을 해야 시작을 할 수 있겠지요. 가입절차는 간단합니다. 제일 첫 페이지에서 Request Beta Access를 누르면 아래 화면이 나오는데요. 순서대로 쭉 적고 Add me to Beta를 누르면 이메일이 날아옵니다. 거기서 Confirm을 하시면 됩니다.


confirm이후 데이터센터를 고르라고 하는데 자그마치 서울에 서버가 있습니다!!!

그냥 서울을 고르도록 합시다. 가끔 속도테스트해보면 도쿄가 서울보다 빠를 때도 있는데 사실 이 서비스가 알게 모르게 소문이 나서 한국 이용자가 좀 됩니다. 그에비해 일본은 PC게임시장 자체가 워낙 좁아서 필요하면 도쿄로 잠깐 이사를 가도 됩니다. 사실 클라이언트에서 설정 가능합니다.


마지막으로 돈 문제가 있는데요. 3시간짜리 평가를 하시려면 좀 많이 기다리셔야 하고 그냥 돈을 내시면 바로 이용 가능합니다. 전 그냥 귀찮아서 종량제 질렀습니다. 제가 게임을 많이 하는 것도 아니고 기다리다가 한 세월 걸릴 것 같아서 그냥 7000(10시간)질렀습니다. 필요하면 더 구매하면 되니까요.


클라이언트는 https://liquidsky.tv/en/downloads 여기에서 받으시면 되고 자그마치 안드로이드도 지원합니다. PlayStore에 있으니 이를 사용하시면 편리합니다. 다만 안드로이드의 경우 터치방식으로 구동하는 조이패드가 뜨는데 그냥 패드 하나를 블루투스나 USB OTG로 연결하는 것을 추천합니다. 더럽게 안 맞더라구요. 아니면 키보드(?)를 하나 더 붙이시던가요.


Linux용 클라이언트는 제공되는 것이 생각보다 잘 구동이 안 되서 직접 Wine으로 굴리는 것을 추천합니다.Windows 클라이언트를 다운로드 받고 Wine으로 실행하면 그냥 실행 잘 됩니다. 어이없을 정도로 너무 잘 되서 더 황당할 지경이네요.


https://cdn.liquidsky.tv/assets/liquidsky.exe

이걸 다운로드 받으신 다음 그냥 Wine으로 돌리시면 됩니다. 참 쉽죠?

여기서 그냥 Yes를 하면 업데이트까지 문제 없습니다.

왠만하면 그냥 HIGH로 하자. Ultra로 해봐야 게임영상은 거기서 거기...

로그인하고 성능 설정을 하시면 게임을 하실 준비가 됩니다. 참고로 패드 지원이 약간 열악해서(Wine이..) 이전 글인 http://moordev.tistory.com/139 여기의 방법을 쓰셔야 패드 지원이 될겁니다. 짜증나기는 하는데 뭐 어쩌겠습니까...


Windows Server 2012에 Nvidia Grid K Xeon CPU에 8GB의 메모리를 제공중이다. 이정도면 현재 보통 PC방 수준의 성능은 뽑아내준다.

바탕화면을 보시면 아시겠지만 스팀은 미리 설치되어있습니다. 스팀을 실행하시고 게임을 설치, 실행해주시면 됩니다. 인터넷 속도는 데이터센터라 무지막지한 속도로 다운로드되니 걱정 안 하셔도 됩니다.

클라우드에서 Portal2를 굴리는 모습입니다.

,

USBIP란 프로젝트가 있습니다. USB over IP를 줄여서 부르는 겁니다.


즉 특정 IP주소에 있는 USB장치를 내 장치에 있는 것처럼 사용하는 방법입니다. 이를 이용하면 지구 반대편에 있는 USB장치(예를 들면 시리얼통신을 쓴 산업장비 등등)을 내 컴퓨터에서 내 장치에 달린 것 마냥 쓸 수 있는 겁니다.


리눅스 커널 3.6 이후에는 이 프로젝트가 커널에 들어가게 되어 USBIP 라이브러리를 설치하는 것 만으로도 이런 것을 사용 할 수 있게 되었습니다. 다만, 바인딩하는 것이 귀찮고 명령이 좀 깁니다. 그리고 Windows에서 사용이 좀 힘듭니다.


그래서 VirtualHere란 업체에서 이를 쉽게 GUI로 만들고 사용할 수 있게끔 결과물을 내놓았습니다. 게다가 안드로이드에 한해서지만 모바일서버를 지원해서 안드로이드에 붙은 USB장치를 PC에서 사용하는 것도 가능해 졌습니다. 심지어 스팀링크에서도 사용이 가능해서 용도가 무궁무진합니다.


일단 저는 안드로이드에 유선형 Xbox컨트롤러를 달아 이를 PC에서 사용 하는 것으로 해보겠습니다. (이렇게 하면 무선 컨트롤러 비스무리하게 쓸 수 있습니다. 스마트폰이 거시기 하지만.


https://www.virtualhere.com/


일단 USB장치가 연결된 곳에 서버프로그램을 설치하고 장치를 사용하고자 하는 곳에 클라이언트를 설치해야 합니다.


서버프로그램은 Windows, Linux, OSX, Android를 지원하고

클라이언트는 Windows, Linux, OSX를 지원합니다. 사실상 3대 대표 OS를 다 지원하는 겁니다. 안드로이드서버가 제일 독특합니다.


서버든 클라이언트든 리눅스에서는 USBIP를 설치해야합니다. 다른 OS는 드라이버를 따로 설치해야합니다. 어찌보면 리눅스가 더 간편합니다.


sudo apt-get install usbip


그리고 홈페이지에서 서버프로그램을 다운로드받아서 설치해야 하는데 온갖 버전들이 즐비합니다. 그 이유는 특정 보드에 최적화된 버전을 준비한 탓인데요. 제일 아래에 가면 안드로이드 버전도 있습니다.


32비트의 경우

wget https://virtualhere.com/sites/default/files/usbserver/vhusbdi386

sudo chmod +x vhusbdi386

sudo ./vhsubi386 -b


이렇게 해주시고


64비트의 경우

wget https://virtualhere.com/sites/default/files/usbserver/vhusbdx86_64

sudo chmod +x vhusbdx86_64

sudo ./vhusbdx86_64 -b


이렇게 해주시면 서버세팅 완료입니다. 안드로이드는 그냥 Play Store에서 서버프로그램을 다운로드 받은 다음 그냥 앱을 실행 하면 됩니다. 이건 설명하고 자시고 할 것도 없네요.


설명을 보시면 제약사항이 있는데 무료로 USB장치는 하나만 된다고 합니다. 일단 저희는 시험만 해보는 것이니 일단 그냥 넘어가 봅시다.


이번에는 클라이언트를 설치하도록 합시다. 다른 PC에서 마찬가지로 USBIP 라이브러리를 설치합시다. OSX나 Windows는 당연히 드라이버를 설치해야 하고요.



https://virtualhere.com/usb_client_software


아래에 보시면 클라이언트가 있는데 GUI와 CLI버전 두가지를 준비해두었습니다. 저희는 귀찮기도 하고 이쪽이 더 편리하니 GUI버전을 다운로드 받기로 하지요.


다운로드 받은 후에는 서버와 마찬가지로 실행속성을 줘야 합니다.

sudo chmod +x vhuit32

혹은

sudo chmod +x vhuit64


GUI로 하시려면 아래 스크린샷을 보시면 됩니다. 속성을 여신 뒤에 실행 허용에 체크만 해주시면 됩니다.


실행속성 주기. 리눅스사용자라면 자주 쓰는 기능입니다. 근데 보통 귀찮아서 그냥 CLI쓰기도...

서버가 동일한 네트워크에 있는 가정하에 클라이언트를 실행하고 잠시 기다리면 서버가 자동으로 검색이 되고 장치를 사용 할 수 있게 됩니다. 저는 안드로이드에 Xbox컨트롤러를 연결하고 기다렸습니다.



저는 바로 연결이 되는데 아닌 분들도 있을 겁니다. 그럴 때는 해당 장치에 오른쪽 버튼을 누르고 Use를 실행하시면 됩니다.


실제로 잘 되더군요. 딜레이도 크게 없었습니다. 요새는 와이파이 속도가 엄청 빠르다보니 USB정도는 그냥 넘어가는 것 같습니다.


virtualHere란 이 프로젝트는 범용성이 워낙 좋아서 다른 용도로도 충분히 사용이 가능할 것 같습니다. 무엇보다 키보드와 마우스조차 사용가능해서 VNC를 대신할 수 있을 것 같기도 하네요.


보너스..


라즈베리파이를 USB 서버로 만들기(물론 라이센스가 있어야 여러개를 쓸 수 있습니다.)


https://www.virtualhere.com/oem_faq

여기 내용입니다.


SSH로 접속후에 아래 내용을 싹 긁어서 넣어주면 됩니다. 그러면 끝.


wget https://www.virtualhere.com/sites/default/files/usbserver/vhusbdarm
sudo chmod +x ./vhusbdarm
sudo mv vhusbdarm /usr/sbin
wget http://www.virtualhere.com/sites/default/files/usbserver/scripts/vhusbdpin
sudo chmod +x ./vhusbdpin
sudo mv vhusbdpin /etc/init.d
sudo update-rc.d vhusbdpin defaults
sudo reboot

이렇게 하면 Virtualhere 서버가 라즈베리파이에 만들어지게 됩니다.


그리고 먼곳에서 접속하기 위해서는 7575 TCP 포트를 열어주셔야 합니다. 왜냐하면 VirtualHere는 7575번 포트로 USB를 원격 접속하기 때문입니다.

,

2000년대 초반에는 대부분 게임의 해상도가 640x480~1024x768이었습니다. 덕분에 대다수 이 당시에 나온 게임들은 이 해상도만 지원하곤 합니다. 하지만 2010년대인 지금 이 정도의 해상도는 계단이 보이고 그래픽이 영 아니게 보입니다.


그래서 이러한 그래픽의 향상을 위해 나온 패치들이 있습니다. 게임제작업체에서 만든 것도 있지만 반대로 유저들이 해킹으로 만든 것도 있습니다. 이런 패치들이 모여있다면 편하겠지요.


바로 https://thirteenag.github.io/ 여기입니다.


여기의 패치를 사용하면 와이드 해상도가 지원이 안되는 게임도 와이드 해상도까지 지원이 됩니다. 심지어 모니터의 네이티브 해상도까지 가능합니다. 요즘 모니터는 4k까지 나오니 엄청난 그래픽으로 보게 되는 겁니다.


사실 요즘 나오는 그래픽을 옵션 타협해서 하는 것보다 옛날 게임을 풀옵션으로 하는 것도 나름 재미입니다.


일단 저는 이 게임을 선택했습니다.



지금봐도 상당히 잘 만들어진 게임이다. 일단 자동차 모델링이 현실적이라 더 그렇게 보이는 것 같기도 하지만.


Need for Speed Underground

2003년 작입니다. 지금 봐도 그래픽이 그럭저럭 봐 줄만 합니다. 사람의 텍스쳐가 좀 안습이기는 하지만 이건 자동차를 보는 게임이지 사람을 보는 게임은 아니니까요.


우분투에서 Gallium Nine을 사용할 경우 검은 화면에서 진행이 안 되는 버그가 있는데 이 패치를 쓰면 버그가 해결됩니다. (이게 목적이었어..)


원인은 최적화를 위해 640x480에서 메뉴를 띄우고 본 게임이 들어가면 해상도를 바꾸는 방식을 사용하는데 여기서 Gallium Nine 버그가 있습니다.Widescreen Fix를 하면 해상도가 고정되면서 버그가 회피되는 겁니다.



Wine에서 사용하실 때는 Wine 설정에서 이렇게 설정해주셔야 합니다. 게임마다 다르지만 NFSU는 이렇게 해주셔야 합니다. 이유는 압축 파일안에 dinput8.dll파일을 사용해서 해상도를 구현하기 때문입니다. 만약 다른 게임이라면 다른 방식을 써야 하겠지요.


스프린터셀은 d3d8.dll이더군요. 패치하실 때 dll파일을 꼭 보고 설정해주셔야 편합니다.


한번 고성능 컴퓨터를 이용해서 한번 과거의 게임을 즐겨보시는 것은 어떨까요? 색다른 기분이 들겁니다.

,


예전에 학생시절에는 PSP를 참 갖고 싶어했습니다. 지하철에서 플레이 하는 사람들을 보면 참 부러웠었지요.

그리고 세월이 지나 지금. PSP는 과거의 유물이 되었고 지금은 다들 스마트폰을 들고 다닙니다. 그리고 PPSSPP란 에뮬레이터가 나와서 PSP게임을 굴릴 수 있게 되었습니다.


하지만 터치인터페이스는 무진장 게임하기 불편했습니다. 그래서 스마트폰용 조이패드를 차던중 이런 녀석이 있더군요.



로지텍 파워쉘입니다. 문제는 이놈은 아이폰 전용이었고 범용성은 내다 버린 것이 문제였습니다. 사실 전 이런놈이 있는 줄도 몰랐는데 누가 컨셉 겹친다고 해서 찾아봤더니 있더군요. 결국 덤핑했다는 후문이 있지만...



어쨌거나 저는 대충 연구실에서 시간 나는대로 게임용 컨트롤러를 만들기로 했습니다.


그래서 만든 것이 바로 위의 물건입니다. 아직 하우징은 만들어지지 않았고 동작만 되는 형편입니다.


일단 제작을 위한 준비물은...



일단 준비물은 아두이노를 썼으니 아두이노가 필요하겠지요. 크기가 크면 문제가 많으므로 작은 모델이 필요합니다. 그리고 조이패드로 인식 시켜야 했으므로 Leonardo와 호환되어야 했지요. 그래서 찾은 모델이 이 모델입니다. 위의 것은 SparkFun 정품이고 아래의 물건은 그것의 호환 제품입니다. 어떤 것을 써도 상관없습니다. 개인적으로 호환품도 크게 문제는 없었습니다.


(프로 마이크로 입니다. 프로 미니, 나노 아니에요!)




버튼도 SparkFun제품을 사용했습니다. 이런 식을 나온 버튼이 상당히 누르는 것이 좋더군요. 하우징 설계할 때도 편리합니다. 뭣하면 다른 스위치를 써도 그만입니다.


조이패드도 SparkFun 호환품으로 구입. 사실 아두이노 키트사면 들어있어요.



그리고 대망의 스마트폰 고정 가이드는 없는 것 빼고 다 판다는 Coms의 제품입니다. 진짜 이 회사의 내부가 궁금합니다. 매번 있을까? 라고 생각하면 있습니다. 우리나라에서 이런 회사가 있다는 것이 자랑스럽습니다.



그외에 준비물로는 부품 고정용 만능 기판 PCB(대충 사서 톱으로 썰어야 합니다.)와 USB OTG케이블, 그리고 USB micro B 케이블(스마트폰 데이터 케이블도 상관없습니다.) 다 Coms에서 팔아요....


음...배선을 깜빡했네요. 배선은.... 그냥 아두이노 책을 보시고 해주시길 바랍니다.(...)


버튼들은 GND와 각 디지털 핀.(Tact스위치는 4개의 다리 중 대각선으로 해주시는 것이 정신건강에 좋습니다. 2개씩은 사실 하나의 다리라 헷갈리면 X되요.


조이패드는 핀배열에 맞게 해주시면 됩니다.


5V-5V

GND-GND

VRx-A0

VRy-A1

SW - 디지털핀 아무거나


그리고 프로그램은 우선 라이브러리를 설치해야 하는데

https://github.com/MHeironimus/ArduinoJoystickLibrary


이것을 사용합니다.

파일 다운로드는 https://github.com/MHeironimus/ArduinoJoystickLibrary/archive/master.zip


위 파일을 다운로드 받은다음


아두이노 IDE에서

스케치- 라이브러리 가져오기-Add Library를 선택하고

해당 파일을 선택합니다.


그리고 아두이노에 넣을 스케치는 다음과 같습니다.


 // Simple example application that shows how to read four Arduino
// digital pins and map them to the USB Joystick library.
//
// The digital pins 9, 10, 11, and 12 are grounded when they are pressed.
//
// NOTE: This sketch file is for use with Arduino Leonardo and
//       Arduino Micro only.
//
// by Matthew Heironimus
// 2015-11-20
//--------------------------------------------------------------------

#include <Joystick.h>

void setup() {
  // Initialize Button Pins
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
  pinMode(15, INPUT_PULLUP);
  pinMode(16, INPUT_PULLUP);
  // Initialize Joystick Library
  Joystick.begin();
}

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 0;
const int deadZone = 30;

// Last state of the button
int lastButtonState[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//int lastButtonState[4] = {0,0,0,0};
int X=0;
int Y=0;

void loop() {

  // Read pin values
  for (int index = 0; index < 17; index++)
  {
    int currentButtonState = !digitalRead(index + pinToButtonMap);
    if (currentButtonState != lastButtonState[index])
    {
      Joystick.setButton(index, currentButtonState);
      lastButtonState[index] = currentButtonState;
    }
  }
  X=analogRead(A0);
  Y=analogRead(A1);
  X=map(X,0,1023,127,-127);
  Y=map(Y,0,1023,-127,127);
  Joystick.setXAxis(X);
  Joystick.setYAxis(Y);

  delay(50);
}


간단하죠? 좀 반응이 느리다 싶으시면 delay를 20정도로 줄여주시면 됩니다. 저는 가끔 느린 것을 느끼기는 하는데 그냥 냅두고 있습니다.


그렇게해서 만들어진 대망의 물건



저는 실력이 미천하여 이정도밖에 못했지만 실력 좋으신 분들은 훨씬 더 좋은 물건을 만들 수 있을 거라고 봅니다.




==================2017. 5. 25======================


아두이노용 조이스틱 라이브러리의 버전이 업그레이드 되었습니다.

https://github.com/MHeironimus/ArduinoJoystickLibrary


이전과 동일한 곳이지만 그전에는

X,Y 축과 버튼까지만 지원했지만 이제는 거의 표준이라 할 수 있는

아날로그 스틱

HAT 방향키

트리거

버튼


이렇게 지원합니다. 즉, 엑스박스 패드의 형식을 그대로 지원하고 엑스박스 패드를 지원하는 게임에서 정상적으로 작동되게 할 수 있습니다.


제가 만든 구조는


왼쪽 4개의 버튼은 방향키로

아래의 아날로그는 HAT으로

오른쪽은 버튼으로 인식되게 했습니다.


하지만 마음을 먹으면 아날로그 스틱을 2개 달고 엑스박스 패드처럼 만들 수도 있는 것이지요.


그래서 이번에 수정한 소스를 공개합니다.


#include <Joystick.h>

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
  5, 1,                  // Button Count, Hat Switch Count
  true, true, false,     // X and Y, but no Z Axis
  false, false, false,   // No Rx, Ry, or Rz
  false, false,          // No rudder or throttle
  false, false, false);  // No accelerator, brake, or steering


int lastDpadState[]={0,0,0,0};
int lastButtonState[]={0,0,0,0,0,0,0};
int lastSWState=0;

void setup() {
  // Initialize Button Pins
  pinMode(10, INPUT_PULLUP);//A
  pinMode(14, INPUT_PULLUP);//B
  pinMode(15, INPUT_PULLUP);//X
  pinMode(16, INPUT_PULLUP);//Y
 
  pinMode(6, INPUT_PULLUP);//Up
  pinMode(8, INPUT_PULLUP);//down
  pinMode(7, INPUT_PULLUP);//left
  pinMode(9, INPUT_PULLUP);//right
 
  pinMode(2, INPUT_PULLUP);//HAT_SW

  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);
 /*not using pin Num
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);

  digitalWrite(11,LOW);
  digitalWrite(12,LOW);
  digitalWrite(13,LOW);  
  */
  //A0=X A1=Y

  // Initialize Joystick Library
  Joystick.begin();
  Joystick.setXAxisRange(-1023, 0);
  Joystick.setYAxisRange(-1023, 0);

  Joystick.setRxAxisRange(-1, 1);
  Joystick.setRyAxisRange(-1, 1);
}

void Analog()
{
  int x = analogRead(A0);
  int y = analogRead(A1);
 
  Joystick.setXAxis(-x);
  Joystick.setYAxis(-y);
}

void Buttons()
{
  for(int index=0; index < 7 ;index++)
  {
    int currentButtonState = !digitalRead(index+10);
    if (currentButtonState !=lastButtonState[index])
    {
      //Joystick.setButton(index, currentButtonState);
      switch (index)
      {
        case 0://A
          Joystick.setButton(0, currentButtonState);
          break;

        case 4://B  
        case 5://X
        case 6://Y
          Joystick.setButton(index-3,currentButtonState);
          break;
          
        default:
          break;
      }
      
      lastButtonState[index]=currentButtonState;
    }
  }
 
}


void Dpad()
{
  for (int index = 0; index < 4; index++)
  {
      int currentDpadState = !digitalRead(index+6);
      if (currentDpadState != lastDpadState[index])
      {
        switch(index){
          case 0://UP
            if (currentDpadState == 1) {
              Joystick.setRyAxis(1);
            } else {
              Joystick.setRyAxis(0);
            }
            break;
          
          case 1://left
          if (currentDpadState == 1) {
            Joystick.setRxAxis(-1);
          } else {
            Joystick.setRxAxis(0);
          }
          break;
            
          case 2://down
          if (currentDpadState == 1) {
            Joystick.setRyAxis(-1);
          } else {
            Joystick.setRyAxis(0);
          }
          break;

          case 3://right
          if (currentDpadState == 1) {
            Joystick.setRxAxis(1);
          } else {
            Joystick.setRxAxis(0);
          }
          break;
            
        }
        lastDpadState[index] = currentDpadState;
      }
  }
}


void HAT()
{
  bool valueChanged =false;
  for (int index = 0; index < 4; index++)
  {
      int currentDpadState = !digitalRead(index+6);
      if (currentDpadState != lastDpadState[index])
      {
        valueChanged =true;
        lastDpadState[index] = currentDpadState;
      }    
  }

 
  if (valueChanged) {
      
    if ((lastDpadState[0] == 0)
      && (lastDpadState[1] == 0)
      && (lastDpadState[2] == 0)
      && (lastDpadState[3] == 0)) {
        Joystick.setHatSwitch(0, -1);//HatSwitch0 is not changed
    }
    if (lastDpadState[0] == 1) {
      Joystick.setHatSwitch(0, 0);
    }
    if (lastDpadState[1] == 1) {
      Joystick.setHatSwitch(0, 90);
    }
    if (lastDpadState[2] == 1) {
      Joystick.setHatSwitch(0, 180);
    }
    if (lastDpadState[3] == 1) {
      Joystick.setHatSwitch(0, 270);
    }
  }//value Changed()
}
void SW()
{
  int currentSWState = !digitalRead(2);
  if(lastSWState != currentSWState)
  {
    Joystick.setButton(4, currentSWState);
    lastSWState=currentSWState;
  }
}

void loop()
{
  Analog();
  //Dpad();
  HAT();
  Buttons();
  SW();
  delay(2);
}


회로 연결은


0번 버튼은 10번핀에

1번 버튼은 14번핀에

2번 버튼은 15번핀에

3번 버튼은 16번핀에


방향버튼(D-PAD)는

위버튼은 6번핀

왼쪽버튼은 7번핀

아래버튼은 8번픈

오른쪽 버튼은 9번핀 으로 연결합니다.


D-PAD는 HAT0로 인식되게 됩니다.


그리고 아날로그는 X축은 A0 Y축은 A1로 연결합니다.

만약 방향이 반대로 인식될 경우에는 위 소스에서 Analog()함수를 찾으신 다음


  Joystick.setXAxis(-x);
  Joystick.setYAxis(-y);


이 둘에서 -를 지워주시고 Seup()안의


  Joystick.setXAxisRange(-1023, 0);
  Joystick.setYAxisRange(-1023, 0);


이 두줄을 삭제해 주시면 됩니다.


아날로그 스틱을 눌렀을 때 스위치는 2번 핀에 연결했습니다.

제가 사용한 Arduino Pro Micro의 구조상 이 구조가 가장 간단해서 이렇게 만들었습니다.


코드나 회로에 자신있으신 분들은 제대로 만드실 수 있을 겁니다.

,


작은 스마트폰에 컴퓨터의 화면을 띄우는 것을 목적으로 삽질을 했습니다. 사실 VR용으로도 써 먹어보려고 한 것도 있습니다. VNC도 있고 많이 있지만 저는 여기서 한 걸음 더 나가 PC의 HDMI포트, 혹은 외부 모니터 단자를 사용하여 하드웨어 적으로 네트워크로 뿌리는 것을 목표로 했습니다. 다행히 VNC 수준의 절망적인 속도는 안 나오더군요.


그러기 전에 하드웨어 신호를 직접 네트워크로 뿌려야 하니 필수 하드웨어인 캡쳐보드가 무엇인지 알아야겠습니다. 캡쳐보드는 말 그대로 영상입력장치입니다. 비싼것은 100만원이 넘어가는데다 그나마 쓸만한 놈도 10만원 안팎합니다. PCI슬롯이 없는 노트북에서 사용하려면 Firewire나 USB를 써야 하는데 요새는 Firewire도 없지요. 그 USB방식 캡쳐보드 중 그중 제일 싸구려에 제일 만만하고 제일 여기저기 사용되는 물건이 Easycap(DC-60)입니다. 특징으로는 3만원도 안 되는 가격에 짝퉁이 좀 있어서 대략 4개 업체에서 같은 이름으로 팔고 있습니다.


STK

somagic

UTV007

eMpia


대략 알려진 것은 이렇습니다. 이중 제일 만만한 것이 STK칩셋을 사용한 제품이지만 문제는 어떤게 STK칩인지 모른다는 겁니다. 제일 리눅스에서 사용하기 고통스러운 제품은 somagic칩셋입니다. 다른 칩셋은 커널에 드라이버가 내장되어 금방 잡히지만 somagic은 Broadcom제품처럼 따로 펌웨어를 넣어줘야하는 문제가 있습니다.


저는 일단 국내에서 구하기 쉬운 쪽을 택하기 위해서 조금 신기해보이는 것은 다 파는 컴스마트에서 찾아봤습니다. 역시 있더군요. (하여간 여기는 제가 갖고 싶다고 생각들면 어느새 들여놓습니다. 신기한 회사입니다.)


헐 같은 이름의 물건이 3개다.

이중에서 가운데있는 물건이 eMpia칩셋입니다. 다른 것은 어떻냐고요? 다 Somagic입니다. 오른쪽의 것을 구입했다가 눈물 흘렸던 것은 비밀입니다.


Somagic만 피하면 일단 리눅스로 캡쳐하는 것은 어렵지 않습니다. 드라이버가 내장되어 있어서 별 문제가 없거든요. STK는 Lanstar란 업체에서 수입하는 것을 보이는데 구입해서 뜯어보지 않으면 모른다고 합니다. 그냥 참고하세요.


그럼 리눅스에서 캡쳐는 어떻게 할까요?


일단 제일 쉬운 방법은 http://easycap.blogspot.kr/p/easyview-n-cap.html 이곳에 있는 TVcap 스크립트를 사용하는 겁니다. 일단 실행만 하면 GUI로 옵션을 선택할 수 있어서 편리합니다. 특히 기능이 워낙 충실해서 쓸 곳이 많은 데 EasyCap 사용시 얼어붙어버리는 VLC의 버그를 회피 할 수 있어서 굉장히 유용한 스크립트 입니다. 그러나 단순 화면 재생도 VLC나 Mplayer가 설치되어 있어야 합니다. 그런데 이 중 하나라도 설치 안되어있는 시스템이 있던가요?


또 다른 것은 xawtv를 쓰는 것인데 아마도 제일 가벼운 영상캡쳐 프로그램이 아닐까 생각합니다. 역시 TV를 위해서 나온 것이지만 인터페이스만 익숙해지면 편리합니다. 모르겠으면 화면에 마우스 오른쪽 버튼을 눌러보세요. 하지만 이 프로그램은 재생과 녹화만 잘 됩니다.


그리고 마지막 녀석은...motion 입니다. 뭐냐고 하시는 분이 계실 것 같은데 motion은 라즈베리파이에서 카메라 스트리밍관련 내용을 보면 여기저기에서 쓰이는 것을 알 수 있습니다. 쉽게 말해 영상에서 움직임을 보기위해 만들어진 프로그램인데 웹으로 스트리밍하는 기능이 내장되어 있어서 이걸 써서 다른 플레이어와 연동되게 할 수 있습니다. 제가 이번에 이용할 것은 라즈베리파이와 연동을 해서 스마트폰에 뿌리기까지 하는 것이므로 이걸 쓸 겁니다.



1. 라즈베리파이에 Raspbian을 설치합니다. 라즈비안 설치는 https://www.raspberrypi.org/downloads/raspbian/ 여기서 다운로드 받아서 사용하시면 됩니다. 자세한 내용은 구글 검색하면 쏟아져 나오니 찾아보시면 됩니다. 이름만 보셔도 아시겠지만 데비안 기반입니다.


간단히 SDCARD에 라즈비안을 설치하는 방법은


SDCARD를 넣고 SDCARD의 주소를 확인한 다음 (Gparted를 쓰면 편합니다.)

sudo dd if="라즈비안이미지" of="SDCARD주소 ex) /dev/sdb" bs=4M


이렇게 하면 SDCARD에 라즈비안이 설치됩니다. 해당 SDCARD를 라즈베리파이에 넣으면 일단 라즈베리파이는 준비됩니다.


2. Raspbian 설치후 motion세팅


 Raspbian도 데비안이니 명령어도 동일합니다. (SSH로 접속하면 더욱 편리합니다. 라즈비안은 기본적으로 SSH접속이 허용되어 있습니다. 로그온 이름은 pi 이고 password는 raspberry입니다. raspi-config에서 꼭 password를 바꾸세요)


sudo apt-get update

sudo apt-get install motion


끝입니다.


그리고 /etc/motion/motion.conf 파일을 수정해야 하는데 수정된 파일을 올려놓겠습니다.

motion.conf

여기서 장치 이름을 /dev/video1로 되어 있는 것을 /dev/video0로 바꿔주셔야 합니다.


3. Easycap 연결

Easycap을 라즈베리파이의 USB포트에 꽂습니다. 즉 라즈베리파이에 영상신호를 넣는 것입니다. 해당 영상은 어떤 것이든 상관 없지만 RCA(AV코드)이므로 여기에 맞게 쓰는 것이 좋습니다. 만약 HDMI를 사용한다면 HDMItoAV같은 장비를 써서 RCA로 넣어야 합니다. 만약 RCA가 너무 구리다고 생각하시면 S-Video를 쓰시면 조금 낫습니다. 화질 문제는 싸구려에게 많은 것을 바라면 안 됩니다. (RCA는 케이블 품질 특성을 많이 탑니다. 그래봐야 HDMI에 비해 현저히 구리지만)


EasyCap같은 캡처보드는 HDMI따위는 지원을 안하기에 이런 장비가 필요하다. 대만에서 만들어진 것으로 추정되는 HDMI to AV 제품 약 2만원 정도



자 이제 motion을 실행해 봅시다.


sudo motion(관리자 권한 필수 싫으면 /dev/video0를 666으로 세팅하면 됩니다.(sudo chmod 666 /dev/video0)


X없이 사용하시는 것이 좋습니다. 라즈베리파이의 IP주소를 알아내고 스마트폰용 웹브라우저에서 다음과 같이 넣어봅시다.

(안드로이드는 모바일 크롬 추천...아이폰은 사파리 추천)


http://라즈베리파이IP주소:8081


이러면 RCA로 입력된 영상이 뜹니다. 여기서 녹화를 하신다거나 추가 작업을 하신다면 라즈베리파이외의 같은 네트워크상에 있는 다른 PC에서 VLC를 쓰시면 편리합니다.


즉 포트만 열어주시면 아프X카 같은 사이트를 이용하지 않고 직접 웹에서 방송하는 것도 가능합니다. 대역폭 문제가 있지만 우리나라 통신망의 대역폭은 무지막지합니다. 별로 문제가 없습니다.


이렇게 VLC로 스트리밍 받거나 (화면은 Xbox One의 화면 HDMI밖에 안 나와서 하는 수 없이 컨버터를 구입했다.)

이렇게 크롬으로 직접 영상을 전송 받을 수도 있다. 만약 웹으로 받으려면 img src="라즈베리주소" 태그면 충분하다



문제는 사운드인데 

cvlc -vvv alsa://plughw:0 --realrtsp-caching 20 --rtsp-caching 20 --sout '#transcode{acodec=s16l,samplerate=44100}:rtp{sdp=rtsp://:8082/,caching=10}'


이렇게 vlc-nox를 설치해서 소리를 전송하려고 하니 (rtsp://라즈베리IP주소:8082/ 를 audio 태그 혹은 VLC에서 재생 및 녹화)Easycap 자체가 워낙 구려서 추천하지 않는다고 합니다. 2300원짜리 USB 사운드 카드도 하나 구비해야 할 듯합니다.


사운드 부분 작업 중.


요놈을 추가로 더 구입했습니다. 7000원 더 들었네요.(2300원짜리는 단종되었다고 합니다...허)



USB 사운드카드 하나를 샀습니다. 어차피 EasyCap은 병맛이라고 하니까요. 우선 라즈베리파이 내장 사운드카드를 죽이도록 하겠습니다.


http://www.instructables.com/id/Disable-the-Built-in-Sound-Card-of-Raspberry-Pi/step3/Test-that-sound-card-is-NOT-detected-by-ALSA-Nativ/

위의 내용에 의하면 

/etc/modprobe.d/alsa-base.conf

여기에

blacklist snd_bcm2835

위의 내용이 들어가면 라즈베리파이 내장 사운드카드를 죽일 수 있게 됩니다.


그다음 aplay -l 명령을 썼을 때 BCM칩이 안 뜨면 죽은 겁니다. 물론 녹음 쪽이 더 중요하니까

arecord -l

위 명령을 써보시는 것이 더 좋습니다.


그 다음 RCA to Stereo 케이블을 사용해서 RCA사운드(빨간색-흰색)단자를 USB사운드카드의 마이크부분에 꽂습니다. 일단 작동은 되는 듯 합니다. 그런데 사운드가 미친듯이 깨집니다.


아마도 PC에서는 문제가 없었던 것을 봐서 라즈베리파이의 성능문제 혹은 설정 문제일 것입니다. http://www.raspyfi.com/raspberry-pi-usb-audio-fix/

여길 보니 설정 문제인듯 합니다.


우선 rpi-update를 설치한다.


sudo apt-get install rpi-update


그 다음


sudo rpi-update


를 실행 업데이트가 완료되면


sudo shutdown -r now


일단 이걸로 대충은 해결이 된다고 하는데 일단 해보고 나머지 포스트.


대충은 VLC에서 소리가 나오기는 하네요. 됩니다.


 그러기 전에 라즈베리파이에 자동 실행이 되도록 약간 손을 좀 봐야 하는데요.

/etc/rc.local 파일을 손을 보겠습니다.


sudo nano /etc/rc.local


위 명령을 사용하면 rc.local 파일을 수정할 수 있게 되는데


exit 0 위에 다음과 같이 적습니다.


sudo motion &


그런데 VLC는 root로는 실행이 되지 않습니다. 그러면 유저모드에서 실행을 하게 하면 됩니다.


sudo raspi-config에서 Boot Options으로 들어간 뒤에 Autologon을 설정합니다.

그리고

sudo nano ~/.profile


여기서 제일 아래에


cvlc -vvv alsa://plughw:0 --realrtsp-caching 10 --rtsp-caching 10 --sout '#transcode{acodec=s16l,samplerate=44100}:rtp{sdp=rtsp://:8082/,caching=10}'  


이걸 넣어주시면 자동으로 실행 됩니다.


이렇게 하면 8081포트로는 화면을 8082 포트로는 wav로 rtsp프로토콜 사운드를 전송하게 됩니다. 그럼 이걸 어떻게 모바일로 확인하는지 알려드리겠습니다.


영상은 이전과 같이 Chrome을 사용하고 사운드는 VLC를 사용하면 됩니다. 이는 PC도 마찬가지입니다. OS를 가리지 않는 두 프로그램을 사용하기 때문에 절대로 OS 호환 문제가 생기지 않습니다. 심지어 이거 iOS도 됩니다. 사파리+VLC를 쓰면 됩니다.



일단 안드로이드에서는 위와 같은 방법을 쓰고 우분투 PC에서는 ffplay를 쓰는것이 가장 나았습니다.


만약 라즈베리파이 IP가 192.168.0.21 이라면

ffplay -f mjpeg -probesize 32 -i http://192.168.0.21:8081 -vf yadif  &
ffplay -i rtsp://192.168.0.21:8082/


위의 내용을 터미널에 넣으면 실행이 완료됩니다. yadif 필터를 먹였으므로 RCA특유의 인터레이스 화면도 필터링됩니다.

,