미디어 다운로드 진행률 출력(Percentage:%)

다운로드 진행률 Percentage(%)

[1.1] 다음 강좌 참고

http://taedi.hosting.paran.com/tc/entry/Downloader-클래스를-이용한-간단한-이미지-다운로드?category=8

1.1에서는 Download 클래스의 DownloadProgressChanged 이벤트를 이용하여 % 를 출력했지만 2.0에서는 WebClient의 DownloadProgressChanged() 이벤트를 사용하며, Silverlight 2.0에 새로 추가된 이벤트 입니다.

MediaElement media = null;
       
        public Page()
        {
            InitializeComponent();
            WebClient webClient = new WebClient();
           // 동영상 경로
            webClient.OpenReadAsync(new Uri("sl2.wmv", UriKind.Relative));
            webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);

            webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
        }

        void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
           // DownloadProgressChangedEventArgs는 미디어를
           // 다운로드 하는 동안 일어나는 이벤트 아규먼트입니다.
            var done = e.ProgressPercentage;
            downProgress.Text = Math.Floor(done) + "%";
        }

        void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            media = new MediaElement();
            media.SetSource(e.Result);

            LayoutRoot.Children.Add(media);
            media.Width = 300;
            media.Height = 300;
            media.Play();
        }




참고

길버트님 블로그 : Downloader 대신 WebClient
공도님 블로그 : 리소스와 URI

[MediaPlayer] 11. Chapters[1-3:Chapters 구현]

지난강좌에서 인코딩한 동영상과 저장한 스틸사진으로 Chapters 기능을 구현해보겠습니다. images 폴더에 있는 이미지의 이름은 00.01.00.jpg, 00.02.00.jpg.... 00.07.00.jpg 이런식으로 이름을 변경합니다.

사용자 삽입 이미지

Chapters 의 7개의 Image 컨트롤에 하드코딩으로 이미지경로를 지정해 주면 됩니다.

사용자 삽입 이미지

이미지 컨트롤에 대한 클릭 이벤트 7개를 선언합니다.

사용자 삽입 이미지


7개의 이벤트 모두 동일한 코드가 들어가 있습니다.

MultiMedia.Position = TimeSpan.FromSeconds(60)

동영상 시작시점에서 60초의 지났을때의 위치를 MediaElement의 Position속성에 값을 할당합니다.

OnPlay_MouseLeftButtonDown(sender, null)

OnPlay 이벤트를 호출하여 동영상의 현재재생시간부터 자동으로 동영상을 재생합니다.

[F5]키를 눌러 실행을 합니다.

사용자 삽입 이미지

1번째 Chapters는 재생시작이 1분부터 시작합니다. 재생시간과 PlayLocation이 옮겨진것을 확인할 수 있습니다.

사용자 삽입 이미지

4번째 Chapters는 재생시작이 4분부터 시작합니다.

사용자 삽입 이미지


7번째 Chapters는 재생시작이 7분부터 시작합니다.

지금까지 작업한 동영상플레이어 소스(최종)를 첨부합나다(동영상 제외) :


마지막 강좌는 조금 허무하게 끝난것도 같고 많이 아쉬움이 남는것 같습니다. Chapters 강좌를 시작할때 이것은 짝퉁(?) 또는 편법이다라는 이야기를 했던것을 기억할 것입니다. 어디까지나 이런식으로도 구현을 할 수 있다라는 것이지 이게 정답은 아니며 좀더 좋은 방법이 있다고 생각합니다.

먄약 강좌에서 다루었던 내용보다 더 좋은 방법이나 기술이 있다면 한수 배운다는 입장으로 저에게 지식을 나누어 주시기 바랍니다.^^

밥>>>> 술>>>> 고기>>>> 능력것 쏘갰습니다. ㅎㅎ

아무튼 저의 부족한 강좌를 여기까지 따라오시느라 수고가 많으셨습니다. 다음에는 더 좋은 내용으로 강좌를 진행하겠습니다.

수고하셨습니다. 짝! 짝! 짝!


[MediaPlayer] 10. Chapters[1-2:Expression Encoder]

Expression Encoder 에서 동영상을 인코딩하고 Markers를 지정하여 일정시간 간격마다 스틸사진 저장하는 작업까지 진행하겠습니다. Expression Encoder은 2007년 9월 6일자로 정식버전이 릴리즈 되었습니다. 720p 수준의 고화질 HD영상을 지원하며 Overlay 기능을 통한 광고 및 자막 삽입등 여러가지 막강한 기능을 갖추고 있습니다.

로컬PC에 Expression Encoder가 설치되지 않았다면 아래링크에서 다운로드 하시기 바랍니다.

 - Expression Encoder 1.0 다운로드 (Free Trial Download )

사용자 삽입 이미지


Expression Encoder의 화면 레이아웃입니다. 프로그램 사용은 아주 쉽고 간단하며 몇 번만 따라서 해보시면 전문가(?)수준의 고품질의 동영상을 제작할 수 있습니다.

1) 동영상 Import
동영상을 Expression Encoder에 불러옵니다. 메뉴에서 File>Open을 클릭하면 열기대화상자가 나타나고 여기서 동영상을 선택하여 불러오면 됩니다.

사용자 삽입 이미지

동영상은 기존에 테스트 하던 동영상을 가져왔습니다. 동영상이 Encoder안에 불러온것을 확인할 수 있습니다.

2) Markers
일정 시간 간격마다 Markrs를 지정하고 스틸사진을 저장합니다.
사용자 삽입 이미지

붉은색으로 표시한 번호1)은 Markers를 지정하는 속성창입니다. 2)번은 타임라인입니다. Markers를 지정하면 일정 간격마다 구문선이 생깁니다.

사용자 삽입 이미지

Add를 클릭하면 새로운 Markers가 등록되며 Thumbnail를 체크해야 스틸사진을 저장할 수 있습나다. Time는 직접 입력해도 되고 아래그림에서 직접 지정해도 됩니다.
사용자 삽입 이미지


