2011. 6. 17. 12:42

OSMF로 플레이어 만들기 - 1.5탄 - 컴파일 명령어 만들기

일단 OSMF로 플레이어를 만드려면 준비물이 필요하다. 최근에 나온 1.6 Sprint 5를 기준으로 샘플을 만들어볼텐데 그걸 어디서 구하냐... 하면 http://opensource.adobe.com/wiki/display/osmf/Downloads 여기서 구하면 된다.

이번에도 저렴하게 Edit Plus로 코딩할텐데 swc 라이브러리 파일을 complie 옵션에 포함시킬지 명령어를 만들어보자.

일단 http://livedocs.adobe.com/flex/3/html/compilers_06.html#149503 여기에 가보면 Command-line에서 사용되는 문법들을 정리해 뒀다. Builder에서 컴파일을 못할경우. 음. 그러니까. 예를 들어 리눅스 환경에서 개발할 경우라던가 하는 경우에 용이하게 사용되거나 나처럼 Builder의 정품 인증 30일을 넘어서 코딩하기 힘들때 용이하게 사용할 수 있겠다.


라이브러리 경로를 추가할 수 있게 되었다. 그렇다면 나는 libs라는 디렉토리를 만들고 거기에 OSMF.swc를 넣어준담에 컴파일을 해보면.. 아래와 같은 현상을 관찰 할 수 있다.

Main.as

 package
{
//-----------------------------------------------------------------------------
//
//  Imports
//
//-----------------------------------------------------------------------------
import flash.display.Sprite;

/**
 *  Main Class
 */
public class Main extends Sprite
{
    //-----------------------------------------------------------------------------
    // Constructor
    //-----------------------------------------------------------------------------
    /**
     *  Constructor.
     */
    public function Main()
    {
        super();
    }

    //-----------------------------------------------------------------------------
    // Variables
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
    // Properties
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
    // Methods
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
    // Events
    //-----------------------------------------------------------------------------
}
}

이렇게 코드를 짜놓고..

libs 폴더를 만들고

OSMF.swc를 복사해 붙여넣고


컴파일 명령어에 -library-path+=libs 명령어를 추가해주면

swf 파일이 생겨납니다.

매우 간단한 과정들이 진행되어 일단 1단계를 마무리 할 수 있게 되었습니다.
"난 Builder를 사용해서 저런거 몰라도 됨"이라고 한다면 뭐 크게 할 말은 없지만 Builder 뒤에서 저런 명령어들이 오고 가는거 조금 알고 있어도 괜찮지 않을까요.
2011. 6. 16. 16:16

OSMF로 플레이어 만들기 - 1탄 -


Flash라는 것을 조금 하다 보면 이런 요구사항들을 들어볼 수 있는데 "동영상 플레이어 만들어주삼" 인거심.
동영상 플레이어를 만드는 방법은 생각보다 많은 이벤트를 이해해야하고
NetStream 머시깽이랑 Video 클래스랑 NetConnection이랑 이것저것 많이 쉐킷쉐킷 섞어서 만들어야 하기 때문에 다들 꺼려하는 장르중에 하나다. 그도 그럴게 일단 Flash에서 동영상 플레이어란 미디어 서버에 붙어서 스트리밍 방식의 동영상 재생이 기본기능으로 자리잡고 있으므로 NetConnection으로 일단 커넥션을 열어두고 그 정보를 NetStream 클래스에 넘겨준다음에 NetStream에서 데이터를 스트리밍으로 받아서 Video에 넘겨주면 그 데이터를 재생시켜주는 순서를 갖게 된다. 뭔가 복잡한가??!!!

그래서 어도비에서 Open Framework 로 OSMF(Open Source Media Framework)라는 것을 만들어 냈다.


이게 뭐냐 하면 Flash로 할 수 있는 거의 모든 미디어 기능을 요녀석이 아주아주 간편하게 만들어주는 것. 이라고 생각하면 된다. 그와 동시에 해결해주는 것들이

1. HTTP Dynamic Streaming
2. RTMP Dynamic Streaming
3. Stage Video
4. Streaming Video Play
등등등..

미디어 서버로 동영상 재생하는건 다된다. 심지어 Live 방송도 재생한다.
그냥 알아서 다 해결해준다. 멋지지 않은가.
하지만 코드양은 좀 많다. 물론 예전보다야 많이 줄었다.
그래서 동영상 플레이어를 사용하는데 큰 어려움이 없어졌다.
그럼 이제 한번 만들어볼까? 다음 이시간에 계속.
2011. 6. 15. 19:38

아이폰에서 포스팅하기

