XDL Manual

XDL VideoView 활용 두번째

(piXoneer XDL Tutorial)

 

 

 

 

 

 

이 문서는 XDL Development Library

 설치 및 사용하기 위한 문서입니다.

 

2017. 01.

 

 

목차

XDL VideoView 활용 두번째... 1

1    사용하기... 3

1.1    NXVideoView 이용한 예제 프로그램 만들기... 3

1.2    Driver복사하기... 4

1.3    메뉴 생성하기... 5

1.4    NXVideoView컨트롤 올리기... 6

1.5    동영 열기 기능... 6

 

 

 

 

1     사용하기

 

1.1    NXVideoView를 이용한 예제 프로그램 만들기

1.1.1     Visual Studio 2010을 실행한다.

1.1.2     메뉴 [파일]-[새로 만들기]-[프로젝트]를 선택한다.

1.1.3     [새 프로젝트] 대화상자에서 왼쪽의 템플릿 창에서 “Visual C#”을 선택하고, 대화상자 중간의 목록에서 “Windows Forms 응용 프로그램을 선택한다. 프로젝트의 이름(XDL_VideoView2)을 입력하고 [새 프로젝트] 대화상자의 확인버튼을 클릭한다.

1.1.4     [도구상자] [항목선택]을 선택한다.

[도구 상자] 창의 일반에서 마우스 오른쪽 버튼을 클릭하여 생성되는 팝업메뉴에서 항목 선택메뉴를 선택한다.

 

메뉴를 선택하면 아래와 같이 [도구 상자 항목 선택] 대화상자가 나타나며, 대화상자 아래쪽에 있는 찾아보기버튼을 클릭한다.

 

열기 대화상자에서 “C:\Pixoneer\XDL1.2\bin\NXVideo.dll” 파일을 선택한 후 열기를 클릭하고, [도구 상자 항목 선택] 대화상자의 확인버튼을 클릭한다.

.Net Framework 구성요소 탭에 다양한 레이어와 NXVideoView가 설정된다. “확인”버튼을 클릭한다.

 

 [도구상자] 에 다양한 MapLayer들과 NXMapView가 추가됨을 확인한다.

1.1.1     솔루션 탐색기의 프로젝트 하부의 [참조]의 오른쪽 마우스 클릭을 통해 [참조추가]를 선택한다.

1.1.2 [찾아보기]탭으로 이동한 후 “C:\Pixoneer\XDL1.2\bin\”경로로 이동한다. Ctrl키를 누른채 연속으로 “NXDL.dll, “NXDLgr.dll”, “NXDLsm.dll”, “NXVideo.dll”을 선택한 후 “확인”버튼을 선택한다.

 

1.1.3 솔루션 탐색기의 프로젝트 하부의 [참조]항에 NXDL이 추가되었음을 확인한다.

 

1.2    Driver복사하기

Driver는 현재 데모 버전에서는 설치된 경로로부터 실행 경로 하부로 손으로 복사하여 넣어야 한다. 차기 버전에는 복사를 하지 않아도 실행될 수 있도록 구성된다.

 

1.2.1     XDL 라이브러리가 설치된 경로(C:\Pixoneer\XDL1.2\bin)로 이동한다.

1.2.2     VDDrivers폴더를 통째로 복사하여 현재 프로 젝트의 “…..\XDL_VideoView2\bin\Debug”폴더 하부에 복사하여 넣는다.

1.2.3     F5키를 눌러 프로그램을 실행하면 다음과 같이 구성된다.

1.3    메뉴 생성하기

1.3.1      [도구상자]  MenuStrip을 선택하고 Form1의 상단부에 드래그하여 위치시킨다.

 

1.3.2      메뉴에 다음과 같이 File-Open을 입력하여 생성한다.

1.4    Player컨트롤 생성하기

1.4.1     동영상 플레이어를 위해 Play, Stop, Pause기능과 진행율을 표시하는 스크롤 기능을 구현하기 위해 다음과 같이 디자인을 수행한다. 먼저 TableLayoutPanel을 하부에 Docking시키고 3개의 Column으로 구성하여 버튼과 스크롤 및 label을 이용하여 다음과 같이 화면을 구성한다. 화면을 구성하는 방법은 C# 컨트롤에 대한 내용으로 여기서는 생략한다.

 

1.5    NXVideoView컨트롤 올리기