하나의 Markers가 등록되면 타임라인에도 표시가 됩니다.

사용자 삽입 이미지

매 1분간격마다 Markers를 지정하여 7개의 Markers를 등록합니다.

3. Output 지정
인코딩 한 동영상을 저장할 위치를 지정합니다.

사용자 삽입 이미지


사용자 삽입 이미지

Template는 기본적으로 인코딩을 하면 동영상을 재생해주는 플레이어를 지정합니다. 그러나 여기서는 이 작업이 필요없으므로 그냥 통과합니다. Media File Name는 기존 동영상이름 그대로 합니다. Directory는 인코딩 된 동영상을 저장하는 경로(Path)를 지정합니다.

4. 인코딩(Encoding)
사용자 삽입 이미지

동영상 잉코딩 시간은 로컬pc의 사양 및 동영상의 품질에 따라 다소 시간차가 발생할 수 있습니다.

5. 인코딩된 동영상 확인

사용자 삽입 이미지

인코딩된 동영상과 7개의 스틸 사진을 확인할 수 있습니다.

6. Silverlight 프로젝트서 기존 동영상을 지우고 새로 인코딩된 동영상으로 Media 폴더에 저장하고 스틸사진은 Images폴더를 만든다음 폴더안에 집어넣으면 됩니다.

사용자 삽입 이미지


두개의 폴더에 각각 저장한 다음 Silverlight 프로젝트를 컴파일 해주면 ASP.NET 프로젝트에도 동일하게 폴더 생성이 됩니다.

사용자 삽입 이미지


여기까지 동영상 인코딩 작업이 끝났습니다. 다음강좌는 동영상 플레이어의 마지막 강좌로서 실제 Chapters기능을 적용하는 비하인드코드에서 작업입니다..

여기까지 수고하셨습니다...

[MediaPlayer] 8. Timer

동영상의 전체 재생시간과 동영상이 재생중일때 현재 재생시간을 화면에 표시합니다.



<Canvas Width="142.083" Height="18.25" Canvas.Left="58.219" Canvas.Top="553.674">

       
<Rectangle x:Name="PlayTimePanel" Width="148.333" Height="24.126" Stroke="#FF000000" StrokeThickness="0.5" 
RadiusX
="2" RadiusY="2" Canvas.Left="-3.006" Canvas.Top="-2.839">
           
<Rectangle.Fill>
               
<LinearGradientBrush EndPoint="0.5, 1" StartPoint="0.5, 0">
                   
<GradientStop Color="#FF201F1F" Offset="0"/>
                    <
GradientStop Color="#FF201F1F" Offset="1"/>
                    <
GradientStop Color="#FF383838" Offset="0.481"/>
                    <
GradientStop Color="#FF606060" Offset="0.553"/>
                </
LinearGradientBrush>
           
</Rectangle.Fill>
       
</Rectangle>

       
<TextBlock x:Name="txPlayCurrentTime" Width="68" Height="16" FontSize="14" Text="00:00:00" 
           TextWrapping
="Wrap" Opacity="0.7" Foreground="#FFF5F5F5" Canvas.Left="0.328" 
           Canvas.Top
="-0.418" FontFamily="Verdana"/>
        <
TextBlock Width="7" Height="20" FontSize="12" Text="/" TextWrapping="Wrap" Canvas.Left="68.693" 
           Opacity
="0.7" Foreground="#FFF5F5F5" Canvas.Top="0.748" FontFamily="Verdana"/>
        <
TextBlock Width="68" Height="16" FontSize="14" Text="00:00:00" TextWrapping="Wrap" 
        x:Name
="txPlayTotalTime" Canvas.Left="76.363" Opacity="0.7" Foreground="#FFF5F5F5" 
          FontFamily
="Verdana"/>
           
        <
Rectangle Opacity="0.01" Width="11.56" Height="12.232" Fill="#FFFFFFFF" Stroke="#FFFCFCFC" 
         RadiusX
="0" RadiusY="0"/>
           
    </
Canvas>

재생시간 관련 xaml 코드입니다.

사용자 삽입 이미지

동영상의 전체 재생시간을 출력하는 이벤트 입니다.

사용자 삽입 이미지

시간, 분, 초를 String.Format()함수에 정수로 포맷을 설정하여 출력합니다.

동영상의 현재 재생시간과 동영상이 끝났을때 현재재생시간이 00:00:00으로 초기화 되는 코드를 집어넣어야 합니다.

사용자 삽입 이미지

timerPlayProgress_Completed 이벤트에 현재재생시간을 출력하는 코드를 집어넣습니다.

사용자 삽입 이미지

OnStop_MouseLeftButtonDown 이벤트에 동영상이 재생이 완료되면 자동적으로 현재재생시간을 00:00:00으로 출력됩니다.

마지막으로 지금까지 강좌를 잘 따라오셨다면 동영상 재생관련 이벤트에서 아래그림에서 처럼 특정코드를 보실수 있었을 겁니다.

사용자 삽입 이미지

동영상의 현재재생시간을 각각의 이벤트가 발생할때 마다 변경된 시간을 출력합니다. [F5]키를 눌러 동영상 플레이어의 재생시간 실행결과를 확인하시기 바랍니다.

사용자 삽입 이미지

지금까지 작업한 동영상플레이어 소스를 첨부합나다(동영상 제외) :


여기까지 동영상 플레이어에 대한 강좌는 마무리가 되었습니다. 아마도 Chapters 기능에 대해 왜 강좌를 안하냐는 질문을 하실것 같아서... 한말씀 올리고 이번강좌를 마무리 하겠습니다. Chapters 기능은 실제로 동영상 스트리밍 과정에서 UCC를 사용자가 업데이트 하고 그 동영상에 대해 특정 시간마다 스틸컷(정지사진)을 캡쳐해서 특정폴더나 영역에 저장을 해야 합니다. 만약 강좌가 진행된다면... Expression Encoder에서 동영상을 인코딩하고 스틸컷(정지사진)을 저장한 다음 편법(?)으로 실버라이트에서 Chapters기능을 구현해야 할것 같습니다....

