본문 바로가기
C#/WPF

[WPF] WebView2와 동영상

by HJ0216 2024. 4. 13.

최근에 프로젝트를 진행하면서 동영상을 프로그램에서 재생하며 어려웠던 부분을 정리하였습니다.

 

👉 기본 환경

- Language: C#, xaml

- IDE: Visual Basic 2022

- Framework: .NET 8.0


📹동영상..

저에게 주어진 임무는 유튭.. 동영상을 프로그램에서 재생하라..!

 

Web할 때 동영상 재생.. 유튭 태그만 적어주면 끝났던 희미한 기억만 남았는데,

☠️ WPF에서는 패키지도 설치해야하고..

☠️ 컨트롤도 마음처럼 안되고..

☠️ 게시 후에 권한 문제도 생기고..

기억에 확실히 남겨두자는 마음으로.. 기록해봅니다✍️.

 

🚨 1. 동영상 재생에 필요한 태그 찾기

제가 찾아본 태그는 크게 3가지 였습니다.

 * (내장) WebBrowser

 * (Nuget, Google) CefSharp.wpf

 * (Nuget, MS) WebView2

 

Nuget 패키지 설치는 프로그램 용량이 커질 수 있기 때문에 최대한 지양했습니다.

그래서 첫 번째로 WebBrowser를 사용했는데, Script Error 문제로 하루동안 찾아보다가 포기했습니다.

 

그 다음 두 번째로는 CefSharp.wpf를 사용했습니다.

왜냐면 Google에서 WPF youtube 재생을 검색해보니, CefSharp.wpf를 사용하는 방법이 첫 번째로 나왔기 때문입니다.

그러나, 개인적으로 노트북에서 먼저 시도를 했을 때,

Warning	NU1701 Package 'CefSharp.Wpf 122.1.120' was restored 
using '.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, 
.NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, .NETFramework,Version=v4.7.2, 
.NETFramework,Version=v4.8, .NETFramework,Version=v4.8.1' 
instead of the project target framework 'net8.0-windows7.0'. 
This package may not be fully compatible with your project.

위와 같은 오류가 발생해서 포기했습니다.

 

그래서 마지막 종착지, 사이좋게 MS에 MS package를 붙여주기로 결정했습니다.

 

2. Nuget 설치 및 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Window x:Class="WebViewTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WebViewTest"
        xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
        mc:Ignorable="d"
        Title="WebViewTest" Height="450" Width="800"
        Name="WebViewTest"
        >
    <Grid>
        <wv2:WebView2 x:Name="webView"
                      Source="https://www.youtube.com/embed/1Qtr8TznwNI"
                      />
    </Grid>
</Window>

 

Window 태그에 wv2를 추가하고 재생할 주소를 Source에 입력해줍니다.

 

저는 Embed 타입을 사용할 예정이라서 youtube에 embed 경로를 입력해주었습니다.

 * embed경로: www.youtube.com/embed/동영상ID

 

연습할 때는 하드코딩으로 작성했지만, MVVM이면 Source 부분을 바인딩하시면 됩니다.

 

 

🚨 3. 전체화면 컨트롤

유튜브 재생은 되는데, 전체화면을 누르면.. 

 * 윈도우보다 큰 창으로 WebView 크기를 조절할 수 없고,

 * 유튜브가 은밀하게 전체화면을 제공할 수 없다고 하는데,

  고객센터에 들어가보니 수줍게 ' YouTube가 아닌 웹사이트에서 YouTube 동영상을 시청하는 경우 전체 화면 옵션이 제공되지 않을 수 있습니다.'라고 합니다.

 

그래서 대안이 크게 2가지가 나왔는데,

  3.1. 윈도우를 전체 화면으로 같이 만들자

  3.2. 전체화면 클릭 시, 웹브라우저를 실행하자

 

저는 윈도우를 전체 화면으로 만드는 방법을 선택했는데, 같은 메서드를 사용할 예정이라 변환이 쉽습니다.

마음에 드시는 걸로 선택해서 사용하시면 됩니다.

 

제가 생각했을 때의 각각의 장단점은 다음과 같습니다.

 * 윈도우 전체화면 시,

  * 장: 간편

  * 단: 전체 화면을 제공할 수 없다는 안내 문구 발생

        : 창과 웹뷰의 크기를 즉각적으로 연동하기 어려움

 

