[Delphi] DirectShow 강좌

 
DirectShow를 이용한 동영상 플레이 시키는 방법을 소개합니다.
Delphi XE 이상에서 컴파일 가능합니다.

준비(폼디자인)

1. 먼저 VCL Forms Application 을 생성합니다.
프로젝트를 저장하고 폼위에 Panel 컴포넌트를 올립니다.
Screen 으로 사용할 패널입니다.

Screen Panel의 Caption 을 지우고
Align 프로퍼티를 alClient 로 설정합니다.
그리고 Panel 을 하나 더 올립니다. 버튼올릴 패널입니다.
Caption 을 지우고 Align 프로퍼티를 alBotton으로 설정합니다.

코딩

2. uses 절에 Winapi.DirectShow9, Winapi.ActiveX 를 추가합니다.
3. private 절에 동영상 플레이어에서 사용할 기본 개체를 선언합니다.

FilterGraph: IGraphBuilder; //필터그래프의 인터페이스 중의 하나.
MediaControl: IMediaControl; // 미디어 제어 인터페이스 Play, Stop, Pause.
VideoWindow: IVideoWindow; // 영상 제어 인터페이스

4. Form Create 이벤트에서

CoInitialize(nil); //COM을 초기화한다

6. 폼위에 버튼을 올린 후 Click 이벤트에 변수 선언을 한 후

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var
  WFileName : Array[0..255] of WideChar;
  PFileName : PWideChar;
begin
  StringToWideChar('재생할 파일경로+파일명',WFileName,255);
  PFileName := @WFileName[0];
 
  // 동영상 파일을 Render 하기
  if FilterGraph.RenderFile(PFileName,nil) = S_OK then begin
    // 영상을 플레이할 패널 지정 Screen = Panel
    VideoWindow.put_Owner(Screen.Handle);
    VideoWindow.put_WindowStyle(WS_CHILD or WS_CLIPSIBLINGS or WS_CLIPCHILDREN);
    VideoWindow.SetWindowPosition(0,0,Screen.Width,Screen.Height);
    VideoWindow.put_MessageDrain(Screen.Handle);
 
    MediaControl.Run;
  end;
end;
cs

이제 Panel 위에 재생하려는 영상이 플레이 됩니다.

7. Form Close 이벤트에
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 중지
if Assigned(MediaControl) then MediaControl.Stop;
 
// 비디오 윈도우 해제
If Assigned(VideoWindow) then
Begin
VideoWindow.put_Visible(false);
VideoWindow.put_Owner(0);
End;
 
// DirectShow 인터페이스 해제
FilterGraph := nil;
MediaControl := nil;
VideoWindow := nil;
 
CoUninitialize; //COM을 셧다운시킨다.
cs
이렇게 코딩합니다.
이렇게 하면 Panel 위에 선택한 동영상이 재생됩니다.

추가기능

8. 열기 버튼 클릭했을때 파일 선택창 나오도록 하기

with TOpenDialog.Create(Self) do 
try 
  Filter := 'Media Files(*.avi;*.mpg;*.wmv;*.mp4)|*.avi;*.mpg;*.wmv;*.mp4;|All Files(*.*)|*.*;'; 
  Title := 'Open Media Files..'; 
  if Execute then begin 
    LoadMedia(FileName); 
  end; 
finally 
  Free; 
end;

9. 미디어 불러오는 코드 프로시져로 변경
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedure TfrmMain.LoadMedia(filename: String); 
var 
  WFileName : Array[0..255] of WideChar; 
  PFileName : PWideChar; 
begin 
  StringToWideChar(filename,WFileName,255); 
  PFileName := @WFileName[0]; 
  // 동영상 파일을 Render 하기 
  if FilterGraph.RenderFile(PFileName,nil) = S_OK then begin 
    // 영상을 플레이할 패널 지정 Screen = Panel 
    VideoWindow.put_Owner(Screen.Handle); 
    VideoWindow.put_WindowStyle(WS_CHILD or WS_CLIPSIBLINGS or WS_CLIPCHILDREN); 
    VideoWindow.SetWindowPosition(0,0,Screen.Width,Screen.Height); 
    VideoWindow.put_MessageDrain(Screen.Handle); 
 
    MediaControl.Run; 
    // 재생/일시정지 버튼 상태 
    btnPlayPause.Caption := ''일시정지''; 
  end; 