곧 준비해서 강좌를 올리도록 하겠습니다.

여기까지 수고하셨습니다.

[MediaPlayer] 7. Volume

동영상의 볼륨을 조절하는 기능을 구현하겠습니다. 음소거(Mute)및 볼륨을 크게 하거나 작게 하는 기능이 주로 포함되어 있습니다.

사용자 삽입 이미지

Mute Button : 음소거 버튼
VolumeProgress : 볼륨크기를 설정 (0.1 ~ 1.0)
VolumeDuration : 볼륨크기의 범위

<!--Mute Button-->
 
<Canvas x:Name="MuteButton" Width="22.599" Height="22.915" Cursor="Hand" Canvas.Left="471.664" Canvas.Top="524.333">
   
<Canvas.RenderTransform>
     
<TransformGroup>
       
<ScaleTransform ScaleX="1" ScaleY="1"/>
        <
SkewTransform AngleX="0" AngleY="0"/>
        <
RotateTransform Angle="0"/>
        <
TranslateTransform X="0" Y="0"/>
      </
TransformGroup>
   
</Canvas.RenderTransform>

   
<Path x:Name="Path_17" Width="7.97936" Height="13.5934" Canvas.Left="1.2951" Canvas.Top="4.71643" 
Stretch
="Fill" Data="F1 M 1.32712,8.875L 3.93698,8.875C 3.93698,8.875 5.3299,
6.52588 7.41919,4.85266C 9.50854,3.17944 10.212,17.4561 7.51581,18.3099C 7.51581,18.3099
4.84143,16.2371 4.22205,14.723L 1.2951,14.723L 1.32712,8.875 Z ">

     
<Path.Fill>
       
<RadialGradientBrush RadiusX="5.47281" RadiusY="9.05507" Center="1.71548,1.71219" 
              GradientOrigin
="1.71548,1.71219">
         
<RadialGradientBrush.RelativeTransform>
           
<TransformGroup>
             
<RotateTransform CenterX="1.71548" CenterY="1.71219" Angle="-90"/>
            </
TransformGroup>
         
</RadialGradientBrush.RelativeTransform>
         
<GradientStop Color="#FFFFFFFF" Offset="0"/>
          <
GradientStop Color="#00FFFFFF" Offset="1"/>
        </
RadialGradientBrush>
     
</Path.Fill>
   
</Path>
   
<Path x:Name="MuteOffSymbol" Width="10.0461" Height="16.9826" Canvas.Left="10.8405" 
Canvas.Top
="3.45026" Stretch="Fill" Data="F1 M 20.8867,11.7611C 20.8867,15.3888 18.5204,18.5812 14.
9367,20.4329C 14.2469,19.9484 13.6205,19.3661 13.0757,18.7044C 16.0509,17.2804 18.0381,14.7036 18.0381,1
1.7611C 18.0381,8.97882 16.2611,6.52325 13.5529,5.06042C 14.1576,4.42773 14.8434,3.8847 15.5917,3.45026C
 18.8058,5.33984 20.8867,8.35907 20.8867,11.7611 Z M 17.3569,11.7611C 17.3569,14.5098 15.5005,16.9166 12.
721,18.2465C 12.2751,17.634 11.8948,16.963 11.5914,16.2464C 13.4129,15.2717 14.6097,13.6264 14.6097,11.
7611C 14.6097,9.99512 13.5375,8.42651 11.8774,7.43732C 12.2321,6.7348 12.6631,6.08392 13.1592,5.49811C 15
.6938,6.86359 17.3569,9.1593 17.3569,11.7611 Z M 13.8419,11.7611C 13.8419,13.3503 12.8636,14.7598 11.3562,1
5.6363C 11.106,14.9225 10.9308,14.1686 10.8405,13.3866C 11.2336,12.9211 11.4628,12.3623 11.4628,11.7611C
11.4628,11.2112 11.2711,10.6968 10.9374,10.2567C 11.0779,9.47992 11.3018,8.73541 11.6001,8.03528C
12.9686,8.91791 13.8419,10.2592 13.8419,11.7611 Z ">

     
<Path.Fill>
       
<RadialGradientBrush RadiusX="1.97782" RadiusY="2.89838" Center="0.724708,-                             0.0721312" GradientOrigin="0.724708,-0.0721312">
         
<RadialGradientBrush.RelativeTransform>
           
<TransformGroup>
             
<RotateTransform CenterX="0.724708" CenterY="-0.0721312" Angle="90"/>
            </
TransformGroup>
         
</RadialGradientBrush.RelativeTransform>
         
<GradientStop Color="#FFFFFFFF" Offset="0"/>
          <
GradientStop Color="#00FFFFFF" Offset="1"/>
        </
RadialGradientBrush>
     
</Path.Fill>
   
</Path>
   
<Path x:Name="MuteOnSymbol" Width="21.9323" Height="22.582" Canvas.Left="0" Canvas.Top="0" 
           Stretch
="Fill" Fill="#CDB2B2B2" Data="F1 M 19.0728,0L 21.9323,2.94427L 2.85956,22.582L 0,19.6378L
           19.0728,0 Z "/>
    <
Rectangle Opacity="0.01" Width="22.099" Height="22.915" Fill="#FFFFFFFF" Stroke="#FFFFFFFF" 
          Canvas.Left
="-0.167" Canvas.Top="-0.333"/>
  </
Canvas>

 
<!--Volume Location-->
 
<Rectangle RenderTransformOrigin="0.5,0.5" x:Name="VolumeDuration" Width="152" Height="8" 
      Stroke
="#FF000000" RadiusX="0" RadiusY="0" Opacity="0.5" StrokeThickness="0" Canvas.Left="496.627" 
      Canvas.Top
="533">
   
<Rectangle.Fill>
     
<LinearGradientBrush EndPoint="0.5, 1" StartPoint="0.5, 0">
       
<GradientStop Color="#FF000000" Offset="0.114"/>
        <
