Subscribe: Firejune Blog
http://firejune.com/rss
Added By: Feedage Forager Feedage Grade B rated
Language: Korean
Tags:
Rate this Feed
Rate this feedRate this feedRate this feedRate this feedRate this feed
Rate this feed 1 starRate this feed 2 starRate this feed 3 starRate this feed 4 starRate this feed 5 star

Comments (0)

Feed Details and Statistics Feed Statistics
Preview: Firejune Blog

Firejune



이 사이트는 자바스크립트 프로그래밍을 중심으로 웹 애플리케이션 개발에 대한 내용을 주로 다룹니다.



Updated: 1970-01-01T00:00:00+00:00

 



2016 Play.Node 발표자료 공유

2016-11-24T23:10:08-08:00

src="//html5.firejune.com/electron.html" width="640" height="500" >

슬라이드를 클릭한 후 방향키를 이용하여 다음으로 넘길수 있습니다.

OctoberSky가 주최하는 2016 Play.Node 개발자 콘퍼런스에서 "Electron 기반의 모바일 앱 테스트 자동화 S/W 개발"이라는 주제로 발표한 슬라이드를 공유합니다. "테스트 자동화"에 대한 개념을 인지해야 소프트웨어 구현의 전반적인 흐름에 대한 이해도를 높일 수 있을 것 같아서 잡설들을 늘어놓다 보니 제 수준에서는 40분 만에 소화하기 어려운 발표자료였습니다. 매번 느끼는 것이지만, 발표하면 할수록 더 못하는 것 같습니다. 그런데도 관심 있게 경청해 주신 여러분께 진심으로 감사드립니다.

발표연습 부족으로 전달 못 한 메시지:

  • Node의 v8 엔진은 대부분의 최신 자바스크립트 문법을 지원하므로 굳이 ES5로 Transpiling할 필요가 없고 최소한의 Babel 플러그인 사용 노하우를 소개하고 싶었어요.
  • NPM 생태계를 적절히 사용하면 꿀리지 않는 데스크탑 애플리케이션을 개발할 수 있어요.
  • PTY로 구현한 터미널 모듈에서 테스트 대상이 되는 모바일 앱의 실시간 로그가 출력되는 데모를 보여드리고 싶었어요.
  • 이 로그는 개발자가 만들어낸 것이어서 디버그하는 힌트가 되고, 크래시가 발생한 경우 스택-추적까지에 대한 리포팅 기능을 소개하고 싶었어요.
  • HighCharts를 이용한 실시간 모바일 시스템 리소스 모니터링 데모를 보여드리고 싶었어요.
  • OpenCV를 활용한 컴퓨터-비전 기술에 대한 가능성은 어마어마해요.('크래시 로얄'에서 교관을 이기는 AI를 개발 중이에요)
  • 동적 게임 테스트 POC를 성공시키지 못한 것이 너무 억울해요.(회사에서 할 때는 졸라 잘 돌아가는데...)
  • 로드맵에서는 모바일 기기의 파편화를 해결하는 방안을 'Test Cloud'를 통해서 만족할 수 있다는 사실과, 'Test Cloud'는 Xamarin을 시작으로 거대한 조직들이 속속 뛰어드는 트랜드를 전달하고 싶었어요.
  • 테스트 클라우드 중 비교적 최근에 출시한 NTT사의 'Remote TestKit' 제품과 연동되는 데모를 보여드리고 싶었어요.
  • 끝으로, 이 Studio 프로젝트는 무료로 풀 것이고, 2017 MWC에서 화려한 데뷔를 목표로 하고 있다는 사실을 알리고 싶었습니다.


Comments | Hits(291,788)(image)



60여개 언어를 지원하는 OCR 엔진 Tesseract

2016-10-25T23:00:31-07:00

Tesseract는 C++로 작성된 Tesseract OCR 라이브러리를 자바스크립트로 포팅한 것으로 텍스트의 방향을 자동으로 탐지하며, 단락을 구분해 내거나 단어 및 문자의 경계를 탐지하는 등의 인터페이스를 제공합니다. Emscripten을 이용하여 tesseract-core라는 이름으로 포트 되었으며, 이 자바스크립트 파일의 용량이 무려 2.7MB에 달합니다. 브라우저의 리소스를 많이 잡아먹어서인지 WebWorker에서 동작하게 되어있고 Node에서는 child_process API를 이용하는군요. 코어와 언어별 트레인드(Trained) 데이터는 최초 인식 때 한 번만 가져오고 이후부터는 캐시에서 불러옵니다.

src="https://jsbin.firejune.com/tesseract/" width="640" height="240" class="hasborder" data-layout="fixed-height">