end;
cs
10. 재생/일시정지 토클 버튼 추가

화면에 버튼 컴포넌트를 추가한 후 OnClick 이벤트에
1
2
3
4
5
6
7
8
if btnPlayPause.Caption = '일시정지' then begin 
  MediaControl.Pause; 
  btnPlayPause.Caption := '재생' 
end 
else begin 
  MediaControl.Run; 
  btnPlayPause.Caption := '일시정지' 
end;
cs

11. 영상을 재생한 후 프로그램을 크기를 바꾸보면 처음 재생했던 패널 크기로만 영상이 재생되는걸
알수 있습니다. 패널 OnResize 이벤트에

if Assigned(VideoWindow) then 
  VideoWindow.SetWindowPosition(0, 0, screen.Width, screen.Height);

위와 같이 코딩을 하면 패널 크기가 바뀔때마다 화면 크기를 변경해 줍니다.

이젠 위 화면 같이 트랙바와 라벨컴포넌트를 이용해
타임라인 제어와 재생시간 표시를 해보겠습니다.

12. 트랙바 컨트롤을 화면에 추가합니다.
강좌 9. 에서 만든 LoadMedia 함수에 총재생시간을 구해서 트랙바의 MAX 값과 Min 값을 세팅해줍니다.

//총 재생 시간 구하기 
MediaPosition.get_Duration(MediaLength); 
TrackBar1.Max := trunc(MediaLength); 
TrackBar1.Min := 0;

13. 트랙바 OnChange 이벤트에 아래와 같이 코딩해줍니다.
1
2
3
4
5
6
7
If Assigned(MediaPosition) then Begin
    // LockTrack 은 Boolean 형의 전역변수임
    if not LockTrack then begin
        // 미디어의 위치를 트랙바위치로 지정
        MediaPosition.put_CurrentPosition(TrackBar1.Position);
    end;
End;
cs

14. 타이머 컴포넌트를 하나 추가하고 OnTimer 이벤트에
1
2
3
4
5
6
7
8
9
10
11
12
var
    CurPos : Double;
begin
    If Assigned(MediaPosition) then Begin
        MediaPosition.get_CurrentPosition(CurPos);
        Label1.Caption := Format('%s', [SecondToTimeStr(CurPos)]);
        
        LockTrack := true;
        TrackBar1.Position := trunc(CurPos);
        LockTrack := false;
    End;
end;
cs
LockTrack 전역변수를 사용하는 이유는 타이머 이벤트에서 트랙바 포지션을 바꿀때 OnChange 이벤트를 타지 않게 하기 위해서

15. SecontToTimeStr 함수 만들기
1
2
3
4
5
6
7
8
9
10
function TfrmMain.SecondToTimeStr(Sec: Double): string;
var
    H, M, S: Integer;
begin
    H := Trunc(Sec) div 3600;
    M := (Trunc(Sec) - H * 3600) div 60;
    S := Trunc(Sec) - H * 3600 - M * 60;
    Result := Format('%d:%d:%d', [H, M, S]);
end;
// 현재 값을 받아서 시:분:초 로 표시
cs
이상입니다. 실제 구현한 소스코드는 아래 github에 공개해 놓았습니다.
기초적인 소스니 필요하신 분은 이용하시길 바라요!!!
그리고 동영상 플레이어 강좌지만 파일 열기에서 mp3를 선택하면 mp3가 플레이 됩니다. ㅎㅎ

github 소스링크

댓글

이 블로그의 인기 게시물

2025년 7월 다이어리

1. 대학교 축제 전시 프로젝트