오랜만에 블로그 포스팅에 열을 올리면서 오늘은 분당 정자동을 향해가는 버스 안에서 글을 올립니다.
은근히 잼나네요. ㅋ
그런데 아이폰이라 그런지 이미지는 못올리는 듯.. 티스토리 블로그 어플같은거 어디 없나요?

'etc' 카테고리의 다른 글

Google+  (0) 2011.08.04
BlogAPI 사용하기  (0) 2011.07.21
2011. 6. 14. 15:22

실버라이트 5 새로 추가된 기능들

실버라이트 5에서 새로 추가된 기능들 중 가장 눈여겨 봐야할 것은 역시 그래픽 영역인듯 합니다.
그래픽 렌더링은 Flash나 Sliverlight나 주력으로 삼고 밀고 있는 영역인데요. 이번 실버라이트 5에서는 아래와 같은 기능들이 추가 되었습니다.

 
  • Hardware Decode and presentation of H.264 improve performance for lower-power devices to render high-definition video using GPU support.
  • TrickPlay allows video to be played at different speeds and supports fast-forward and rewind. At up to twice the speed, audio pitch correction allows users to watch videos while preserving a normal audio pitch.
  • Improved power awareness prevents the screen saver from being shown while watching video and allows the computer to sleep when video is not active.
  • Remote-control support allows users to control media playback.
  • Digital rights management advancements allow seamless switching between DRM media sources.
영어로 되어있어서 무슨 이야긴지 모르는 사람을 위해 콩글리시밖에 할 줄 모르는 제가 구글 번역기와 통밥으로 대충 해독해 보면

1. GPU를 지원해서 하드웨어 디코드와
저전력 기기를 위해 고화질 비디오 렌더링 퍼포먼스를 개선했다.
2. 
TrickPlay 서로 다른 속도로 재생할 수 있으며 비디오 빨리 감기 및 되감기를 지원합니다. 최대 두 배 속도로, 오디오 피치 보정 정상적인 오디오 피치를 유지하면서 사용자가 비디오를 볼 수 있다.
3.  비디오 보는 중에는 스크린세이버가 동작하지 않고 컴퓨터가 잠자고 있으면 비디오가 동작하지 않는다.
4.  
원격 제어 지원 미디어 재생을 제어하는​​ 사용자 허용합니다.(이게 뭔소린지 모르겠습니다.)
5. DRM 기능 향상

뭐 이정도가 되는 듯 합니다.
이것 외에 여러가지가 향상되었는데 이는 직접 찾아가보시면 도움이 될거라고 생각합니다.

'Sliverlight' 카테고리의 다른 글

Sliverlight 5가 나왔네요.  (0) 2011.06.14
2011. 6. 14. 12:22

Sliverlight 5가 나왔네요.

아직 베타버젼이지만 앞으로 실버라이트가 어떤 기능들을 들고 나올지 기대되는 군요.
 

 
좀더 자세한 이야기는 여기에 http://www.microsoft.com/silverlight/future/ 

'Sliverlight' 카테고리의 다른 글

실버라이트 5 새로 추가된 기능들  (1) 2011.06.14
2011. 6. 13. 20:30

야훔의 저렴한 개발 시즌2 - 싱글톤 패턴


예전에 시즌 1에서 이야기 했는지 모르겠지만 디자인 패턴이라는 부분에 대해서 좀 짚고 넘어가야할 부분이 있는것 같다. 요즘 플래시 모임이나 어디 게시판에 가보면 디자인 패턴 좀 안다면서 코드를 주르륵 흘려놓고 그걸 어떻게 치워야 할지도 모른 채 지나가버리는 사람들을 종종 보게 되는데 여기서 문제는 그 주르륵 흘려놓고 뒷 수습을 못한다는 부분이다.
디자인 패턴이라고 흘려놓은 코드들이 잘못되었다는게 아니라 디자인 패턴이라는 것이 도데체 왜 생겨났고 그걸 어떻게 이용하는 것인지 그리고 그걸 왜 이용하는 것인지에 대한 이해 없이 슥 코드만 써놓고 "이게 싱글톤 패턴임"이라고 적어놓는다는데 있다. 그러 식의 글을 보면서 느끼는건 "나는 싱글톤을 알고있다. 그건 이런 코드로 작성하면 됨"하고 자랑하는 것으로 밖에 보이지 않는다. 그런 사람들하고 대화를 하다보면 디자인 패턴이라는게 왜 있고 그걸 왜 쓰고 도데체 그걸 어디다 어떻게 적용하는 것인지에 대해 전혀 이해없이 그저 코드만 외워서 쓰는 경우가 많다.
본문으로 들어가기 전에 미리 이야기하는데 디자인 패턴을 설명하는 것은 "방법론을 공유하자" 라는 부분과 "방법론을 좀 더 간결하게 만들자"하는 개발자 적 욕구로 시작되었음을 이해해야한다. 그래서 최초의 디자인 패턴을 서술해 놓은 책을 보면 코드는 단 한줄도 없었다고 한다. 그저 그 책은 "이런 문제가 있을 땐 이런식으로 해결하자"는 식의 풀이집에 더 가까웠다는 것이다. 그 이후 그 책을 기반으로 각각의 언어로 구현하는 방법들을 소개하는 책들과 글들이 쏟아져 나왔다. 그러니 "자바에서 싱글톤 패턴이 구현되나요?"라던가 "자바에서 MVC 패턴을 구현하는 방법이 있나요?" 같은 바보같은 질문은 삼가하도록 하자. 자바나 플래시, C나 C++과 같은 언어들의 종류를 불문하고 디자인 패턴이라는 것은 구현된다. 서로서로 방법이 다를 뿐 디자인 패턴이라는 것은 결국 하나의 흐름에서 각각의 문제를 해결하기 위한 방법들을 만들어가는 가이드 라인일 뿐이니.
서론이 길었다. 본론으로가자.