한글의 인식률이 어떤지 궁금해서 원래 있던 데모에 한글모드를 추가해 보았습니다. 고딕 계열 폰트로 작성된 한글 이미지의 인식률이 가장 높았으며, 불분명하다고 판단하는 경우가 아주 많았습니다. 상단 탭을 한글로 맞추고 한글이 들어간 이미지 파일을 드롭하면 다른 파일의 인식 테스트도 가능합니다.

Tesseract.recognize(myImage)
         .progress(function  (p) { console.log('progress', p)    })
         .then(function (result) { console.log('result', result) })


Comments | Hits(331,823)(image)



웹기반 MT-32 시퀸스드 뮤직 플레이어

2016-09-11T14:05:14-07:00

src="https://jsbin.firejune.com/MT32Emu/" width="640" height="300" class="hasborder" data-layout="fixed-height">

자바스크립트로 간단하게 만들어 본 MIDI 시퀸스 플레이어입니다. 미디 모듈은 Roland사의 MT-32이며 이것은 MUNT라는 C/C++ 에뮬레이션 라이브러리를 Emscripten을 이용하여 ASM으로 포팅한 것입니다. SIERRA사의 Silpheed라는 슈팅게임 외 몇몇개의 사운드트랙을 데모용으로 올려두었습니다. (걍 플레이 버튼을 누르면 되요) MT-32용 MIDI 파일을 직접 구해서 플레이어로 끌어다 놓거나 버튼을 눌러 MIDI 파일을 선택하면 자동으로 재생합니다. 복수로 선택하는 경우 재생목록이 만들어 집니다. 더 많은 사운드트랙을 구하려면 구글링해서 어렵지 않게 얻을 수 있고, 특히, Loom, Monky Island, Ultima, Zeliard, YS의 사운드트랙을 추천합니다. 아쉽게도 GM 용으로 만들어진 MIDI 파일은 오류가 나거나 제대로 재생되지 않으며, iOS 브라우저는 ctx.createScriptProcessoronaudioprocess 콜백이 정상적으로 호출되지 못하는 이슈가 있어 작동하지 않습니다. iOS Unmute Hack을 이용하여 재생할 수 있습니다.

GM 기반 MIDI 파일은 libTiMidity 라이브러리를 ASM으로 포팅하여 재생이 되는 것을 확인하였습니다. 확실히 파워풀한 사운드를 들려주는군요. libTiMidity는 사운드폰트기반이어서 별도로 내려받아 실행해야 하고 쓸만한 폰트 파일의 크기가 100MB를 훌쩍 넘기 때문에 온라인 플레이어로 만들기는 다소 힘들어 보입니다.(폰트를 악기단위로 분리하고 MIDI 파일을 분석하여 필요한 악기만을 비동기로 로드하고 재생하는 개념의 midijs라는 프로젝트가 있네요!)

(image)

유년시절에 즐겼던 대부분의 DOS 게임들이 시퀸스 모듈을 이용하여 제작되었습니다. 시퀸스드 뮤직 파일은 여러 종류가 있는데 퀄리티 순으로 나열하면 General MIDI 호환 > MT-32 호환 > OPL 시리즈(AdLib Sound) > PC 스피커 순이 됩니다. 이 중에서도 중저가형인 MT-32호환 모듈인 CM-32를 사려고 용돈을 모으다가 저가형 하이-엔드 사운드 카드인 OPL-4기반의 "옥소리"가 출시되어 지르는 바람에 물 건너 가버렸던 그런 추억이 있는 시퀸스 모듈입니다. OPL-4는 YAMAHA사에서 만든 칩셋으로 낮은 가격대비 고수준의 PCM 음원을 내장한 시퀸스 모듈입니다만, 하필이면 이즈음 하드웨어에 의존 없이 소프트웨어 믹서만으로 CD 오디오 수준의 사운드를 재생하는 분위기로 개발 동향이 바뀌면서 시퀸스 사운드는 게임계에서 자취를 감추게 되었죠.

MT-32 음향을 꼭 한번 들어보고 싶었는데, 20년이 훌쩍 지난 지금 자바스크립트로 재생해 보게 되었네요. 추억 돋게 하는군요.



Comments | Hits(386,755)(image)



구글 액셀러레이티드 모바일 페이지(AMP) 적용하기

2016-08-08T11:12:14-07:00

