Compartilhar via


Controle manual dos controles de transporte de mídia do sistema

A partir do Windows 10, versão 1607, os aplicativos UWP que usam a classe MediaPlayer para reproduzir mídia são integrados automaticamente aos SMTC (Controles de Transporte de Mídia do Sistema) por padrão. Essa é a maneira recomendada de interagir com o SMTC para a maioria dos cenários. Para obter mais informações sobre como personalizar a integração padrão do SMTC com o MediaPlayer, consulte Integrar com os controles de transporte de mídia do sistema.

Há alguns cenários em que pode ser necessário implementar o controle manual do SMTC. Isso inclui se você estiver usando um MediaTimelineController para controlar a reprodução de um ou mais players de mídia. Ou se você estiver usando vários players de mídia e quiser ter apenas uma instância do SMTC para seu aplicativo. Você deve controlar manualmente o SMTC se estiver usando MediaElement para reproduzir mídia.

Configurar controles de transporte

Se você estiver usando o MediaPlayer para reproduzir mídia, poderá obter uma instância da classe SystemMediaTransportControls acessando a propriedade MediaPlayer.SystemMediaTransportControls . Se você for controlar manualmente o SMTC, deverá desabilitar a integração automática fornecida pelo MediaPlayer definindo a propriedade CommandManager.IsEnabled como false.

Observação

Se você desabilitar o MediaPlaybackCommandManager do MediaPlayer definindo IsEnabled como false, ele interromperá o vínculo entre o MediaPlayer e os TransportControls fornecidos pelo MediaPlayerElement, de modo que os controles de transporte internos não controlarão mais automaticamente a reprodução do player. Em vez disso, você deve implementar seus próprios controles para controlar o MediaPlayer.

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

Você também pode obter uma instância do SystemMediaTransportControls chamando GetForCurrentView. Você deve obter o objeto com esse método se estiver usando MediaElement para reproduzir mídia.

_systemMediaTransportControls = SystemMediaTransportControls.GetForCurrentView();

Habilite os botões que seu aplicativo usará definindo a propriedade "está habilitada" correspondente do objeto SystemMediaTransportControls, como IsPlayEnabled, IsPauseEnabled, IsNextEnabled e IsPreviousEnabled. Consulte a documentação de referência SystemMediaTransportControls para obter uma lista completa dos controles disponíveis.

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

Registre um manipulador para o evento ButtonPressed para receber notificações quando o usuário pressionar um botão.

_systemMediaTransportControls.ButtonPressed += SystemControls_ButtonPressed;

Manipule os controles de transporte de mídia do sistema pressionados por botões

O evento ButtonPressed é gerado pelos controles de transporte do sistema quando um dos botões habilitados é pressionado. A propriedade Button do SystemMediaTransportControlsButtonPressedEventArgs passada para o manipulador de eventos é um membro da enumeração SystemMediaTransportControlsButton que indica qual dos botões habilitados foi pressionado.

Para atualizar objetos no thread da interface do usuário do manipulador de eventos ButtonPressed, como um objeto MediaElement, você deve empacotar as chamadas por meio do CoreDispatcher. Isso ocorre porque o manipulador de eventos ButtonPressed não é chamado do thread da interface do usuário e, portanto, uma exceção será gerada se você tentar modificar a interface do usuário diretamente.

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;
    }
}

Atualize os controles de transporte de mídia do sistema com o status de mídia atual

Você deve notificar o SystemMediaTransportControls quando o estado da mídia for alterado para que o sistema possa atualizar os controles para refletir o estado atual. Para fazer isso, defina a propriedade PlaybackStatus como o valor MediaPlaybackStatus apropriado de dentro do evento CurrentStateChanged do MediaElement, que é gerado quando o estado da mídia é alterado.

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;
    }
}

Atualizar os controles de transporte de mídia do sistema com informações de mídia e miniaturas

Use a classe SystemMediaTransportControlsDisplayUpdater para atualizar as informações de mídia exibidas pelos controles de transporte, como o título da música ou a arte do álbum para o item de mídia em execução no momento. Obtenha uma instância dessa classe com a propriedade SystemMediaTransportControls.DisplayUpdater. Para cenários típicos, a maneira recomendada de passar os metadados é chamar CopyFromFileAsync, passando o arquivo de mídia em execução no momento. O atualizador de exibição extrairá automaticamente os metadados e a imagem em miniatura do arquivo.

