시스템 미디어 전송 컨트롤의 수동 제어

Windows 10 버전 1607부터 MediaPlayer 클래스를 사용하여 미디어를 재생하는 UWP 앱은 기본적으로 SMTC(시스템 미디어 전송 컨트롤)와 자동으로 통합됩니다. 이것은 대부분의 시나리오에서 권장되는 SMTC 상호작용 방식입니다. MediaPlayer와 SMTC의 기본 통합을 사용자 지정하는 방법에 대한 자세한 내용은 시스템 미디어 전송 컨트롤과 통합을 참조하세요.

SMTC의 수동 제어를 구현해야 하는 시나리오가 몇 가지 있습니다. 여기에는 MediaTimelineController를 사용하여 하나 이상의 미디어 플레이어 재생을 제어하는 경우 등이 포함됩니다. 또는 여러 미디어 플레이어를 사용하는데 해당 앱에 SMTC 인스턴스가 하나만 있어야 하는 경우도 포함됩니다. MediaElement를 사용하여 미디어를 재생하는 경우 SMTC를 수동으로 제어해야 합니다.

전송 컨트롤 설정

MediaPlayer를 사용하여 미디어를 재생하는 경우 MediaPlayer.SystemMediaTransportControls 속성에 액세스하여 SystemMediaTransportControls 클래스의 인스턴스를 가져올 수 있습니다. SMTC를 수동으로 제어할 경우에는 CommandManager.IsEnabled 속성을 false로 설정하여 MediaPlayer에서 제공하는 자동 통합을 사용하지 않도록 설정해야 합니다.

참고 항목

IsEnabled를 false로 설정하여 MediaPlayerMediaPlaybackCommandManager를 사용하지 않도록 설정하면 MediaPlayerMediaPlayerElement에서 제공하는 TransportControls 간 연결이 끊어지므로 기본 제공 전송 컨트롤이 더 이상 플레이어의 재생을 자동으로 제어하지 않습니다. 그 대신 MediaPlayer를 제어할 고유한 컨트롤을 구현해야 합니다.

_mediaPlayer = new MediaPlayer();
_systemMediaTransportControls = _mediaPlayer.SystemMediaTransportControls;
_mediaPlayer.CommandManager.IsEnabled = false;

GetForCurrentView를 호출하여 SystemMediaTransportControls의 인스턴스를 가져올 수도 있습니다. MediaElement를 사용하는 경우 이 메서드를 사용하여 개체를 가져와야 합니다.

_systemMediaTransportControls = SystemMediaTransportControls.GetForCurrentView();

IsPlayEnabled, IsPauseEnabled, IsNextEnabled, IsPreviousEnabled 같은 SystemMediaTransportControls 개체의 해당 "is enabled" 속성을 설정하여 앱에서 사용할 단추를 사용하도록 설정합니다. 사용 가능한 컨트롤 전체 목록은 SystemMediaTransportControls 참조 설명서를 참조하세요.

_systemMediaTransportControls.IsPlayEnabled = true;
_systemMediaTransportControls.IsPauseEnabled = true;

사용자가 단추를 누를 때 알림을 받을 ButtonPressed 이벤트의 처리기를 등록합니다.

_systemMediaTransportControls.ButtonPressed += SystemControls_ButtonPressed;

시스템 미디어 전송 컨트롤 처리 단추 누름

ButtonPressed 이벤트는 활성화된 단추 중 하나를 누를 때 시스템 전송 컨트롤이 발생시킵니다. 이벤트 처리기에 전달된 SystemMediaTransportControlsButtonPressedEventArgsButton 속성은 활성화된 버튼 중에서 누른 단추를 나타내는 SystemMediaTransportControlsButton 열거형의 멤버입니다.

MediaElement 개체 같은 ButtonPressed 이벤트 처리기에서 UI 스레드의 개체를 업데이트하려면 CoreDispatcher를 통해 호출을 마샬링해야 합니다. 이는 ButtonPressed 이벤트 처리기가 UI 스레드에서 호출되지 않으므로 UI를 직접 수정하려고 하면 예외가 throw되기 때문입니다.

async void SystemControls_ButtonPressed(SystemMediaTransportControls sender,
    SystemMediaTransportControlsButtonPressedEventArgs args)
{
    switch (args.Button)
    {
        case SystemMediaTransportControlsButton.Play:
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                mediaElement.Play();
            });
            break;
        case SystemMediaTransportControlsButton.Pause:
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                mediaElement.Pause();
            });
            break;
        default:
            break;
    }
}

시스템 미디어 전송 컨트롤의 현재 미디어 상태 업데이트