1.5.1     [도구상자]-[일반]에서 NXVideoView를 드래그하여 Form1에 올려 놓는다. NXVideoView컨트롤의 [부모컨테이너에서 도킹]버튼을 눌러 도킹시킨다. 또한 NXVideoOverlay컨트롤을 NXVideoView 컨트롤 위에 드래그하여 올려놓는다.

 

1.5.2     NXVideoView[부모컨테이너에 도킹]을 눌러 Full화면으로 확장시킨다.

 

1.5.3     [F5]키를 눌러 프로그램을 실행한다. 아래와 같이 NXVideoView컨트롤이 존재하는 프로그램이 실행된다.

1.5.4      프로그램을 종료한다.

 

1.6    동영상 열기 기능 구현

1.6.1     디자인창에서 Toolbar[File]-[Open]을 더블클릭하여 함수를 자동 생성한다.

 

private void toolStripMenuOpen_Click(object sender, EventArgs e)
{

}

 

1.6.2     NXVideo객체들을 사용하기 위해서 다음과 같이 NXDL, NXVideo 네임스페이스를 추가한다.

using Pixoneer.NXDL;
using Pixoneer.NXDL.NXVideo;

 

1.6.3     NXVideoView구현시 필요한 XVideoIO, XVideo, XVideoChannel객체를 선언한다.

enum VideoAction { STOP, PLAYING, PAUSED }

struct VideoState
{
    public XVideo video;                  // 파일이나 네트워크로부터 입력되는 스트리밍데이터를 제어하는 기능을 수행할 객체 선언
    public XVideoChannel videoChannel;    // 동영상 개체에 포함된 채널 객체 선언
    public string videoFilePath;          // 동영상 파일 경로 
public VideoAction action;		// 비디오 플레이 상태를 정의하는 객체 선언
}

private XVideoIO m_videoIO = null;        // 동영상의 입출력을 담당할 객체 선언
private VideoState VS;			// 비디오 상태를 관리하는 객체 선언

 

1.6.4     Form1생성자에서 XVideoIO의 객체 생성 및 VideoState에 대한 초기화를 수행한다. 또한 프로그램 종료시에 메모리 관리 등을 위해 NXVideoView컨트롤의 초기화를 수행한다.

public Form1()
{
    InitializeComponent();
    m_videoIO = new XVideoIO(); // VideoIO를 생성
    
    VideoInit();
    nxVideoLayerOverlay1.LayerVisible = true;
}

private void VideoInit()
{
    // VideoState의 초기화
    VS.video = null;   
    VS.videoChannel = null;    
    VS.videoFilePath = string.Empty;
    VS.action = VideoAction.STOP;
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    // 동영상 채널 정보 초기화
    nxVideoView1.ResetVideoChannel();

    if (VS.video != null)
    {
        // 동영상 객체 Close
        VS.video.Close();
        VS.video = null;
    }

    if (m_videoIO != null)
    {
        // 동영상 입출력 객체 Dispose
        m_videoIO.Dispose();
    }
}

 

1.6.5     File-Open 버튼을 눌렀을 때 생성될 Open 대화상자와 선택된 파일에 대한 XVideo객체를 생성한다. 또한, XVideo객체에 실제 스트리밍을 담당하는 XVideoChannel객체를 활성화(Activate) 시켜 Frame을 내부적으로 생성하도록 지시한다.

 

private void toolStripMenuOpen_Click(object sender, EventArgs e)
{
// 새로운 파일 Open을 수행한다.
    OpenFileDialog openFileDialog = new OpenFileDialog();
    openFileDialog.Filter = "TS file(*.ts)|*.ts||";
    openFileDialog.RestoreDirectory = true;

    if (openFileDialog.ShowDialog() != DialogResult.OK) return;

    string videoPath = openFileDialog.FileName;

    // 동영상 파일의 존재 유무 체크
    if (System.IO.File.Exists(videoPath) == false)
    {
        MessageBox.Show(this, "해당 경로에 영상이 존재하지 않습니다.", "오류");
        return;
    }

// 파일 경로를 저장한다.
    VS.videoFilePath = videoPath;

    // 둥영상의 재생상태가 중지가 아닐 경우 동영상 재생 중지
    OnStop();

    // 동영상 스트리밍 환경을 생성시킨다.
    OnOpen();

    // 동영상을 Play 시킨다.
    OnPlay();
}

 