구글 검색 콘솔에 액셀러레이티드 모바일 페이지(AMP)라는 신기한 녀석이 출현했습니다. AMP는 모바일 환경에서 빠르게 로드되도록 설계된 페이지입니다. 자신의 웹사이트에 이를 적용하면 구글에서 제공하는 캐시에 저장되어 구글을 비롯한 여러 메타사이트가 웹페이지 프리뷰 등의 목적으로 활용할 수 있게 됩니다. 이전 글에 간단한 소개가 있으니 참고하세요. AMP HTML 사양에 대한 기본적인 내용을 번역하기보다는 제가 이 작업을 수행하면서 경험한 삽질이나 알아낸 것, 유용하다고 생각되는 방법을 중심으로 설명하겠습니다. AMP 페이지를 작업하기에 앞서 선행되어야 할 사항으로 구글 페이지 인사이트에서 모바일 사용환경 테스트 점수를 80점 이상으로 통과한 상태여야 하며, 추가로 데이터 구조화 유형 중 아티클을 만족해야 합니다. 아티클 유형으로는 Article, NewsArticle, BlogPosting 또는 VideoObject입니다. 이 네 가지 유형에 속하지 않는 웹사이트는 AMP를 적용하는 것이 현재 무의미합니다. 그러면, 일반 게시판이나 위키, 쇼핑몰은 어디에 속할까요? 대부분 Article 유형에 속합니다. Note: 선택적으로는 SSL을 지원하는 것이 좋습니다. 이나 를 제외한 URL 속성을 필요로 하는 대부분의 AMP 컴포넌트가 SSL 주소를 요구하기 때문입니다. 여기부터 작성되는 내용은 위 두 조건을 모두 만족한 것을 전제로 합니다. 이제 AMP HTML을 작성해 봅시다. 기존 HTML에 AMP 모드를 추가할 것인지 아니면 AMP 페이지를 별도로 제공할 것인지를 우선 결정해야 합니다. 여기에는 장점과 단점이 존재합니다. 전자는 작업효율이 높습니다. 이미 잘 돌아가고 있는 HTML을 건드릴 필요가 없으니까요. 스펙 문서를 보고 마구잡이로 때려 고쳐 내려가면서 검사기를 통과시키면 됩니다. 단점은 관리 포인트가 늘어나는 것이죠. 후자는 고스란히 그 반대입니다. 굉장히 하드코어한 코딩을 구사하게 될 거에요. 저는 이 두 가지 방법을 모두 시도하는 것을 추천합니다. 최초 페이지를 별도로 작업하다 보면 두 문서 간의 차이점을 쉽게 찾아낼 수 있고요. 결국에는 하나의 작업물에서 두 가지 아웃풋을 내는 형태로 병합할 수 있습니다. 자, 이제 AMP HTML 스펙 문서를 열고 코딩하세요. 코딩하면서 아래의 유의해야 할 항목을 살펴보세요. 이것은 제가 범한 실수이고 오류가 보고될 때마다 기록한 것입니다. 작게 여겨질 수도 있겠지만, 오류 하나가 보고되면 이 오류 항목이 사라지기까지는 보통 1달 정도 혹은 그 이상의 시간이 소요된다는 점 꼭 유념하시기 바랍니다. AMP 구분자와 언어코드를 HTML에 삽입해 주세요. UTF-8이 기본입니다. 태그의 값에는 원래 문서의 고유 주소를 사용하세요. 주소에는 필터와 같은 파라미터가 기입되지 않도록 하여 하나의 문서가 여러 링크를 만들어 내는 일이 없도록 해야합니다. m.firejune.com과 같이 모바일용 페이지를 별도로 제공하는 경우 를 이용하세요. 필수 요소 입니다.

webodf는 여러 개의 자바스크립트가 하나로 합쳐져 만들어진 것입니다. 소스는 GitHub 리파지토리에서 확인하거나 다운로드 할 수 있으며, CMake를 이용하여 빌드하는 방법은 다음과 같습니다.

git clone https://github.com/kogmbh/WebODF.git webodf
mkdir build
cd build
cmake ../webodf
make webodf-target

에디터는 일반 편집과 협업 편집모드를 제공하며, Wodo.TextEditor라는 컴포넌트를 필요로 합니다. Wodo.TextEditor는 Dojo를 기반으로 작성되었으며, webodf를 포함하고 있습니다. 다음과 같은 코드로 페이지에 추가할 수 있습니다.











Node용 프로젝트인 Etherpad에서 제공하는 것과 같은 협업모드 편집은 웹소켓을 이용한 것으로 서버 컴포넌트가 필요하지만 서버-사이드의 소스코드는 공개되어 있지 않습니다. 단, "programs/editor/backend/pullbox"에 클라이언트-사이드에서 데이터 송/수신을 위한 구현한 코드가 포함했으니 참고하라고 하네요. 이 과정은100% 클라이언트(브라우저)에서 발생하며, 데이터를 서버로 전송하지는 않는다고 합니다.



Comments(2) | Hits(651,561)(image)



자바스크립트 바이너리 데이터 스트럭쳐 - struct

2013-08-01T09:24:06-07:00

