Player 만들기..

예전부터 해보고 싶었다.
UI에 관련된 일을 하면서.. 그리고 DirectShow를 접하면서
KMPlayer를 쓰면서 정말 잘만들었고 나만의 Player도 저렇게 만들어보고 싶다는 생각을 많이 했다.

이번에 다행(?)스럽게도 연관된 프로젝트가 주어졌다.
비록 시간은 부족하지만.. 어느정도 흉내낸 프로그램은 만들 수 있을것이다.

일단 요구사항은

1. 파일재생
2. 파일전송
3. 파일자르기
4. UI

재생은 예전에 Capture 코드를 이용하여 변경해서 만들었지만.. 많이 다듬진 못했다.. ㅠ_ㅠ
전송은 그냥 Broadcasting.. -_-;;; UDP소켓을 이용하는데 앞에 헤더를 붙이고 잘라서 보내니 너무느리다.. 이건 많이 검토해봐야 겠다..

파일 자르기는 정말 Virtualdub처럼 만들고 싶었지만. 아직 실력이 미숙하여 어려운점이 많았다.
일단 VFW라이브러리를 사용하여 AVI파일만 자를수 있도록 하였다.
하지만 특정 AVI 파일에서 Audio Stream을 읽어올때나 쓸때 VFW함수가 에러를 리턴하였다.
이건 로우레벨로 가야 수정이 가능할듯하다. 시간의 여유가 없어서 일단 마무리 했다...

마지막으로 많이 신경은 썼지만 아직도 허접한.. UI다..

--------------------------------- 추가사항1
VFW는 audio stream이 VBR(Variable Bit Rate)을 지원하지 않는다.
그래서 일부 AVI파일 (Dvix코덱은 VBR을 기본적으로 사용한다.) 에러가 리턴되었던 것이다. ㅠ_ㅠ
따라서 Audio stream을 split하려면 virtualdub을 분석해야 할듯하다.

--------------------------------- 추가사항2
필요한 창이 많아지면서 스킨색상의 변경에 대한 이벤트가 많아졌다.
일일히 파라미터로 Color값을 넘겨주는것에 한계를 느껴 Skin Mediator 를 만들었다.
Mediator는 단순히 Colleague들만 등록,삭제기능을 하고 이벤트 발생시 Colleague맵을 돌며 알려준다.
따라서 스킨을 써야하는 윈도우는 Colleague를 상속받고 Colleague는 생성자에서 Mediator에 등록을 해준다.
이때 Colleague에서 Mediator를 참조해야하므로 Mediator는 싱글톤 전역클래스에 공개를 해두었다.
윈도우들은 이벤트 함수 하나에서 필요한 파라미터를 전달받아 각자에 맞게 구현해주면 스킨의 동기화가 완료되었다.


UI 보기




초기 화면이다.
위쪽은 메뉴, 아래쪽은 컨트롤이다.
이모든걸 다 GDI+를 이용해서 그렸다. -_- 물론 몇개의 오픈소스를 이용하긴했지만.. 상당한부분을 직접구현해보았다.

처음에 Dialog based로 만들어서 모든 컨트롤을 Dialog에 구현을 했는데 깜빡임이 정말 심했다.
그래서 Toobar( menu, display, control)을 child로 구현하였다.
막상 이렇게 해보니 SDI구조랑 별반 차이가 없어졌다... 나 왜 다이얼로그로 만든거니..-_-;;
하면서 불편한 사항은 내가 조금씩 추가하면서 만들고 있다.
아직 불완전하지만.. KMP에 버금갈때까지 진행할 것이다.. 후후..
기다려라..

-------------------- 깜박임 문제.
예전의 프로그래밍에서는 UI작성시 상용 라이브러리를 썼었다.
하지만 이 프로젝트에서는 상용을 쓰지말고자 해서 코드를 왠만큼다 수정하였다.
거기서 문제가 memDC의 클래스를 변경하는 부분이었는데. 그리기를 GDI+로 하면서 memory DC 에 그리는 것이 미숙했다.
하지만 깜박임문제가 계속 지속되면서 차분히 분석한 결과 DC에 직접그리는 문제때문으로 생각되었다.
그래서 MemoryDC에 그리고 마지막에 DC로 복사를 하면서 문제가 말끔히 해결되었다.

-------------------- 여기서 약간의 소스공개 (SliderCtrl)
플레이어 SeekBar를 만들때 CSliderCtrl을 쓰는데, 기본 SliderCtrl은 마우스 클릭시 Tick단위로 이동된다.
하지만 다른 플레이어(GOM,KMP)를 보면 클릭되는 위치로 Thumb이 이동된다. (물론 MPC코드를 참고했다..-_-)

void _SetThumbPosition(CPoint point)
{
    CRect rc;
    GetChannelRect(&rc);
     if(rc.left >= rc.right) return;


    int nMin, nMax;
    GetRange(nMin, nMax);

    if(point.x < rc.left) SetPos(nMin);
    else if(point.x >= rc.right) SetPos(nMax-1);
    else
    {
        __int64 w = rc.right - rc.left - 1; ///-1는 Thumb size
        if(nMin < nMax)
        {
            SetPos( (nMin + ((nMax-nMin)*(point.x-rc.left)+(w/2)) / w ));
        }
    }

}
// Thumb Pos Move
void OnLButtonDown(UINT nFlags, CPoint point)
{
    _SetThumbPosition(point);
/// 부모창에 알려 HSCROLL 이벤트를 발생시킨다. - 이 메시지로 비디오위치를 이동시킨다.
    GetParent()->PostMessage(WM_HSCROLL, MAKEWPARAM((short)0, SB_THUMBPOSITION), (LPARAM)m_hWnd);
    
    CSliderCtrl::OnLButtonDown(nFlags, point);
}

-------------------- UI 변경사항


버튼 수정, Resize - 오른쪽 밑에서만 가능하도록 변경함.. (꺄뵤~~ 노다메♡)

--------------------------------- 변경사항..


흠.. 현재의 나도 노다메의 모습과 동일..? OTL...

자막추가.. - 오버레이나 믹싱이아니라 그냥 출력했다.. 좀 시간이 걸릴듯함..
Renderer 선택 - Default, Overlay Mixer, VMR7, VMR9 선택가능하게 함. (Renderless 모드는 수정할게 많은 관계로 Windowed 모드로 구현하였다.)
스킨선택 - 다양한 색상을 적용할수 있게 함

흠.. 점점 지체되는듯 하다.. 언넝 여러가지 넣어야하는데. 아자.. 힘내자.

--------------------------------- 비스타에서 연습..

나중에는 UI의 대부분은 C#으로 구현하고 다른연산은 C++로 가지 않을까하는 생각에
마침 비스타 환경을 구축하였고, DirectShow .Net도 잘 구현되어 있어서 한번 테스트 해보았다.
.NET Framework 3.5 환경에서 WPF로 구현하였는데 생각보단 느리다.. 아직은 MFC가 낫다.. -_-;;
그래도 Interop쪽은 공부해놔야 두루두루 써먹을수 있겠지..


보너스로 티파니 눈웃음 작렬~~♡



by 이카로스 | 2008/01/23 18:15 | I am ... | 트랙백 | 덧글(2)

트랙백 주소 : http://icarosss.egloos.com/tb/1714146
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Commented at 2008/04/11 18:41
비공개 덧글입니다.
Commented at 2008/04/14 18:04
비공개 덧글입니다.

:         :

:

비공개 덧글

<< 이전 페이지     다음 페이지 >>