1.6.6     OnOpen함수에 동영상을 Play하기 위해 VS.videoFilePath에 설정된 파일 경로를 통해 NXVideoView컨트롤을 XVideoChannel로 초기화 시킨다.

// 동영상 파일 열기
public void OnOpen()
{
    try
    {
        string strError = null;
        // 동영상 스트림 정보 가져오기
        VS.video = m_videoIO.OpenFile(VS.videoFilePath, "XFFMPDRIVER", out strError);

        if (VS.video == null)
        {
            MessageBox.Show(this, "동영상 재생에 실패하였습니다. 파일을 확인해주십시오.", "파일 열기");
            return;
        }

        // 다중 채널을 가진 동영상 객체의 Channel 인덱스
        int nIdxChannel = 0;

        // 동영상 뷰에 재생할 동영상 채널을 성정
        nxVideoView1.SetVideoChannel(VS.video, nIdxChannel);

        // 입력 인덱스에 해당하는 Channel을 가져오기
        VS.videoChannel = VS.video.GetChannel(nIdxChannel);

        // GetChannel에 실패할 경우 Null 객체가 return되며, 그에 대한 예외처리
        if (VS.videoChannel == null)
        {
            MessageBox.Show(this, "동영상 재생에 실패하였습니다. 파일을 확인해주십시오.", "파일 열기");
            return;
        }

        // 동영상 객체에 포함된 Channel 객체 중 해당 Channel 객체를 활성화
        // 활성화된 객체만 스트리밍이 수행
        VS.videoChannel.Activate();

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
        MessageBox.Show(this, "재생 실패!", "동영상");
        VS.action = VideoAction.STOP;
    }
}

 

1.6.7     동영상을 Play시키도록 지시하는 OnPlay, Play되고 있는 도중에 비디오를 멈추고 초기화 시키는 OnStop, Play되고 있는 도중에 Pause 시키는 OnPause함수를 구현한다.

private void OnPlay()
{
    if (VS.action == VideoAction.PAUSED)  // 동영상이 중지 상태가 아닐경우
    {
         VS.videoChannel.Resume();        // 동영상 채널 Resume
         VS.action = VideoAction.PLAYING;
    }
    else  if (VS.action == VideoAction.STOP)                                // 동영상이 중지 상태일 경우
    {
        // 동영상 Channel을 처음부터 재생하다록 Play 신호 설정
        VS.videoChannel.Play();
        VS.action = VideoAction.PLAYING;
    }
}

// 동영상 멈춤버튼클릭 이벤트
private void OnPause()
{
    if (VS.action == VideoAction.PLAYING)
    {
        VS.videoChannel.Pause();         // 동영상 채널 Pause
        VS.action = VideoAction.PAUSED;
    }
}

// 동영상 정지버튼클릭 이벤트
public void OnStop()
{
    if (VS.videoChannel != null)
    {
        // 재생 Frame Buffer를 삭제
        VS.videoChannel.ClearFrameBuffer();
        // 동영상 재생 스크린을 갱신한다.
        nxVideoView1.RefreshScreen();
        // 동영상 재생 중지
        VS.videoChannel.Stop();
    }

    // 동영상 채널 정보 초기화
    nxVideoView1.ResetVideoChannel();

    if (VS.video != null)
    {
        // 동영상 객체 Close
        VS.video.Close();
        VS.video = null;
    }

    VS.action = VideoAction.STOP;
}

 

1.6.8     Form1에 있는 button_Play, button_Pause, button_Stop을 눌렀을 때 수행되는 Event기능을 구현한다.

private void button_Play_Click(object sender, EventArgs e)
{
    // 비디오가 Stop인 상태인 경우 다시 비디오를 저장된 파일 경로로부터 Open해서 설정한다. 
    if (VS.action == VideoAction.STOP)
    {
        OnOpen();
    }

    // 설정된 비디오를 Play한다.
    OnPlay();
}

private void button_Pause_Click(object sender, EventArgs e)
{
    // Play되고 있는 비디오를 Pause시킨다.
    OnPause();
}

private void button_Stop_Click(object sender, EventArgs e)
{
    // Play되고 있는 비디오를 Stop시킨다.
    OnStop();
}

 

1.6.9      [F5]키를 눌러 프로그램을 실행한다. [File]-[Open]메뉴를 눌러 stream.ts파일을 연다. button_Play, button_Pause, button_Stop버튼을 눌러 기능을 확인한다.