Chame a atualização para fazer com que os controles de transporte de mídia do sistema atualizem sua interface do usuário com os novos metadados e miniatura.

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();
}

Se o cenário exigir, você poderá atualizar os metadados exibidos pelos controles de transporte de mídia do sistema manualmente definindo os valores dos objetos MusicProperties, ImageProperties ou VideoProperties expostos pela classe DisplayUpdater.


// 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();

Observação

Os aplicativos devem definir um valor para a propriedade SystemMediaTransportControlsDisplayUpdater.Type , mesmo que não estejam fornecendo outros metadados de mídia a serem exibidos pelos controles de transporte de mídia do sistema. Esse valor ajuda o sistema a lidar com o conteúdo de mídia corretamente, incluindo impedir que o protetor de tela seja ativado durante a reprodução.

Atualizar as propriedades da linha do tempo dos controles de transporte de mídia do sistema

Os controles de transporte do sistema exibem informações sobre a linha do tempo do item de mídia em reprodução no momento, incluindo a posição de reprodução atual, a hora de início e a hora de término do item de mídia. Para atualizar as propriedades da linha do tempo dos controles de transporte do sistema, crie um novo objeto SystemMediaTransportControlsTimelineProperties. Defina as propriedades do objeto para refletir o estado atual do item de mídia em reprodução. Chame SystemMediaTransportControls.UpdateTimelineProperties para fazer com que os controles atualizem a linha do tempo.

// 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);
  • Você deve fornecer um valor para StartTime, EndTime e Position para que os controles do sistema exibam uma linha do tempo para o item em jogo.

  • MinSeekTime e MaxSeekTime permitem que você especifique o intervalo dentro da linha do tempo que o usuário pode buscar. Um cenário típico para isso é permitir que os provedores de conteúdo incluam intervalos de anúncios em suas mídias.

    Você deve definir MinSeekTime e MaxSeekTime para que o PositionChangeRequest seja gerado.

  • É recomendável manter os controles do sistema sincronizados com a reprodução de mídia atualizando essas propriedades aproximadamente a cada 5 segundos durante a reprodução e novamente sempre que o estado da reprodução for alterado, como pausar ou buscar uma nova posição.

Responder a alterações de propriedade do jogador

Há um conjunto de propriedades de controles de transporte do sistema que se relacionam ao estado atual do próprio reprodutor de mídia, em vez do estado do item de mídia em reprodução. Cada uma dessas propriedades é correspondida a um evento que é gerado quando o usuário ajusta o controle associado. Essas propriedades e eventos incluem:

Propriedade Evento
Modo de repetição automática AutoRepeatModeChangeRequested
PlaybackRate PlaybackRateChangeRequested
Habilitado para embaralhar ShuffleEnabledChangeRequested

  Para lidar com a interação do usuário com um desses controles, primeiro registre um manipulador para o evento associado.

_systemMediaTransportControls.PlaybackRateChangeRequested += SystemControls_PlaybackRateChangeRequested;

No manipulador do evento, primeiro verifique se o valor solicitado está dentro de um intervalo válido e esperado. Se estiver, defina a propriedade correspondente em MediaElement e, em seguida, defina a propriedade correspondente no objeto 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;
    }
}
  • Para que um desses eventos de propriedade do jogador seja gerado, você deve definir um valor inicial para a propriedade. Por exemplo, PlaybackRateChangeRequested não será gerado até que você tenha definido um valor para a propriedade PlaybackRate pelo menos uma vez.

Usar os controles de transporte de mídia do sistema para áudio em segundo plano

Se você não estiver usando a integração automática do SMTC fornecida pelo MediaPlayer , deverá integrar-se manualmente ao SMTC para ativar o áudio em segundo plano. No mínimo, seu aplicativo deve habilitar os botões de reprodução e pausa definindo IsPlayEnabled e IsPauseEnabled como true. Seu aplicativo também deve lidar com o evento ButtonPressed . Se o aplicativo não atender a esses requisitos, a reprodução de áudio será interrompida quando o aplicativo for movido para o segundo plano.

Os aplicativos que usam o novo modelo de um processo para áudio em segundo plano devem obter uma instância do SystemMediaTransportControls chamando GetForCurrentView. Os aplicativos que usam o modelo herdado de dois processos para áudio em segundo plano devem usar BackgroundMediaPlayer.Current.SystemMediaTransportControls para obter acesso ao SMTC de seu processo em segundo plano.

Para obter mais informações sobre como reproduzir áudio em segundo plano, consulte Reproduzir mídia em segundo plano.