일반적으로 C언어에서 struct에 의해 구조화된 바이너리 데이터를 자바스크립트에서 사용할 수 있게 변환하고 이를 다시 조작하여 바이너리로 생성하는 과정이 엘레강스(?)하지가 않아서 C의 struct와 유사하게 자바스크립트에서도 구조체를 사용할 수 있도록 작은 유틸리티를 만들었습니다. 만들고 보니, 다른 곳에서도 유용하게 사용될 수 있을 것 같아 공개합니다. 우선, 자바스크립트만으로 ArrayBuffer를 다루어 보겠습니다. 예제에 사용되는 바이너리 데이터는 0번째 번지에 Uint8 유형의 정수, 1번째 번지에 Int8 유형의 정수, 3번째 번지에는 Uint16 유형의 2바이트짜리 정수이며, 이를 쓰고 다시 읽어내는 것입니다: // define struct var struct = { foo: 255, bar: 127, baz: { qux: 65535 } }; // write arraybuffer from javascript object var ab = new ArrayBuffer(4); var dv = new DataView(ab); dv.setUint8(0, struct.foo); dv.setInt8(1, struct.bar); dv.setUint16(2, struct.baz.qux, true); console.log(dv.buffer); // => ArrayBuffer {byteLength: 4, slice: function} // read data from arraybuffer var dv2 = new DataView(dv.buffer); var data = { foo: dv2.getUint8(0), bar: dv2.getInt8(1), baz: { qux: dv2.getUint16(2, true) } }; console.log(data); // => Obejct {foo: 255, bar: 127, baz: {qux: 65535}}} 옵셋을 손으로 패딩해야하며 형식이 동일한 구조의 데이터를 읽고 생성하려 했지만 도저히 같다고는 느껴지지 않습니다. 그리고 버퍼의 크기가 크면 클수록 사용성이 떨어지는 문제도 있습니다. struct를 사용하면 다음과 같이 코드를 작성할 수 있습니다: // define struct var struct = new Struct({ foo: ['uint8', 255], bar: ['int8', 127], baz: { qux: ['uint16', 65535] } }, 0, true); // write arraybuffer from javascript object var ab = struct.write(); console.log(ab); // => ArrayBuffer {byteLength: 4, slice: function} // read data from arraybuffer var data = struct.read(ab); console.log(data); // => Obejct {foo: 255, bar: 127, baz: {qux: 65535}} 옵셋을 자동으로 카운트하고, 자바스크립트 형식으로 작성한 데이터 구조체를 재활용하여 새로운 arraybuffer를 생성하거나 반대로 자바스립트에서 읽을 수 있는 데이터로 만들어 사용하기가 수월합니다. 이는 마치 C에서 생성하는 구조체를 사용하는 느낌입니다. 속성(키)/[유형(타입), 값(밸류)]로 구조를 작성해야 하며 '속성/유형'만 지정하면 버퍼를 작성하는 경우 기본값이 할당됩니다. 즉, '밸류'는 write 메서드를 이용하여 ArrayBuffer를 생성하는 곳에만 사용되며, 단순히 read 메서드로 데이터를 읽기만 한다거나, 속성마다 특정한 값을 설정할 필요가 없는 경우라면 타입만 지정해도 된다는 의미입니다. 다음은 read 메서드의 두 번째 인자에 사용자 지정 옵셋을 입력하여 동일한 형식의 데이터가 복수로 담긴 청크를 처리하는 모습입니다. /** * read multiple data with custom offset */ var struct = new Struct({ sig: 'uint8', mimeType: 'uint8', id: 'uint16', byteLength: 'uint32' }); ... function parseBinary(chunk, count, callback) { var offset = 0; for (var index = 0; index < count; index++) { var meta = struct.read(chunk, offset) , buffer = chunk.slice( offset += struct.byteLength, offset += meta.byteLength ); callback(meta, new Uint8Array(buffer)); } } write 메서드에 변경할 내용이 담긴 객체를 인자로 전달하여 복수의[...]



Signed와 Unsigned 차이

2013-07-31T09:21:02-07:00

자바스크립트에서 버퍼를 읽거나 쓰는 예문들을 볼때 C에서 사용되는 'signed'와 'unsigned'라는 키워드에 비유하는 내용을 자주 접하게 됩니다. 이게 무엇이고 왜 구분을 해야 하는 것인지를 몰라서 우리 팀장님께 커피 한 잔 사드리고 특강을 받았습니다. 제가 이해하기 쉽게 '음수를 표현하느냐 안 하느냐의 차이'라고 알려 주셨고, 메모리에 비트를 기록하는 방식이 다르다고 했습니다. "더 자세히 설명해 주세요~"했더니 CPU가 어쩌니 어셈블리가 저쩌니 한 귀로 듣고 흘려 버릴수 밖에 없는 내용이어서... 나중을 대비해 나름 이해한 내용을 정리합니다.

예를 들어 C언어에서는 다음과 같이 8비트 정수 타입을 선언할 수 있습니다.

signed char
unsigned char