GradientStop Color="#FFFFFFFF" Offset="1"/>
        <
GradientStop Color="#FF636363" Offset="0.605"/>
      </
LinearGradientBrush>
   
</Rectangle.Fill>
   
<Rectangle.RenderTransform>
     
<TransformGroup>
       
<ScaleTransform ScaleX="1" ScaleY="1"/>
        <
SkewTransform AngleX="0" AngleY="0"/>
        <
RotateTransform Angle="0"/>
        <
TranslateTransform X="0" Y="0"/>
      </
TransformGroup>
   
</Rectangle.RenderTransform>
 
</Rectangle>

 
<Rectangle x:Name="VolumeProgress" Width="76" Height="8" Fill="#FF19DF6C" Stroke="#FF000000" 
     RadiusX
="0" RadiusY="0" StrokeThickness="0" Canvas.Left="496.75" Canvas.Top="533"/>


xaml 코드가 약간 깁니다.^_^;;

사용자 삽입 이미지

MuteButton_MouseLeftButtonDown 이벤트는 음을 키고 끄는 기능을 합니다.

VolumeDuration_MouseLeftButtonDown, VolumeProgress_MouseLeftButtonDown 두 이벤트는 마우스 클릭한 위치의 좌표값을 계산하여 0.1~1.0까지 볼륨을 조절합니다. pt는 마우스의 X 좌표값이고 이것을 VolumeDuration의 Width값으로 나눕니다. Math 클래스에 있는 Round 함수를 이용하여 소수점 첫째 자리까지 출력합니다.

ASP.NET 프로젝트를 시작 프로젝트로 설정하고 Default.aspx 페이지를 시작페이지로 지정한다음 [F5]키를 눌러 실행결과를 확인합니다.

사용자 삽입 이미지


수고하셨습니다.

[MediaPlayer] 6. Play Progressbar

Downloader Progressbar 부분과 Play Progressbar 부분으로 강좌가 2개로 나누어졌습니다. 지난강좌에서는  Downloader Progressbar에 대해서 알아보았고 이번시간에는 Play Progressbar 강좌를 계속해서 진행하도록 하겠습니다.

xaml 코드는 지난 강좌에서 모두 작성하였습니다. Play Progressbar에 애니메이션을 적용하기 위해서는 StoryBoard가 추가 되어야 합니다.

사용자 삽입 이미지

0.01초마다 1번씩 Interval이 발생합니다.

애니메이션에 대해서 좀더 자세히 공부하시고 싶다면 공도님의 블로그 및 실버라이트카페를 참고하시기 바랍니다.

 - 공도님 블로그 : http://gongdo.tistory.com/

 - 실버라이트 카페 : http://cafe.naver.com/mssilverlight.cafe

사용자 삽입 이미지

Page_Loaded 이벤트에 Play Progressbar 관련 이벤트를 선언합니다.
사용자 삽입 이미지

PlayProgress_MouseLeftButtonDown 이벤트는 PlayProgressbar를 클릭했을때 PlayLocation을 기준으로 왼쪽 동영상의 앞부분으로 재생위치가 이동을 합니다.

DownProgress_MouseLeftButtonDown 이벤트는 Downloader를 클릭했을때 PlayLocation을 기준으로 오른쪽 동영상의 뒷으로 재생위치가 이동을 합니다.

사용자 삽입 이미지

드레그 앤 드롭 기능을 구현하기 위해서는 2개의 변수가 필요합니다. MouseDrogBeginX는 PlayLocation이 가로로 움직이므로 그에 대한 마우스 X좌표 값입니다. MouseDrogDown 변수는 마우스가 드롭 상태인지 아닌지 체크하기 위한 Bool 형태의 값입니다.

사용자 삽입 이미지

이 코드는 PlayLocation을 마우스 드레그 앤 드롭 하여 원하는 위치로 재생위치를 이동하는 이벤트 입니다.

마우스의 드레그 앤 드롭에 관한 자세한 내용은 네이버의 실버라이트카페의 Drag & Drop 의 구현 강좌를 참고하시기 바랍니다.

사용자 삽입 이미지

timerPlayProgress_Completed 이벤트는 애니메이션이 종료하고 발생하는 이벤트입니다. 그리고 동영상 플레이어의 제어버튼 3개(Play, Pause, Stop)에 애니메이션의 시작과 종료, 일시정지에 메소드를 집어넣어야 합니다.
사용자 삽입 이미지


3개의 이벤트에 애니메이션 메소드를 각각 추가하였습니다.

MultiMedia_CurrentStateChanged 이벤트는 동영상의 재생상태를 출력하기 위한 이벤트 입니다. CurrentStateChanged 관련 글입니다.

http://blogs.msdn.com/silverlight_sdk/archive/2007/05/31/using-playlists-in-silverlight.aspx

사용자 삽입 이미지

Page.xaml 파일에 추가된 코드입니다. Visibility="Collapsed" 속성은 화면에서 보이지 않게 기본설정합니다. MultiMedia_CurrentStateChanged 이벤트에서 현재의 재생 상태를 파악하여 동영상이 종료되면 Play Progressbar 및 PlayLocation 같은 현재 진행 상태를 동영상의 처음위치로 초기화 하는데 필요한 이벤트가
MultiMedia_CurrentStateChanged 입니다.

여기까지 5회와 6회에 걸쳐서 동영상 재생관련 강좌를 진행하였습니다. 지금까지의 강좌중에 가장 시간이 오래 걸린듯 합니다.  다음강좌에서는 사운드 조절에 관한 부분을 다루어 보겠습니다.

수고하셨습니다.~~

'닷넷 프로그래밍(~2012)' 카테고리의 다른 글

[MediaPlayer] 10. Chapters[1-2:Expression Encoder]  (0) 2007.09.07
[MediaPlayer] 8. Timer  (0) 2007.09.07
[MediaPlayer] 7. Volume  (0) 2007.09.07
[MediaPlayer] 6. Play Progressbar  (0) 2007.09.06
[MediaPlayer] 5. Downloader Progressbar  (0) 2007.09.06
[Mediaplayer] 4. Player Control  (0) 2007.09.06
[MediaPlayer] 3. Full Screen  (0) 2007.09.06
OCX 등록  (0) 2007.09.06