이번 포스팅은 싱글톤 패턴에 대해서 써놓으려고 한다. 싱글톤을 처음 이야기 하는 이유는 디자인 패턴 중에서 가장 쉽고 설명하기도 간편하며 가장 많이 사용되는 패턴이라서 그렇다. 그래서 이번 포스팅에서는 Actionscript 3.0으로 싱글톤을 구현하는 방법에 대해 설명할텐데 그전에 싱글톤이 뭔지부터 좀 알아보자.


위키엔 없는게 없다. 역시 우리 모두의 백과사전. 싱글톤 패턴의 기본적인 정의를 잘 설명해 놨다. 싱글톤 패턴의 구현여부는 인스턴스가 하나만 있어야한다는 무결성을 보장해야하며 이 인스턴스에 접근 할 수 있는 전역적인 접촉점을 제공하면 된다. 음. 데이터의 무결성. "단 하나만의" 객체를 생성하는 약속이 보장되어야 한다는게 바로 싱글톤 패턴이다. 그럼 이걸 언제 사용하지?

싱글턴 패턴이나 팩토리 패턴, 옵져버 패턴, MVC패턴. 이런게 다 어디에 사용하느냐. 언제 사용하느냐. 에 대한 질문을 받을때면 대답하기가 굉장히 애매해진다. "싱글톤 패턴이 뭔가요?"라고 질문하면 "그건 ....."이라면서 설명이라도 해줄 텐데 "싱글톤 패턴은 언제 사용해요?"라는 질문에는 "적절하게 필요할 때..."라고 밖에 대답을 못해주겠다. 데이터가 두번 생성되지 말아야하는 경우가 어디 한두가지여야 말이지. 뭐. 싱글턴 패턴의 용도는 일단 앞에서 말했다 시피 데이터가 두번 생성되지 말아야하는 상황에서 사용된다. 무결성이 보장되어야하고. 한번만 생성되어야하며 그 데이터의 변경 값에 따라 다른 객체들도 그 변경값이 동일하게 적용되어야하는 상황에서 싱글턴 패턴을 사용한다. 간단한 예제를 들어서 설명해볼까. 일단 Flash에서 빈번하게 사용되는 싱글턴 패턴 클래스를 만들어 보자. 워낙 많은 사람들이 알고 있는 코드이기도 하고 코드를 좀 살펴보면 이해하기도 간편하니 설명없이 코드를 써놓을 텐데 코드가 이해가 안간다고 슬퍼하지 말 것. 필요한 때가 오면 다 이해가 되니깐.

classes/UserInfo.as
package classes
{
   public class UserInfo
   {
       public function UserInfo(creator:Creator = null):void
       {
           if( null != instance )
           {
               throw new Error(“이미 객체가 생성되어 있음”);
           }

           if( null == creator )
           {
               throw new Error(“정상적인 방법으로 생성하지 않았음”);
           }
       }

       public static var instance:UserInfo;
public var isLogin:Boolean = false; 

       public static function getInstance():UserInfo
       {
           if( null == instance )
           {
               instance = new UserInfo( new Creator() );
           }

           return instance;
       }
   }
}

final class Creator
{} 

위의 코드가 Flash에서 흔히 사용하는 싱글톤 패턴의 정형화된 구현인데 위와 같은 방법으로 코드를 작성할 경우 getInstance() 라는 static 메서드를 통하지 않는다면 다른 방법으로 instance를 생성할 방법이 없도록 구현된다. 결국 instance는 한개 밖에 생성되지 않기 때문에 그 클래스 안의 내용들은 한번만 생성되고 무결성을 유지할 수 있게 된다. 저렇게 코드를 하나 두고 샘플클래스 몇몇개를 작성해보도록 하자.