* 웹브라우저 실행 시,

 * 장: 전체 화면 가능, 유튜브에서 제공하는 기본 옵션들 자유롭게 사용 가능

 * 단: 웹으로 전체화면 실행 시, 처음부터 다시 재생

 (코드를 통해서 넘기는 방법이 있는 것 같지만, 너무 복잡합니다.)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
namespace WebViewTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            InitializeAsync();
        }
 
        /// <summary>
        /// WebView2 컨트롤을 초기화하고, 
        /// 특정 이벤트를 구독하는 과정을 비동기적으로 처리하는 메서드
        /// </summary>
        private async void InitializeAsync()
        {
            await webView.EnsureCoreWebView2Async();
            // CoreWebView2 환경을 초기화
            // 메서드가 성공적으로 반환되면 CoreWebView2 객체가 준비된 상태임을 보장
            webView.CoreWebView2.ContainsFullScreenElementChanged += CoreWebView2_ContainsFullScreenElementChanged;
            // ContainsFullScreenElementChanged
            // 웹 페이지 내에서 전체 화면 요소(예: 비디오의 전체 화면 재생)의 상태가 변경될 때마다 발생
        }
 
        /// <summary>
        /// 웹 페이지 내의 요소가 전체 화면 모드로 전환될 때마다 이 이벤트가 발생
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CoreWebView2_ContainsFullScreenElementChanged(object sender, object e)
        {
            var isFullScreen = webView.CoreWebView2.ContainsFullScreenElement;
            Application.Current.Dispatcher.Invoke(() =>
            {
                if (isFullScreen)
                {
                    // Enter full-screen mode
                    this.WindowStyle = WindowStyle.None;
                    this.WindowState = WindowState.Maximized;
                    this.ResizeMode = ResizeMode.NoResize;
                    webView.Width = this.ActualWidth;
                    webView.Height = this.ActualHeight;
                }
                else
                {
                    // Return to normal mode
                    this.WindowStyle = WindowStyle.SingleBorderWindow;
                    this.WindowState = WindowState.Normal;
                    this.ResizeMode = ResizeMode.CanResize;
                    webView.Width = this.ActualWidth;
                    webView.Height = this.ActualHeight - 35;
                }
            });
        }
 
    }
}

 

ContainsFullScreenElementChanged 이벤트를 통해서 전체화면을 처리하였습니다.

 

WebView2에서 제공하는 기본 컨트롤은 다음 공식문서를 참고하면 됩니다.

 

CoreWebView2 Class (Microsoft.Web.WebView2.Core)

WebView2 enables you to host web content using the latest Microsoft Edge browser and web technology.

learn.microsoft.com

 

만일 전체화면 클릭 시, 웹으로 이동하는 것을 구현하고 싶으시다면 ContainsFullScreenElementChanged에 선언하면 됩니다.

 

🚨 4. 게시 후, 주의 사항

(게시하는 방법 참조)

게시를 할 때 위치 및 게시 후 프로그램 설치 위치 모두 권한 문제에 유의해야 합니다.

 

WebVIew2 폴더 권한 문제

안녕하세요. 윈폼으로 웹뷰2를 사용하여 응용 프로그램을 만들어서 배포하였습니다. (관리자 권한 적용) 해당 프로그램은 Program Files 폴더 하위에 프로젝트명으로 되어 있습니다. 그런데 어떤 PC

forum.dotnetdev.kr

위치를 ProgramFiles로 설정할 경우, 접근 권한의 문제가 생기기 때문에 ProgramData 등 상대적으로 권한이 낮은 다른 곳에 설치를 할 수 있습니다.

 

 

 

😮 오늘의 깨달음: 폴더마다 접근 권한이 다르고, 웹에서 로컬 폴더로의 직접 접근은 보안상 이유로 제한된다.

 

'C# > WPF' 카테고리의 다른 글

[WPF] Static Resource와 Dynamic Resource  (0) 2024.04.20
[WPF] MaterialDesignTheme 적용  (0) 2024.04.13
[WPF] Button 클릭 영역과 Background  (0) 2024.04.06
[WPF] MVVM Scroll 동작 구현  (0) 2024.03.31
[WPF] ListView와 SelectedItem 초기화  (0) 2024.03.31