[MediaPlayer] 5. Downloader Progressbar

동영상 플레이어의 현재 진행상태를 보여줍니다. 동영상 다운로드 Proress Bar  및 백분률 표시, 재생상태를 Progress Bar에 표시, 현재 위치등의 상태를 보여줍니다.

사용자 삽입 이미지
Play State Progressbar :  현재 재생상태

Play Location : 현재 재생 위치

DownLoad State Progressbar : 동영상의 다운로드 상태

DownLoad Percentage : 동영상 다운로드 상태를 백분율로 표시

※ DownLoad State Progressbar 아래쪽에는 진행상태의 기준이 되는 Play Duration(bar형태의 도형)이 있습니다.

<Rectangle RenderTransformOrigin="0.5,0.5" x:Name="PlayDuration" Width="410" Height="8" Stroke="#FF000000" 
RadiusX
="0" RadiusY="0" Canvas.Left="24.249" Canvas.Top="533" Opacity="0.5" StrokeThickness="0">
       
<Rectangle.Fill>
           
<LinearGradientBrush EndPoint="0.5, 1" StartPoint="0.5, 0">
               
<GradientStop Color="#FF000000" Offset="0.114"/>
                <
GradientStop Color="#FFFFFFFF" Offset="1"/>
                <
GradientStop Color="#FF636363" Offset="0.605"/>
            </
LinearGradientBrush>
       
</Rectangle.Fill>
       
<Rectangle.RenderTransform>
           
<TransformGroup>
               
<ScaleTransform ScaleX="1" ScaleY="1"/>
                <
SkewTransform AngleX="0" AngleY="0"/>
                <
RotateTransform Angle="0"/>
                <
TranslateTransform X="0" Y="0"/>
            </
TransformGroup>
       
</Rectangle.RenderTransform>
   
</Rectangle>
       
   
<Rectangle x:Name="DownProgress" Width="1.793" Height="8" Fill="#FFC7C7C7" Stroke="#FF000000" 
         RadiusX
="0" RadiusY="0" Canvas.Left="24.25" Canvas.Top="533" StrokeThickness="0"/>
   
<
Rectangle x:Name="PlayProgress" Width="1.793" Height="8" Fill="#FF19DF6C" Stroke="#FF000000" 
RadiusX
="0" RadiusY="0" Canvas.Left="24.249" Canvas.Top="533" StrokeThickness="0"/>

    <
TextBlock Opacity="0.7" x:Name="txtProgress" Width="22" Height="9" Canvas.Left="438.011" 
Canvas.Top
="529.162" FontSize="11" Foreground="#FFFFFFFF" Text="100%" TextWrapping="Wrap"/>

    <
Rectangle x:Name="PlayLocation" Width="17" Height="8" Stroke="#FF000000" RadiusX="0" RadiusY="0" 
Canvas.Left
="24.25" Canvas.Top="533" StrokeThickness="1">
       
<Rectangle.Fill>
           
<LinearGradientBrush EndPoint="0, 0" StartPoint="1, 1">
               
<GradientStop Color="#FFFFFFFF" Offset="0"/>
                <
GradientStop Color="#FF707070" Offset="1"/>
            </
LinearGradientBrush>
       
</Rectangle.Fill>
   
</Rectangle>


Play State 관련 xaml 코드입니다. Page.xaml 파일에 붙여넣기 하시면 됩니다.

동영상 다운로드 먼저 진행하고 동영상 재생 관련 부분을 다루도록 하겠습니다. 다운로드부분은 이미지다운로드 강좌에서 내용을 다루었던 내용이므로 여기서는 코드 설명만 하겠습니다.

사용자 삽입 이미지

변수 선언부에 Downloader 클래스를 인스턴스 합니다.

사용자 삽입 이미지

Page_Loaded 이벤트에 Downloader 구현 및 2개의 Downloader 이벤트를 선언합니다.

사용자 삽입 이미지

_downloader_DownloadProgressChanged 이벤트는 현재 동영상 다운로드 상태를 Progressbar 및 TextBlock에 백분율 형태로 보여줍니다. DownProgressbar의 진행상태는 _downloader * PlayDuration의 Width 값을 DownProgressbar의 WidthProperty에 지정을 합니다.

_downloader_Completed이벤트는 MediaElement Control에 다운로드 받은 동영상을 화면에 출력할 수 있도록 SetSource() 메소드에 값을 설정합니다.

다음강좌는 다운로드 받은 동영상을 재생하여 진행상태를 보여주는 부분을 다루어 보겠습니다.

수고하셨습니다.

'닷넷 프로그래밍(~2012)' 카테고리의 다른 글

[MediaPlayer] 8. Timer  (0) 2007.09.07
[MediaPlayer] 7. Volume  (0) 2007.09.07
[MediaPlayer] 6. Play Progressbar  (0) 2007.09.06
[MediaPlayer] 5. Downloader Progressbar  (0) 2007.09.06
[Mediaplayer] 4. Player Control  (0) 2007.09.06
[MediaPlayer] 3. Full Screen  (0) 2007.09.06
OCX 등록  (0) 2007.09.06
[MediaPlayer] 2. TitleBar Link, MediaElement  (0) 2007.09.05

[Mediaplayer] 4. Player Control

동영상을 재생하고 일시정지하고 멈추는 등의 일련의 작업등을 수행하는 동영상 제어 버튼 Play, Pause, Stop등의 3개의 버튼을 구현해보겠습니다. 일시정지버튼은 화면에서 보여지는 속성인 Visibility의 속성값이 Collapsed(Refresh 버전으로 릴리즈 되면서 Hidden에서  Collapsed로 변경됨)속성으로 초기화 되어있으며 동영상이 재생되고 있을때 화면에 보여집니다.

사용자 삽입 이미지