시스템이 현재 상태를 반영하도록 컨트롤을 업데이트할 수 있도록 미디어 상태가 변경되면 SystemMediaTransportControls에 알려야 합니다. 이렇게 하려면 미디어 상태가 변경될 때 발생하는 MediaElementCurrentStateChanged 이벤트 내에서 PlaybackStatus 속성을 적절한 MediaPlaybackStatus 값으로 설정합니다.

void MediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
{
    switch (mediaElement.CurrentState)
    {
        case MediaElementState.Playing:
            _systemMediaTransportControls.PlaybackStatus = MediaPlaybackStatus.Playing;
            break;
        case MediaElementState.Paused:
            _systemMediaTransportControls.PlaybackStatus = MediaPlaybackStatus.Paused;
            break;
        case MediaElementState.Stopped:
            _systemMediaTransportControls.PlaybackStatus = MediaPlaybackStatus.Stopped;
            break;
        case MediaElementState.Closed:
            _systemMediaTransportControls.PlaybackStatus = MediaPlaybackStatus.Closed;
            break;
        default:
            break;
    }
}

시스템 미디어 전송 컨트롤의 미디어 정보 및 썸네일 업데이트

SystemMediaTransportControlsDisplayUpdater 클래스를 사용하여 현재 재생 중인 미디어 항목의 노래 제목 또는 앨범 아트 같은 전송 컨트롤에 표시되는 미디어 정보를 업데이트합니다. SystemMediaTransportControls.DisplayUpdater 속성을 사용해 이 클래스의 인스턴스를 가져옵니다. 일반적인 시나리오의 경우 메타데이터를 전달하는 권장 방법은 CopyFromFileAsync를 호출하여 현재 재생 중인 미디어 파일을 전달하는 것입니다. 표시 업데이트 프로그램이 해당 파일에서 메타데이터 및 썸네일 이미지를 자동으로 추출합니다.

Update를 호출하여 시스템 미디어 전송 컨트롤이 새 메타데이터 및 썸네일로 UI를 업데이트하도록 합니다.

async void MediaElement_MediaOpened(object sender, RoutedEventArgs e)
{
    // Get the updater.
    SystemMediaTransportControlsDisplayUpdater updater = _systemMediaTransportControls.DisplayUpdater;

    await updater.CopyFromFileAsync(MediaPlaybackType.Music, currentMediaFile);

    // Update the system media transport controls
    updater.Update();
}

사용자 시나리오에서 필요한 경우 DisplayUpdater 클래스에서 노출하는 MusicProperties, ImageProperties 또는 VideoProperties 개체의 값을 설정하여 시스템 미디어 전송 컨트롤이 표시하는 메타데이터를 수동으로 업데이트할 수 있습니다.


// Get the updater.
SystemMediaTransportControlsDisplayUpdater updater = _systemMediaTransportControls.DisplayUpdater;

// Music metadata.
updater.Type = MediaPlaybackType.Music;
updater.MusicProperties.Artist = "artist";
updater.MusicProperties.AlbumArtist = "album artist";
updater.MusicProperties.Title = "song title";

// Set the album art thumbnail.
// RandomAccessStreamReference is defined in Windows.Storage.Streams
updater.Thumbnail =
   RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Music/music1_AlbumArt.jpg"));

// Update the system media transport controls.
updater.Update();

참고 항목

앱은 시스템 미디어 전송 컨트롤에서 표시할 다른 미디어 메타데이터를 제공하지 않더라도 SystemMediaTransportControlsDisplayUpdater.Type 속성에 대한 값을 설정해야 합니다. 이 값을 사용하면 재생하는 동안 화면 보호기를 활성화하는 것을 방지하는 등 시스템에서 미디어 콘텐츠를 올바르게 처리할 수 있습니다.

시스템 미디어 전송 컨트롤의 타임라인 속성 업데이트

시스템 전송 컨트롤은 현재 재생 위치, 시작 시간 및 미디어 항목의 종료 시간을 포함해 현재 재생 중인 미디어 항목의 타임라인에 관한 정보를 표시합니다. 시스템 전송 컨트롤 타임라인 속성을 업데이트하려면 새 SystemMediaTransportControlsTimelineProperties 개체를 만듭니다. 재생 중인 미디어 항목의 현재 상태가 반영되도록 개체의 속성을 설정합니다. SystemMediaTransportControls.UpdateTimelineProperties를 호출하여 컨트롤이 타임라인을 업데이트하게 합니다.

// Create our timeline properties object 
var timelineProperties = new SystemMediaTransportControlsTimelineProperties();