unsigned char는 비트를 투명하게 볼 수 있는 특성이 있으며, 임의의 메모리에 바이트 단위로 접근해서 값을 다룰 수 있습디다. 이 경우에는 unsigned char를 사용하는 것이 강제됩니다. 그리고 signed char는 unsigned char와 값이 같아도 같지 않은 경우가 발생할 수도 있습니다. 왜냐하면 signed는 음수 표현을 위해 2의 보수 체계를 사용하고 부호 비트(MSB)가 필요하기 때문입니다.(0 이면 양수 1 이면 음수) 그래서 부호 비트가 없는 unsigned는 양수 범위를 두 배로 늘리는 역활을 한답디다. 즉, char 형식은 8비트이므로 signed char은 -128~127의 범위를 표현할 수 있고 unsigned chare은 0~255의 표현범위를 가지는 것입니다.

조금더 이해하기 쉽게 그림으로 예를 들어봅시다. 정수 3인 1바이트(8비트)를 2진수로 기록하면 00000011이 됩니다. Unsigned에서는 다음과 같이 부호가 할당되겠죠.

0 0 0 0 0 0 1 1

Signed는 음수를 표현하기 위해 제일 앞 하나의 비트를 소비한다고 했습니다. 그럼 정수 3은 이렇게 되겠군요.

0 0 0 0 0 0 1 1

온라인 이진수-정수 변환기를 사용해 보면 금방 이해할 수 있습니다.

(나도 언젠가는 CPU의 마음과 메모리의 정신을 이해할 수 있겠...)



Comments(4) | Hits(1,616,774)(image)



빅엔디안과 리틀엔디안 개념

2013-07-23T09:09:38-07:00

자바스크립트의 DataView를 이용하여 바이너리를 메모리에 쓰거나(Write) 전송(Send)하면서 삽질하는 과정들이 저에게는 마냥 신세경입니다. ArrayBuffer API를 소개하면서 간소하게 언급했던 DataView 인터페이스에서 등장하는 리틀엔디안과 빅엔디안에 대한 개념을 탑재해 보겠습니다.

컴퓨터에서 어떤 크기의 데이터를 메모리에 저장할 때 바이트 단위로 나누어 저장합니다. CPU 아키텍처에 따라 바이트 저장순서가 달라질 수 있기 때문에 두 가지로 나뉘는 데 그것이 바로 '리틀-엔디안'과 '빅-엔디안' 방식입니다. 어떤 CPU에서는 이 두 가지 방식을 모두 지원하도록 구성할 수도 있답디다.

리틀-엔디안 (Little-Endian)

낮은(시작) 주소에 하위 바이트부터 기록, Intel CPU 계열
예) 32비트형 (4바이트) 값: 0x01020304

하위 주소 0x04 0x03 0x02 0x01 상위 주소

빅-엔디안 (Big-Endian)

낮은(시작) 주소에 상위 바이트부터 기록, Sparc / RISC CPU 계열
예) 32비트형 (4바이트) 값: 0x01020304

하위 주소 0x01 0x02 0x03 0x04 상위 주소

빅엔디안은 우리가 평소에 보던 방식으로 메모리에 쓴다고 생각하면 되고 리틀엔디안은 뒤집혀서 쓴다고 이해하면 되겠죠? 그럼 왜 빅엔디안으로 안 쓰는 걸까요? 그 이유는 산술연산유닛(ALU)에서 메모리를 읽는 방식이 메모리 주소가 낮은 쪽에서부터 높은 쪽으로 읽기 때문에 산술 연산의 수행이 더 쉽습니다. 또한, 데이터를 다른 시스템으로 전송할 때 서로 다른 데이터 저장 방식의 시스템끼리 통신하게 되면 전혀 엉뚱한 값을 주고받기 때문이랍니다.

자바스크립트의 DataView 인터페이스는 특정 파일 또는 수신된 바이너리 데이터를 읽고 쓸 수 있도록 설계되었습니다. 브라우저가 작동 중인 CPU에 상관 없이 일관되고 올바른 결과를 얻을 수 있도록 작동하기 위해 모든 값의 모든 접근에 엔디안(Endianness)을 지정해야 합니다.

var buffer = new ArrayBuffer(12);
var dv = new DataView(buffer);
dv.setInt32(0, 25, false); // set big-endian int32 at byte offset 0 to 25
dv.setInt32(4, 25); // set big-endian int32 at byte offset 4 to 25
dv.setFloat32(8, 2.5, true); // set little-endian float32 at byte offset 8 


Comments(3) | Hits(911,396)(image)



자바스크립트에서의 BLOB 객체

2013-07-17T07:18:33-07:00