동영상 재생관련 버튼 이미지 디자인에 대한 xaml 코드입니다.

<Path Opacity="0.6" Width="2" Height="25" Fill="#FFFCFCFC" Stretch="Fill" Stroke="#FFFCFCFC" 
       Data
="M353,702.22846 L353,760.26293" x:Name="Path_4" Canvas.Left="369" Canvas.Top="552"/>
<
Path Opacity="0.6" x:Name="Path_3" Width="2" Height="25" Fill="#FFFCFCFC" Stretch="Fill" 
      Stroke
="#FFFCFCFC" Canvas.Left="331.666" Canvas.Top="552" Data="M353,702.22846 L353,760.26293"/>
 <
Path Opacity="0.6" Width="2" Height="25" Fill="#FFFCFCFC" Stretch="Fill" Stroke="#FFFCFCFC" 
         Data
="M353,702.22846 L353,760.26293" x:Name="Path_2" Canvas.Left="293.5" Canvas.Top="552"/>
 
 
<!--Play-->
   
<Path Stretch="Fill" Width="14" Height="14" Data="M32,382.18669 L32,391.32257 40,386.65438 z" x:Name="OnPlay" Cursor="Hand" Fill="#FFFFFFFF" Stroke="#FFFCFCFC" Opacity="1" Canvas.Left="307.249" 
Canvas.Top
="557.252" Visibility="Visible" RenderTransformOrigin="0.5,0.5">
       
<Path.RenderTransform>
           
<TransformGroup>
               
<ScaleTransform ScaleX="1" ScaleY="1"/>
                <
SkewTransform AngleX="0.5" AngleY="0.5"/>
                <
RotateTransform Angle="0"/>
                <
TranslateTransform X="0" Y="0"/>
            </
TransformGroup>
       
</Path.RenderTransform>
   
</Path>
   
 
<!--Pause-->
   
<Canvas Visibility="Collapsed" x:Name="OnPause" Width="13.333" Height="14" Canvas.Left="307.654" 
Canvas.Top
="557.252" RenderTransformOrigin="0.5,0.5" Cursor="Hand">

       
<Canvas.RenderTransform>
           
<TransformGroup>
               
<ScaleTransform ScaleX="1" ScaleY="1"/>
                <
SkewTransform AngleX="0.5" AngleY="0.5"/>
                <
RotateTransform Angle="0"/>
                <
TranslateTransform X="0" Y="0"/>
            </
TransformGroup>
       
</Canvas.RenderTransform>

       
<Rectangle Opacity="1" Width="4" Height="14" Fill="#FFFFFFFF" Stroke="#FFFCFCFC" RadiusX="0" RadiusY="0" 
RenderTransformOrigin
="-0.286,0.857" x:Name="rect_1"/>

        <
Rectangle Opacity="1" Width="4" Height="14" Fill="#FFFFFFFF" Stroke="#FFFCFCFC" RadiusX="0" RadiusY="0" 
RenderTransformOrigin
="-0.286,0.857" x:Name="rect_2" Canvas.Left="9.333"/>
   
        <
Rectangle Opacity="0.01" Visibility="Visible" Width="13.246" Height="14.061" Fill="#FFFFFFFF" Stroke="#FFFCFCFC"
 RadiusX="0" RadiusY="0"/>
   
    </
Canvas>

 
<!--Stop-->
 
<Rectangle Opacity="1" Width="14" Height="14" Fill="#FFFFFFFF" Stroke="#FFFCFCFC" RadiusX="0" RadiusY="0" 
Canvas.Left
="344.666" Canvas.Top="557.252" RenderTransformOrigin="0.5,0.5" x:Name="OnStop" Cursor="Hand">
   
<Rectangle.RenderTransform>
     
<TransformGroup>
       
<ScaleTransform ScaleX="1" ScaleY="1"/>
        <
SkewTransform AngleX="0" AngleY="0"/>
        <
RotateTransform Angle="0"/>
        <
TranslateTransform X="0" Y="0"/>
      </
TransformGroup>
   
</Rectangle.RenderTransform>
 
</Rectangle>

버튼간 경계선과 Play, Pause, Stop 버튼에 대한 디자인 xaml 코드입니다. 처음에는 하나하나 까보면 머리에
쥐가 나는 관계로 Page.xaml에 쭈욱~~ 붙여넣기를 하시면 됩니다. Expression Blend가 있으니 가급적 xaml 디자인시에는 무식하게 날코딩을 하는 불쌍사가 없기를 바랍니다... 도구는 인류를 편하게 해주는 산물이 아닙니까.. ㅋㅋ

2번째 강좌에서 동영상 테스트를 하기위해 MediaElement 컨트롤의 속성중에 자동재생 속성인 AutoPlay="True" 값을 주었던 것을 기억하실 겁니다. 이 값을 자동실행을 방지하기 위해 False로 변경하여 주세요...

사용자 삽입 이미지

동영상이 제대로 재생되는지 또는 일시정지하고 멈추는지 설정값이 있어야 합니다. Page.xaml.cs의 클래스 이름 아래에 enum 형식의 Play, Pause, Stop등의 사용자 변수를 만들고 동영상의 재생상태의 초기값을 Stop로 설정하겠습니다.

사용자 삽입 이미지

Play, Pause, Stop의 버튼 이벤트에 동일하게 적용됩니다.


사용자 삽입 이미지

MouseEnter, MouseLeave 이벤트는 버튼의 롤오버효과를 주기 위한 위벤트입니다.


사용자 삽입 이미지

MultiMedia 는 MediaElement의 Name입니다. Play() 메소드를 이용하여 동영상을 재생합니다. PlayState 변수에는 재생상태값을 지정하며 OnPlay, OnPause 버튼은 각각 활성화 또는 비활성화 됩니다.


사용자 삽입 이미지

Pause 이벤트도 Play 이벤트와 비슷한 동작을 수행하며 단지 동영상을 일시정지합니다.

사용자 삽입 이미지

Stop 이벤트는 동영상을 완전 정지하고 재생위치를 처음으로 초기화합니다.