// Fill in the data, using the media elements properties 
timelineProperties.StartTime = TimeSpan.FromSeconds(0);
timelineProperties.MinSeekTime = TimeSpan.FromSeconds(0);
timelineProperties.Position = mediaElement.Position;
timelineProperties.MaxSeekTime = mediaElement.NaturalDuration.TimeSpan;
timelineProperties.EndTime = mediaElement.NaturalDuration.TimeSpan;

// Update the System Media transport Controls 
_systemMediaTransportControls.UpdateTimelineProperties(timelineProperties);
  • 시스템 컨트롤이 재생 항목의 타임라인을 표시하려면 StartTime, EndTimePosition 값을 제공해야 합니다.

  • MinSeekTimeMaxSeekTime을 사용하면 타임라인 내에서 사용자가 찾을 수 있는 범위를 지정할 수 있습니다. 이에 대한 일반적인 시나리오는 콘텐츠 공급자가 그 미디어에 광고 중단을 포함할 수 있게 하는 것입니다.

    PositionChangeRequest가 발생하도록 MinSeekTimeMaxSeekTime을 설정해야 합니다.

  • 재생하는 동안 약 5초마다 이러한 속성을 업데이트하고 재생 상태가 변경될 때마다(예: 일시 중지 또는 새 위치 찾기) 다시 업데이트하여 시스템 컨트롤을 미디어 재생과 동기화된 상태로 유지하는 것이 좋습니다.

플레이어 속성 변경에 응답

재생 중인 미디어 항목의 상태가 아니라 미디어 플레이어의 현재 상태에 관한 시스템 전송 컨트롤 속성 집합이 있습니다. 이러한 속성 각각은 사용자가 연결된 컨트롤을 조정할 때 발생하는 이벤트에 매칭됩니다. 이러한 속성과 이벤트에는 다음이 포함됩니다.

속성 이벤트
AutoRepeatMode AutoRepeatModeChangeRequested
PlaybackRate PlaybackRateChangeRequested
ShuffleEnabled ShuffleEnabledChangeRequested

  이러한 컨트롤 중 하나와의 사용자 상호 작용을 처리하려면 연결된 이벤트용 처리기를 먼저 등록합니다.

_systemMediaTransportControls.PlaybackRateChangeRequested += SystemControls_PlaybackRateChangeRequested;

이벤트 처리기에서, 요청된 값이 유효한 예상 범위에 드는지 먼저 확인합니다. 그런 경우 MediaElement에서 해당 속성을 설정한 다음 SystemMediaTransportControls 개체에서 해당 속성을 설정합니다.

void SystemControls_PlaybackRateChangeRequested(SystemMediaTransportControls sender, PlaybackRateChangeRequestedEventArgs args)
{
    // Check the requested value to make sure it is within a valid and expected range
    if (args.RequestedPlaybackRate >= 0 && args.RequestedPlaybackRate <= 2)
    {
        // Set the requested value on the MediaElement
        mediaElement.PlaybackRate = args.RequestedPlaybackRate;

        // Update the system media controls to reflect the new value
        _systemMediaTransportControls.PlaybackRate = mediaElement.PlaybackRate;
    }
}
  • 이러한 플레이어 속성 이벤트 중 하나가 발생하려면 해당 속성의 초기 값을 설정해야 합니다. 예를 들어, PlaybackRateChangeRequestedPlaybackRate 속성에 대한 값을 한 번 이상 설정한 후에야 발생합니다.

백그라운드 오디오에 시스템 미디어 전송 컨트롤 사용

MediaPlayer에서 제공하는 자동 SMTC 통합을 사용하지 않는 경우에 백그라운드 오디오를 사용하도록 설정하려면 SMTC와 수동으로 통합해야 합니다. 최소한 IsPlayEnabledIsPauseEnabled를 true로 설정하여 재생 및 일시 중지 단추를 사용하도록 설정해야 합니다. 앱에서 ButtonPressed 이벤트도 처리해야 합니다. 앱에서 이러한 요구 사항을 충족하지 않으면 앱이 백그라운드로 이동할 때 오디오 재생이 중지됩니다.

백그라운드 오디오에 새 원프로세스 모델을 사용하는 앱은 GetForCurrentView를 호출하여 SystemMediaTransportControls의 인스턴스를 가져와야 합니다. 백그라운드 오디오에 레거시 2 프로세스 모델을 사용하는 앱은 BackgroundMediaPlayer.Current.SystemMediaTransportControls를 사용하여 백그라운드 프로세스에서 SMTC에 액세스해야 합니다.

백그라운드에서 오디오 재생에 대한 자세한 내용은 백그라운드에서 미디어 재생을 참조하세요.