2017년 6월 22일 목요일

Video Streaming In Unity


Unity는 자체적으로 비디오 녹화와 재생을 지원하지 않는다.

최신 버젼에서는 재생을 더 잘하기 위한 VideoPlayer 를 제공하지만, Online Streaming에 대한 모든 기능을 포함하고 있지는 않은 듯 하다.

따라서, 유니티에서 비디오 녹화와 재생을 구현하려면, 서버뿐만 아니라, 클라이언트 사이드에서도 Native Plugin의 도움을 받아야 하며, Native Plugin에서 사용하는 Frame Buffer와의 통신과 조작을 아주 잘 해야지만 상용화 할 수 있는 수준에 도달할 수 있다.


일단, 시작하려면, 아래의 소스들이 도움이 될 것이다.

RTMP/HLS 비디오 스트리밍 서버

SRS

상용 서비스인 wowza 보다 간단하며, 완성도가 높다. config조절을 통해서 구성도 가능하며,
오픈소스이기 때문에 분석 및 개선이 가능하다.


비디오 레코딩 구현을 위한 참고 소스

yasea
LFLiveKit

RTMP 서버로 비디오 프레임을 전달하는 역할을 하는 안드로이드/iOS 소스.
버그가 있다! 하지만, 고칠 수 있다. 찾아보라 ^^
다른 것들보다 잘 작성되어 있고, 완성도가 그래도 높은 편이다.
네이티브와 유니티와 통신하는 부분을 해결하는데 시간을 많이 써야 한다.


유니티에서 비디오 재생 구현을 위한
AV Pro Video
Universal Media Player
Exo Player

요 3가지를 참고할 만하다.


Fly Messenger는 유니티상에서 비디오 녹화 및 재생을 실시간으로 하여, 상대에게 전달하는 신개념의 메신져이다. 위의 기술들을 사용했다!

설치해 보고 체험해 보셔요! ^^
http://youfly.me/





In Why Rust


Writing Chat in Rust라는 글에서,

http://nbaksalyar.github.io/2015/07/10/writing-chat-in-rust.html
But arguably the most common pitfall is the memory safety. It is the root cause for a class of bugs such as buffer overflowsmemory leaksdouble deallocations, and dangling pointers. And these bugs can be really nasty: well known issues like the infamous OpenSSL Heartbleed bug is caused by nothing more than the incorrect management of memory — and nobody knows how much more of these severe bugs are lurking around.
However, there are several good practice approaches in C++ such as smart pointers[1] and on-stack allocation[2] to mitigate these common issues. But, unfortunately, it’s still too easy to “shoot yourself in the foot” by overflowing a buffer or by incorrectly using one of the low-level memory management functions because these practices and constraints aren’t enforced on the language level.
Instead, it’s believed that all well-grounded developers would do good and make no mistakes whatsoever. Conversely, I do believe that these critical issues have nothing to do with the level of skill of a developer because it’s a machine’s task to check for errors — human beings just don’t have that much attention to find all weaknesses in large codebases.
That’s the major reason of existence for a common way to automatically handle the memory management: the garbage collection. It’s a complex topic and a vast field of knowledge in itself. Almost all modern languages and VMs use some form of GC, and while it’s suitable in most cases, it has its own shortcomings — it’s complex[3], it introduces an overhead of a pause to reclaim unused memory[4], and generally requires intricate tuning tricks for high-performance applications to reduce the pause time.


인간이 방대한 코드베이스의 모든 약점을 찾는데 주의를 기울여야 한다고 생각하지 않는다.

21세기적인 프로그래머 마인드라서 마음에 든다. ^^

그리고, GC가 대부분의 경우 적합하지만 한계가 있다는 것을 알아야 한다.

Rust takes a slightly different approach — basically, a middle ground: automatic memory and resources reclamation without a significant overhead and without the requirement of a tiresome and error-prone manual memory management. It’s achieved by employing ownership and borrowing concepts.

그래서, Rust 가 채용한 방식은 수동과 자동을 섞은 것이다.
ownership 개념과 borrowing 개념을 도입한 것이다.

http://nbaksalyar.github.io/2015/07/10/writing-chat-in-rust.html

rust를 학습하고자 한다면, 지루하게 rust by example을 보는 것보다, 요 링크를 먼저 한번 쭉 읽어보시길 권한다.  rust를 배우고자 하는 동기부여도 될 것이고, rust에 대한 전반적인 이해가 될 것이다.







2017년 6월 21일 수요일

Erlang - Getting Started using rebar3,cowboy in MacOSX


brew doctor

brew update

brew upgrade

brew install openssl

curl -O https://raw.githubusercontent.com/kerl/kerl/master/kerl && chmod a+x kerl

export KERL_BUILD_BACKEND=git

export OTP_GITHUB_URL="https://github.com/basho/otp"

kerl list releases

kerl update releases

KERL_CONFIGURE_OPTIONS="--disable-hipe --enable-smp-support --enable-threads
                        --enable-kernel-poll --with-ssl=/usr/local/opt/openssl --without-odbc --enable-darwin-64bit" kerl build 19.2 19.2

kerl install 19.2 ~/erlang/19.2

. ~/erlang/19.2/activate

erl -version

wget https://s3.amazonaws.com/rebar3/rebar3 && chmod +x rebar3

./rebar3 local install

rebar3 new release cowboy_hello_world 

cd cowboy_hello_world/

vi rebar.config 

{deps, [
        {cowboy, {git, "https://github.com/ninenines/cowboy", {tag, "2.0.0-pre.1"}}}
]}.

{plugins, [rebar3_run]}.


Add cowboy to the list {application, [{applications, [kernel, stdlib, cowboy]}]}

 vi apps/cowboy_hello_world/src/cowboy_hello_world.app.src 

vi apps/cowboy_hello_world/src/cowboy_hello_world_app.erl 

start(_StartType, _StartArgs) ->
    {ok, Pid} = 'cowboy_hello_world_sup':start_link(),
    Routes = [ {
        '_',
        [
            {"/", cowboy_hello_world_root, []}
        ]
    } ],
    Dispatch = cowboy_router:compile(Routes),

    NumAcceptors = 10,
    TransOpts = [ {ip, {0,0,0,0}}, {port, 2938} ],
    ProtoOpts = [{env, [{dispatch, Dispatch}]}],

    {ok, _} = cowboy:start_http(chicken_poo_poo,
        NumAcceptors, TransOpts, ProtoOpts),

    {ok, Pid}.

vi apps/cowboy_hello_world/src/cowboy_hello_world_root.erl

-module(cowboy_hello_world_root).

-export([init/2]).

init(Req, Opts) ->
    Req2 = cowboy_req:reply(200,
        [{<<"content-type">>, <<"text/plain">>}],
        <<"Hello Erlang!">>,
        Req),
    {ok, Req2, Opts}.

rebar3 run

curl http://localhost:2938