이번강좌는 군더더기 없이 말끔하게 끝낸것 같은데... 뭔가 아쉬움이 남습니다. ㅋ

다음강좌에서는 동영상의 재생관련 진행상태에 대해 진행하겠습니다. 단순히 재생만 된다고 해서 그게 끝이 아니니까 말입니다.~~~

수고하셨습니다...

'닷넷 프로그래밍(~2012)' 카테고리의 다른 글

[MediaPlayer] 7. Volume  (0) 2007.09.07
[MediaPlayer] 6. Play Progressbar  (0) 2007.09.06
[MediaPlayer] 5. Downloader Progressbar  (0) 2007.09.06
[Mediaplayer] 4. Player Control  (0) 2007.09.06
[MediaPlayer] 3. Full Screen  (0) 2007.09.06
OCX 등록  (0) 2007.09.06
[MediaPlayer] 2. TitleBar Link, MediaElement  (0) 2007.09.05
[MediaPlayer] 1. Getting Started  (0) 2007.09.05

[MediaPlayer] 3. Full Screen

대부분 국내 UCC 동영상 제공업체가 자체제작으로 플래시 버전의 플레이어를 지원하지만 모니터의 스크린 전체크기에 맞게 지원되는 곳은 없는 것 같습니다. 대부분 UCC 동영상이 홈비디오 6mm 수준의 영상이 올라오거나 동영상의 해상도 및 품질이 떨어져서 모니터 스크린 크기에 맞는 Full Screen Mode를 지원할 필요가 없다고 봅니다. 그러나 Silverlight나 플래시 모두 HD 720P 수준의 고해상도 HD영상을 지원하는 추세로 넘어감에 따라 앞으로 Full Screen Mode가 지원되지 않을까 생각합니다.

참고로 아래 링크로 참조된 주소는 플래시 기반의 Full Screen Mode를 지원하는 Demo 입니다. 얼마전까지 실버라이트의 장점 아닌 장점이었던 Full Screen 기능이 이제는 플래시쪽에서도 지원이 되니 점점 경쟁은 더 치열해 지리라 봅니다.

http://www.flashcomguru.com/apps/fullscreen_player9/fullscreen.html

http://labs.adobe.com/technologies/flashplayer9/fullscreendemo/

단 고품질 동영상 지원이 국내 UCC 동영상 업체에서도 지원되길 기대하지만 그에 맞추어 개인PC의 컴퓨터 사양이 따라와야 한다는 전제가 깔려있습니다.

서론이 좀 길었던것 같습니다. 이 강좌에서는 완전한 Full Screen이 아닌 테스트 동영상에 맞추어 일반 4:3비율로 기능을 구현해 보겠습니다.

 

<Canvas x:Name="OnFullScreen" Width="35.763" Height="21.375" Canvas.Left="616.448" Canvas.Top="559.749"
 RenderTransformOrigin="0.854,0.573">
   
<Rectangle Width="30.815" Height="15.83" Stroke="#FFFFFFFF" Opacity="0.5" RenderTransformOrigin="0.5,0.5" 
Canvas.Left
="2.417" Canvas.Top="2.878">
     
<Rectangle.Fill>
       
<LinearGradientBrush EndPoint="0.5, 1" StartPoint="0.5, 0">
         
<GradientStop Color="#FF000000" Offset="0.648"/>
          <
GradientStop Color="#FFFFFFFF" Offset="0.019"/>
          <
GradientStop Color="#FFA4A4A4" Offset="0.867"/>
        </
LinearGradientBrush>
     
</Rectangle.Fill>
   
</Rectangle>
   
<TextBlock Opacity="0.5" Width="28.82" Height="16.081" FontSize="12" Foreground="#FFFFFFFF" Text="FULL" 
TextWrapping
="Wrap" Canvas.Left="3.586" Canvas.Top="2.126"/>
  </
Canvas>


Full Screen 기능을 구현하기 위한 일종의 버튼 코드입니다. Page.xaml 파일의 하단에 </Canvas> 바위 위쪽에 붙여넣기를 하시면 됩니다.

사용자 삽입 이미지


부모 Canvas 크기를 변경하면 하위에 포함된 모든 자식 Canvas, 도형, Control등을 동일한 크기에 맞게 변경이 됩니다. 다음 코드는 부모 Canvas의 크기를 변경할 수 있는 xaml 코드입니다.

 

<Canvas x:Name="OnFullScreen" Width="35.763" Height="21.375" Canvas.Left="616.448" Canvas.Top="559.749" 
       RenderTransformOrigin
="0.854,0.573">
   
<Rectangle Width="30.815" Height="15.83" Stroke="#FFFFFFFF" Opacity="0.5" RenderTransformOrigin="0.5,0.5" 
Canvas.Left
="2.417" Canvas.Top="2.878">
     
<Rectangle.Fill>
       
<LinearGradientBrush EndPoint="0.5, 1" StartPoint="0.5, 0">
         
<GradientStop Color="#FF000000" Offset="0.648"/>
          <
GradientStop Color="#FFFFFFFF" Offset="0.019"/>
          <
GradientStop Color="#FFA4A4A4" Offset="0.867"/>
        </
LinearGradientBrush>
     
</Rectangle.Fill>
   
</Rectangle>
   
<TextBlock Opacity="0.5" Width="28.82" Height="16.081" FontSize="12" Foreground="#FFFFFFFF" Text="FULL"
 TextWrapping="Wrap" Canvas.Left="3.586" Canvas.Top="2.126"/>
  </
Canvas>

붉은 색 안쪽에 코드를 붙여넣기 하시면 됩니다. 코드를 간단하게 설명하면 <RanderTransform>은 객체의 크기 및 회전, 위치이동등의 변경된 모양을 화면에 랜더링(Rendering)하기 위한 xaml 태그입니다. <TransformGroup>은 여러가지 Transform관련 효과들을 그룹화 해줍니다. <ScaleTransform>은 객체의 크기를 변경합니다.

사용자 삽입 이미지