Main.as
package
{
import flash.display.Sprite;
import flash.display.Graphics;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;

import classes.LoginCheck;
import classes.UserInfo;

public class Main extends Sprite
{
    public function Main()
    {
        super();

        addEventListener( Event.ADDED_TO_STAGE, onAddedToStage );
    }

    private var btn_login:Sprite;
    private var btn_logout:Sprite;
    private var txt_output:TextField;
    private var loginCheck:LoginCheck

    /**
     *  @private
     *  Create Buttons
     */
    private function createButtons():void
    {
        var g:Graphics;

        if( null == btn_login )
        {
            btn_login = new Sprite();
            
            g = btn_login.graphics;
            g.clear();
            g.beginFill( 0xFF0000, 1 );
            g.drawRect( 0, 0, 100, 50 );
            g.endFill();

            btn_login.buttonMode = true;
            btn_login.useHandCursor = true;

            btn_login.addEventListener( MouseEvent.CLICK, onLoginClick );

            addChild( btn_login );
        }

        if( null == btn_logout )
        {
            btn_logout = new Sprite();

            g = btn_logout.graphics;
            g.clear();
            g.beginFill( 0x0000FF, 1 );
            g.drawRect( 0, 0, 100, 50 );
            g.endFill();

            btn_logout.buttonMode = true;
            btn_logout.useHandCursor = true;

            btn_logout.addEventListener( MouseEvent.CLICK, onLogoutClick );

            addChild( btn_logout );
        }

        if( null == txt_output )
        {
            txt_output = new TextField();
            txt_output.autoSize = TextFieldAutoSize.LEFT;
            txt_output.text = "logout";
            addChild( txt_output );

            loginCheck = new LoginCheck( txt_output );
        }
    }

    private function updateButtons():void
    {
        if( null != btn_login )
        {
            btn_login.x = 10;
            btn_login.y = 10;
        }

        if( null != btn_logout )
        {
            btn_logout.x = 115;
            btn_logout.y = 10;
        }

        if( null != txt_output )
        {
            txt_output.x = 225;
            txt_output.y = 10;
        }
    }


    /**
     *  @private
     *  Added To Stage
     */
    private function onAddedToStage( event:Event ):void
    {
        removeEventListener( Event.ADDED_TO_STAGE, onAddedToStage );

        stage.align = StageAlign.TOP_LEFT;
        stage.scaleMode = StageScaleMode.NO_SCALE;

        createButtons();

        updateButtons();
    }

    /**
     *  @private
     *  Click Login button
     */
    private function onLoginClick( event:MouseEvent ):void
    {
        UserInfo.getInstance().isLogin = true;

        if( null != loginCheck )
        {
            loginCheck.checkLogin();
        }
    }

    /**
     *  @private
     *  Click Logout button
     */
    private function onLogoutClick( event:MouseEvent ):void
    {
        UserInfo.getInstance().isLogin = false;

        if( null != loginCheck )
        {
            loginCheck.checkLogin();
        }
    }
}
}


classes/LoginCheck.as
package classes
{
import flash.text.TextField;
public class LoginCheck
{
    public function LoginCheck(targetField:TextField)
    {
        field = targetField;
    }

    private var field:TextField;

    public function checkLogin():void
    {
        if( true == UserInfo.getInstance().isLogin )
        {
            field.text = "login";
        }
        else
        {
            field.text = "logout";
        }
    }
}
}

 
위와 같이 코딩하고 나면 TextField에 Text를 입력하는 부분은 Main에서 해주는게 아니라 LoginCheck라는 클래스에서 해주게 되어있다. 이때 LoginCheck의 값에 따라서 TextField에 "login"이나 "logout"을 뿌려주는데 Main에서는 그저 UserInfo라는 싱글톤 클래스에 값을 변경해주는 것 뿐이고 그것에 대한 행동은 LoginCheck라는 클래스에서 알아서 하도록 냅두기 위함이다.
여기서 싱글톤 클래스를 사용하는 한가지 예를 살펴보았다. "이게 뭔소리여"할 수도 있는데 나중에 도움이 되리라 생각하고 읽어보길 바란다.  



p.s http://goo.gl/Ueoip 이것은 싱글톤 패턴에 대한 정리로 예전에 디자인 패턴에 대해 정리한 적이 있었는데 그때 써놓은걸 간추려놓은 것임. 싱글톤 패턴을 구현하는 기술적 방법론에 대해 서술했음.