이전 포스트에서 ArrayBuffer에 대해 알아보았습니다. 일반적으로 컴퓨팅에서 말하는 블랍(BLOB)은 대체로 커다란 파일을 일컫는 말이며, 사운드, 비디오와 같은 멀티미디어 데이터를 객체로 다루기 위해 주로 사용되는 것으로 알려졌습니다. File API가 생겨나면서 동시에 등장한 BLOB은 자바스크립트에서 조금 다른 의미로 해석되는데 지금은 파일을 다루기 위한 메모리 참조 수단 정도입니다. 원래 BLOB 객체는 스트림을 이용해서 읽기/쓰기를 하는 것이 정설이지만 자바스크립트에서는 바이너리로 수신한 청크(Chunk)들을 한방에 생성하여 File로 인식하는 용도로 자주 사용되며, FileReader API와 함께 사용하여 자바스크립트로 버퍼링을 제어하는 수준의 미디어 스트리밍을 구현할 수 있게 합니다. 또한, 이를 DOM으로 연결하기 위한 URL.createObjectURL이 존재합니다. 다음 예제는 AJAX에서 BLOB 데이터 형식으로 수신한 이미지를 DOM에 참조시키고 이미지가 출력된 후 URL.revokeObjectURL을 이용하여 BLOB을 해제하는 것입니다. var req = new XMLHttpReqest(); xhr.open("GET", "download?name=" + name, true); xhr.responseType = "blob"; xhr.onreadystatechange = function () { if (xhr.readyState == xhr.DONE) { var blob = xhr.reponse; var image = document.getElementById("my-image"); image.addEventListener("load", function (evt) { URL.revokeObjectURL(evt.target.src); } image.src = URL.createObjectURL(blob); } } xhr.send(); Node의 BinaryJS모듈을 이용하여 스트림으로 수신한 Chunk를 배열로 취합하고 스트림이 끝나는 시점에 Blob으로 변환하여 DOM으로 참조시키는 예제: // Connect to Binary server var client = new BinaryClient('ws://localhost:9000'); // Received new stream from server! client.on('stream', function(stream, meta){ // Buffer for parts var parts = []; // Got new data stream.on('data', function(arrayBuffer){ parts.push(arrayBuffer); }); stream.on('end', function(){ // Display new data in browser! var img = document.createElement("img"); img.src = URL.createObjectURL(new Blob(parts)); document.body.appendChild(img); }); }); 다음 예제는 MediaSource API와 연계하여 작동하는 것을 가정한 코드로서 현재 구글 크롬 브라우저에서 구현 중인 명세이고 WebM 포맷(vorbis, vp8 인코딩)으로 만들어진 미디어만 정상적으로 작동(웹 소켓 바이너리 통신)하는 것을 직접 확인한 것입니다. 처음으로 수신한 Chunk의 Blob 객체를 생성하고 FileReader API에서 뒤이어 수신하는 Chunk를 추가(Append)하여 미디어 스트리밍을 구현한 예제입니다. var xhr = new XMLHttpRequest(); xhr.open('GET', 'test.webm', true); xhr.responseType = 'arraybuffer'; xhr.onload = function(e) { if (xhr.status != 200) { alert("Unexpected status code " + xhr.status + " for " + url); return false; } callback(new Uint8Array(xhr.response)); }; xhr.send(); function callback(uInt8Array) { var file = new Blob([uInt8Array], {type: 'video/webm'}); var chunkSize = Math.ceil(file.size / NUM_CHUNKS); console.log('num chunks:' + NUM_CHUNKS); console.log('chunkSize:' + chunkSize + ', totalSize:' + file.size); // Slice the video into NUM_CHUNKS and append each to the media element. var i = 0; (function readChunk_(i) { var reader = new FileReader(); // Reads aren't guaranteed to finish in the same order they're started in, // so we need to read + append the n[...]



HTML5 ArrayBuffer API 이해하기

2013-07-15T08:17:49-07:00

최근 자바스크립트로 바이너리를 다룰 일이 생겨서 이런저런 삽질 중에 ArrayBuffer API는 짚고 넘어가야겠다는 생각이 들어 학습차 정리합니다. HTML5에서 지원하는 ArrayBuffer를 이용하여 Ajax 또는 WebSocket을 통해 바이너리 데이터를 서버와 브라우저 간에 송/수신할 수 있습니다. 이를테면, 서버와 클라이언트에서 Base64로 인코딩/디코딩하는 비용을 줄이거나 사진에서 EXIF 정보를 뽑아내거나, MediaSource API를 함께 사용하여 동영상 스트리밍을 구현할 수도 있으며, WebSocket으로 파일을 업로드하는 등 다양하게 활용할 수 있습니다. 일반적인 스트림(Stream) 객체에 의해 순차적으로 발생하는 이벤트로 전달되는 ArrayBuffer는 우리가 소위 말하는 Chunk 데이터이며 메모리에 위치하게 됩니다. 이것을 자바스크립트에서 다룰 수 있도록 하기 위해서 타입 배열 뷰(Typed array views)로 만들 수 있는데, 이는 ArrayBufferView 클래스로 생성할 수 있으며 그 종류는 다음과 같습니다. // Signed integer arrays. var i8 = new Int8Array(64) // 1 byte, 8-bit twos complement signed integer var i16 = new Int16Array(32) // 2 bytes, 16-bit twos complement signed integer var i32 = new Int32Array(16) // 4 bytes, 32-bit twos complement signed integer // Unsigned integer arrays. var u8 = new Uint8Array(64) // 1 byte, 8-bit unsigned integer var u16 = new Uint16Array(32) // 2 bytes, 16-bit unsigned integer var u32 = new Uint32Array(16) // 4 bytes, 32-bit twos complement signed integer var pixels = new Uint8ClampedArray(64) // 1 byte, 8-bit unsigned integer // Floating point arrays. var f32 = new Float32Array(16) // 4 bytes, 32-bit IEEE floating point number var f64 = new Float64Array(8) // 8 bytes, 64-bit IEEE floating point number 멋모르고 프로그래밍 세계에 발을 들여 놓은 저로서는(보는 것 만으로도 화가 남) 이렇게 많은 형식이 어디에 어떻게 쓰이는지 막연하기만 했는데, O'Reilly에서 출판한 Javascript: The Definitive Guide(자바스크립트 완벽 가이드) 6판 챕터 22에 뭔가 감을 잡을 수 있는 예문(문제 되면 삭제하겠습니다)이 있더군요. var matrix = new Float64Array(9); // A 3x3 matrix var 3dPoint = new Int16Array(3); // A point in 3D space var rgba = new Uint8Array(4); // A 4-byte RGBA pixel value var sudoku = new Uint8Array(81); // A 9x9 sudoku board 이것은 그냥 처리할 바이너리가 메모리에서 비트 연산에 효율적으로 사용될 유형을 선택해 주면 되는 정도로 어렴풋이 이해했습니다. 더 많은 내공이 쌓여야 이 타입들에 대한 개념을 탑재할 수 있을 듯합니다. ArrayBuffer를 다루는 더 쉬운 방법은 DataView와 StringView를 이용하는 것입니다. DataView는 ArrayBuffer로부터 값을 읽거나 쓸 수 있도록 로우 레벨의 인터페이스를 제공하며, StringView는 문자열에 대한 C 스타일의 인터페이스를 제공합니다. 끝으로 준비한 예제는 비동기로 수신한 바이너리를 자바스크립트에서 사용할 수 있는 배열로 변환하여 어딘가에 써먹는 예제입니다. var req = new XMLHttpRequest(); req.open('GET', "/your/binary/data"); req.responseType = "arraybuffer"; req.onload = function () { if (req.status != 200) { alert("Unexpected status code " + req.status); return false; } var buffer = req.response; var dataView = new DataView(b[...]



3D 드로잉 펜 - 3Doodler

2013-02-21T03:09:57-08:00

width="664" height="374" src="//www.youtube.com/embed/DQWyhezIze4?rel=0" allowfullscreen>

3Doodler는 세계 최초이자 유일한 공기중에 입체로 그림을 그릴 수 있는 펜입니다. 전원에 연결하고 몇 분 정도 기다리면 바로 사용할 수 있으며, 소프트웨어나 컴퓨터를 필요로 하지 않습니다. 심은 ABS 플라스틱(3D 프린터에서 흔히 사용되는 재료)를 이용한다고 합니다.

3Doodler는 어린이용 장난감으로는 부적합하며, 가격은 50달러군요.



Comments(4) | Hits(205,770)(image)



스타크래프트2 - 군단의 심장 시네마틱

2013-01-22T06:50:46-08:00

id="sc2" width="640" height="360" src="https://www.youtube.com/embed/MVbeoSPqRs4" allowfullscreen>

퀄리티 쩌네요. 여기를 클릭하면 한글 더빙판으로 토글합니다.



Comments | Hits(184,938)(image)



웹 분석도구 Piwik 한국어 현지화 완료!

2013-01-21T08:39:27-08:00

(image)

Piwik은 오픈 소스 기반의 웹사이트 분석도구입니다. 구글 Analytics의 대안으로 손꼽히고 있으며, 비교적 트래픽이 많은 사이트도 소화할 수 있다고 합니다. 최신 버전인 1.10.1의 한국어 현지화를 방금 마무리했어요. 작업을 시작할 무렵 김종인님이 36% 진행해 놓은 것에 바톤을 이어받아 100% 까지 총 2,153개의 리소스 번역을 한 주에 걸쳐 완료했습니다. 다음 버전 릴리즈 때 반영되겠지만 먼저 적용해 보실 분들은 여기에서 다운로드 할 수 있습니다.(확장자를 php로 바꾸고 piwik/lang/ 디렉토리에 덮어쓰세요)

(image)
뿌..., 뿌듯함!

직접 사용해 보면서 문맥이 이상한 부분들은 최대한 수정하고 있지만 미처 발견하지 못한 오역이나 이상한 부분이 있다면 알려주세요. 즉시 수정해서 반영하도록 하겠습니다. 그런데 이걸 왜했냐고요? 가끔은 자기 자신을 무작정 괴롭혀 보는 것도 기분전환에 큰 도움이 되더군요….

덧. Piwik을 설치하고 알아낸 유용한 것들을 정리해 보았습니다.

  • Piwik 모바일을 사용한다면, 보고서의 그래프에 문자가 깨집니다. unifont.ttf를 다운로드하고, 압축을 풉니다. piwik/plugins/ImageGraph/fonts 디렉토리로 업로하면 문자가 깨지는 것을 바로잡을 수 있습니다.
  • Maxmind에서 유료로 제공하는 데이터베이스를 misc 디렉토리에 업로드하면, ISP 공급자와 업체를 추적할 수 있습니다.
  • 20개 이상의 다양한 플러그인을 사용할 수 있습니다. 압축을 푼 후 plugins 디렉토리에 업로드하기만 하면 플러그인 목록에서 활성/비활성 할 수있습니다.
  • 검색어 보고서에서 네이버의 한글 검색어가 깨져 보이는 문제는 core/DataFiles/SearchEngines.php 파일에서 'search.naver.com' 문자열을 찾고 정의되는 배열 마지막에 , 'EUC-KR'을 제거하여 해결할 수 있습니다.

덧. 2013-01-25 업데이트: 추가적인 문맥 수정



Comments(2) | Hits(208,684)(image)



실시간 모바일 앱 분석 도구 - Countly

2013-01-16T09:01:32-08:00

Countly는 4인으로 구성된 터키출신의 착한 젊은 친구들에 의해 만들어진 실시간 모바일 앱 분석 도구입니다. 모바일 앱 엔드-유저의 행동 자료를 수집하고 분석하여 시각화해 줍니다. 구글 Analytics와 같은 웹 분석 도구를 모바일 앱에 최적화한 것으로 이해할 수 있겠네요. 오픈 소스이며 데이터 수집 및 관리할 수 있는 서버와 안드로이드, 윈도폰, iOS, 블랙베리(WebWorks)용 SDK를 동시에 제공합니다. (서드-파티에서 만든 유니티, 앱셀러레이터 타이타니움, 맥OSX용 SDK도 있습니다.) 재미있는 것은 SDK에서 제공하는 사용자 이벤트 API를 이용하면 앱 안에서의 사용자 패턴도 분석할 수 있습니다. (예를 들면, 게임 내 어떤 무기가 빈번하게 사용되는지 라던가...)

(image)

그들이 제공하는 데모를 실행해 보고 가지고 싶다는 생각이 들더군요. 나중에 서비스할지는 모르겠습니다만, 앱을 유료로 등록하고 사용할 수 있게 하는 기능은 없습니다. 그래서 Countly를 지금 사용해 보기 위해서는 운영 가능한 웹서버에 설치를 해야 하는 상황인 거죠. 서버는 Node와 MongoDB로 구축되었고 NginX와 Supervisor, Python 등의 패키지 설치를 요구하며, 리눅스 머신(우분투 권장)에 설치할 수 있습니다. 자체적으로 제공하는 설치 스크립트를 이용하면 Node를 비롯한 서버 실행 환경을 자동으로 구성해 줍니다. (비추천) 서버는 API와 Frontend로 양분되었으며, API 서버는 데이터의 입/출력을 담당하고, Express기반의 Frontend 서버는 데이터의 섹시한 비주얼라이제이션과 사용자 관리 기능을 포함합니다. 이 두 서버는 supervisord으로 관리되며, NginX에서 라우팅 룰에의해 서로 다른 포트를 가진 서버 프로세스로 프락시 패스하도록 구성되어 있었습니다. Cafe24에 놀리고 있는 가상서버에 설치하기 위해, 반나잘 삽질하고 윤진군의 도움으로 성공적으로 실행했습니다. 그런데 아쉽게도 등록할 만한 앱이 없네요. 혹시 관심 있는 분은 무료로 앱을 등록해 드릴께요. 요청에 한해서 등록한 앱 단위로 데이터베이스까지 덤프해서 드릴 생각입니다.

아쉽게도 한글 지원이 없어서 직접 한글화 작업을 완료하고 적용해 줄 것을 요청한 상태입니다. 그리고 각종 데이터를 PDF 문서로 생성해 주는 기능과 모바일에서 액세스할 수 있는 네이티브 앱을 개발 중이며 곧 선보일 예정이라고 하네요. 아주 멋집니다!



Comments(2) | Hits(82,730)(image)