지금끼지 Page.xaml 파일에 xaml코드를 적용하였습니다. 다음은 Page.xaml.cs 비하인드 코드에 Full Screen 기능을 구현하기 위한 코드를 작성하겠습니다. 이벤트는 MediaElement와 Full Screen 버튼 2군데에 적용을 하겠습니다. Full Screen 기능을 구현하기 위해서는 화면제어를 할 수 있는 이벤트와 속성을 담고 있는 네임스페이스 using System.Windows.Interop을(를) 선언해야 합니다.

사용자 삽입 이미지


Page_Loaded 이벤트에 5개의 이벤트를 선언합니다. MouseEnter, MouseLeave 이벤트는 롤오버효과를 만들기 위한 이벤트입니다. 버튼에는 공통적으로 롤오버효과가 들어갑니다. 공통코드를 클래스형태로 만들면 중복된 코드를 방지할 수 있습니다. VS2008의 솔루션 탐색기 Silverlight 프로젝트를 선택후 Common 폴더를 하나 생성하고 폴더안에 RandTransForms란 이름으로 클래스를 하나 만듭니다.

FullScreenChange 이벤트는 화면크기(Screen Mode)가 변경될때마다 발생하는 이벤트 입니다.

 

ScaleTransform scale = null;

        #region
 "ScaleTransform"

       
public ScaleTransform scaleTransform(double scaleX, double scaleY)
        {
            scale
= new ScaleTransform();

           
scale.ScaleX = scaleX;
           
scale.ScaleY = scaleY;

            return
scale;
       
}

       
public ScaleTransform scaleTransform
        (
double scaleX, double scaleY, double centerX, double centerY)
        {
            scale
= new ScaleTransform();

           
scale.ScaleX = scaleX;
           
scale.ScaleY = scaleY;
           
scale.CenterX = centerX;
           
scale.CenterY = scaleY;

            return
scale;
       
}

       
#endregion

객체의 크기에 대한 ScaleX, ScaleY값을 받아 변경된 크기를 적용후 값을 리턴하는 함수입니다.

void MultiMedia_MouseLeftButtonDown(object sender, MouseEventArgs e)
{
    BrowserHost.IsFullScreen
= !BrowserHost.IsFullScreen;
   
ResizeControl();
}

void OnFullScreen_MouseLeftButtonDown(object sender, MouseEventArgs e)
{
    BrowserHost.IsFullScreen
= !BrowserHost.IsFullScreen;
   
ResizeControl();
}

void OnFullScreen_MouseEnter(object sender, MouseEventArgs e)
{
    OnFullScreen.RenderTransform
= rnadTransForms.scaleTransform(1.3, 1.3);
}

void OnFullScreen_MouseLeave(object sender, EventArgs e)
{
    OnFullScreen.RenderTransform
= rnadTransForms.scaleTransform(1, 1);
}

void BrowserHost_FullScreenChange(object sender, EventArgs e)
{
    ResizeControl()
;
}

void ResizeControl()
{
   
double scale = Math.Min(BrowserHost.ActualHeight /
                   
this.Height, BrowserHost.ActualWidth / this.Width);

   
scanTransfrom.ScaleX = scale;
   
scanTransfrom.ScaleY = scale;
}

코드의 내용은 어렵지 않게 이해하실 수 있는 코드로 되어 있습니다. 그중에서 BrowserHost.IsFullScreen = !BrowserHost.IsFullScreen는 현재의 화면크기를 체크하여 Full Screen 상태인지 아닌지에 따라 그 반대값을 적용합니다.

ResizeControl 메소드는 객체의 실제 크기로 반환합니다.

코드의 내용은 길지 않았으나 잡설이 많았던 강좌였습니다....

[MediaPlayer] 1. Getting Started

사용자 삽입 이미지
동영상 플레어를 만들기 위한 사전준비입니다... 동영상 플레이어를 만들기 위한 몇가지 준비입니다.

1. 테스트를 위한 동영상 : 다운로드 (동영상은 제공하지 않습니다.)

2. Silverlight 프로젝트를 생성합니다. 프로젝트 이름은 MediaPlayer로 합니다.

사용자 삽입 이미지

사용자 삽입 이미지


3. 호스팅을 위한 ASP.NET 프로젝트를 생성합니다. 프로젝트 이름은 WebProject로 합니다.
   (솔루션 탐색기에서  Add>New Project )


사용자 삽입 이미지


4. Silverlight 프로젝트에 동영상 폴더 및 동영상 파일 첨부

폴더명을 "Media" 로 만들고 다운로드한 동영상을 폴더에 첨부합니다.


사용자 삽입 이미지


5. Silverlight 프로젝트를 ASP.NET 프로젝트에 호스팅하기 위한 연결(Add Silverlight Link)

Downloader 클래스를 이용한 간단한 이미지 다운로드 강좌를 참고하시기 바랍니다. Silverlight 프로젝트를 연결하기 전에 반드시 Silverlight 프로젝트를 컴파일후 연결하시기 바랍니다.

프로젝트 연결이 완료되었다면 솔루션 탐색기에 Silverlight 프로젝트 파일(동영상, silverlight.js, page.xaml, TestPage.html, TestPage.html.js, ClientBind 폴더와 Silverlight 프로젝트 dll)이 포함된 것을 확인할 수 있습니다.

사용자 삽입 이미지


여기까지 동영상 플레이어를 만들기 위한 준비가 완료되었습니다.

Taedi Media Player(소스공개) -Silverlight 1.1

동영상 플레이어 소스를 공개합니다. 소스의 내용은 그리 어렵지 않으며 코드를 직접 치시면서
실행하시면 대부분 이해할 수 있는 내용들입니다.
소스의 복제/수정/배포 모두 허용합니다. 팍~ 팍~

※ 주요기능

- Full Screen
- Volume Control
- Chapters
- Download 진행 표시(100분율)
- Play Progressbar
- 음소거(Mute)


※ 코드의 일부수정으로 인해 소스를 다시 수정배포합니다.