Schnellstart: Streamen einer Diashow mit "Wiedergeben auf"
Language: HTML | XAML

Schnellstart: Streamen von Bildschirmpräsentationen mit „Wiedergeben auf“ (XAML)

[ Dieser Artikel richtet sich an Windows 8.x- und Windows Phone 8.x-Entwickler, die Windows-Runtime-Apps schreiben. Wenn Sie für Windows 10 entwickeln, finden Sie weitere Informationen unter neueste Dokumentation]

Verwenden Sie "Wiedergeben auf", damit Benutzer auf einfache Weise Audiodaten, Videodaten oder Bilder von ihrem Computer auf Geräte in ihrem Heimnetzwerk streamen können. In diesem Thema wird erläutert, wie "Wiedergeben auf" in einer Windows Store-App verwendet werden kann, um Bilder als Bildschirmpräsentation auf ein Zielgerät zu streamen.

Ziel: Streamen Sie mit "Wiedergeben auf" Bilder als Bildschirmpräsentation auf ein Zielgerät.

Voraussetzungen

Microsoft Visual Studio

Anweisungen

1. Erstellen eines neuen Projekts und Aktivieren des Zugriffs auf Bilder

  1. Öffnen Sie Visual Studio, und wählen Sie im Menü Datei die Option Neues Projekt aus. Wählen Sie im Abschnitt Visual C# oder Visual Basic die Option Anwendung aus. Geben Sie für die App den Namen PlayToSlideShow ein, und klicken Sie auf OK.
  2. Öffnen Sie die Datei Package.appxmanifest, und klicken Sie auf die Registerkarte Funktionen. Wählen Sie die Funktion Bildbibliothek aus, damit Ihre App auf den Bilderordner auf einem Computer zugreifen kann. Schließen und speichern Sie die Manifestdatei.

2. Hinzufügen einer HTML-Benutzeroberfläche

Öffnen Sie die Datei MainPage.xaml, und fügen Sie dem standardmäßigen <Grid>-Element Folgendes hinzu. Die UI enthält ein StackPanel, das dazu verwendet wird, die Bilder und einen TextBlock einzublenden, der zur Anzeige von Statusmeldungen zum Einsatz kommt. Darüber hinaus enthält sie einen TextBlock, der dem Benutzer erklärt, wie er mithilfe von "Wiedergeben auf" streamt, und eine Button, um ihm das Trennen beim Streamen zu ermöglichen. Diese beiden Elemente sind ausgeblendet und erscheinen abhängig davon, ob die Bildschirmpräsentation gerade gestreamt wird oder nicht.


<StackPanel Orientation="Vertical">
    <StackPanel x:Name="SlideShowPanel"  Height="600" Orientation="Horizontal" />
    <TextBlock x:Name="MessageBlock" FontSize="14" >Slideshow disconnected</TextBlock>
    <Button x:Name="DisconnectButton" Width="600" Height="60" Visibility="Collapsed" FontSize="14">
        <StackPanel Orientation="Horizontal">
            <TextBlock>Connected to</TextBlock>
            <Image x:Name="IconImage" Width="30" />
            <TextBlock x:Name="DeviceBlock" />
        </StackPanel>
    </Button>
    <TextBlock x:Name="InstructionsBlock" FontSize="14" >Swipe from the right edge of the screen, select "Devices", 
        and select a device to stream the slide show to.</TextBlock>
</StackPanel>


3. Hinzufügen von Initialisierungscode

Der Code in diesem Schritt initialisiert den PlayToManager und startet anschließend die Bildschirmpräsentation.

Öffnen Sie die Datei MainPage.xaml.cs oder MainPage.xaml.vb, und fügen Sie anstelle der OnNavigatedTo-Standardmethode den folgenden Code hinzu.


private Windows.Media.PlayTo.PlayToManager ptm;
private Windows.UI.Xaml.DispatcherTimer timer;
private Windows.UI.Core.CoreDispatcher dispatcher = Window.Current.CoreWindow.Dispatcher;

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    ptm = Windows.Media.PlayTo.PlayToManager.GetForCurrentView();
    ptm.SourceRequested += SourceRequested;
    ptm.SourceSelected += SourceSelected;

    StartSlideShow();
}


4. Hinzufügen von Code zum Abrufen und Anzeigen der Bilder als Bildschirmpräsentation

In diesem Beispiel werden Bilder, die sich im Stammverzeichnis des Bilderordners befinden, als Bildschirmpräsentation angezeigt. Dabei wird zunächst eine Liste der Bilder aus dem Bilderordner abgerufen, und anschließend werden <image>-Objekte zum Durchlaufen der Liste erstellt.

Beim Streamen der Bilder mithilfe von "Wiedergeben auf" nutzt der Code für diese Bildschirmpräsentations-App die Möglichkeit, das nächste Medienelement mithilfe von "Wiedergeben auf" zu puffern. Dies ist optional und eignet sich für Szenarien, in denen zusätzliche Zeit zum Abrufen des nächsten zu streamenden Mediums in Anspruch genommen wird. Durch Puffern des Mediums können Sie es direkt nach Beenden des aktuellen Mediums streamen und damit Verzögerungen zwischen den Medienelementen vermeiden.

Zum Puffern des nächsten Medienelements legen wir für die Quelle "Wiedergeben auf" des nächsten Elements die Next-Eigenschaft des aktuellen Elements fest. Wenn das aktuelle Element abgeschlossen ist, rufen wir die PlayNext-Methode des aktuellen Elements auf, um die nächste Medienquelle auf das Zielgerät zu streamen.

Falls die Bildschirmpräsentation nur lokal erfolgt, greift der Code auf ein Zeitlimit zurück, um zum nächsten Bild in der Liste zu wechseln. Wenn die Bildschirmpräsentation auf einen "Wiedergeben auf"-Empfänger gestreamt wird, greift der Code ebenfalls auf ein Zeitlimit zurück, um zum nächsten Bild zu wechseln, reagiert jedoch auch, wenn der "Wiedergeben auf"-Empfänger die Bildschirmpräsentation pausiert, zum nächsten Bild wechselt, bevor das Zeitlimit abgelaufen ist, oder getrennt wird. Dies wird mithilfe des Statechanged-Ereignisses der "Wiedergeben auf"-Quelle erreicht, das von der PlayToSource-Eigenschaft eines Bildobjekts referenziert wird. Beim Statechanged-Ereignis überprüft der Code die CurrentState- und PreviousState-Eigenschaften der Argumente, die an das Ereignis weitergegeben werden. Über die verschiedenen Zustände, zusammen mit der Zahl, die den Index des Bilds identifiziert, das das Statechanged-Ereignis ausgelöst hat, kann festgestellt werden, wie reagiert werden soll, wie in der folgenden Tabelle zu sehen.

CurrentStateAuszuführende Aktion
disconnected

Wenn der Index des Bilds, das das Ereignis ausgelöst hat, derselbe Index ist wie derjenige des Bilds, das gerade angezeigt wird, wurde die "Wiedergeben auf"-Quelle getrennt, während ein Bild gerade angezeigt wurde. Das bedeutet, dass der "Wiedergeben auf"-Empfänger nicht mehr verbunden ist und wir die Bildschirmpräsentation lokal mithilfe des aktuellen Bildindex starten. Ansonsten gibt der Zustand Disconnected einfach an, dass die Bildschirmpräsentation fertig mit der Einblendung des Bilds ist, das das Ereignis ausgelöst hat, und wir das Bildobjekt aufräumen können, das nicht mehr benötigt wird.

connected

Wenn der vorherige Zustand Disconnected ist, wurde das Bild, das das Ereignis ausgelöst hat, eben mit dem "Wiedergeben auf"-Empfänger verbunden. An diesem Punkt erhalten wir das nächste Bild, sodass es geladen wird, während das aktuelle Bild angezeigt wird.

Wenn der vorherige Zustand Rendering ist, hat der Benutzer die Bildschirmpräsentation auf dem "Wiedergeben auf"-Empfänger pausiert, und wir setzen das aktuelle Zeitlimit außer Kraft, bevor der Benutzer die Präsentation neu startet.

renderingWenn der vorherige Zustand Connected ist, hat der "Wiedergeben auf"-Empfänger die Bildschirmpräsentation fortgesetzt, und wir können die Präsentation wieder starten.

 

Fügen Sie in der Datei MainPage.xaml.cs oder MainPage.xaml.cs den folgenden Code hinter dem Code aus dem vorherigen Schritt ein.


IReadOnlyList<Windows.Storage.StorageFile> imageList;   // contains the list of images to show
bool streaming = false;      // true when streaming using Play To; otherwise false
int timeLapse = 5;           // time between images (5 seconds)
int imageSize = 600;         // size of current displayed image
int thumbnailSize = 200;     // size of "thumbnail" of next image
int currentImage = 0;        // index of the current image from imageList

// Get the list of images from the Pictures folder and start the slide show.
async private void StartSlideShow()
{
    var resultsLibrary = await
        Windows.Storage.KnownFolders.PicturesLibrary.GetFilesAsync();
    imageList = resultsLibrary;
    if (imageList.Count > 0)
    {
        var image = QueueImage(0, true);
    }
    else
    {
        MessageBlock.Text = "There are no images in the Pictures library.";
    }
}

// PlayNextImage
// Called when a new image is displayed due to a timeout.
// Removes the current image object and queues a new next image.
// Sets the next image index as the new current image, and increases the size 
// of the new current image. Then sets the timeout to display the next image.

private async void PlayNextImage(int num)
{
    // Stop the timer to avoid repeating.
    if (timer != null) { timer.Stop(); }

    await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
        async () =>
        {
            SlideShowPanel.Children.Remove((UIElement)(SlideShowPanel.FindName("image" + num)));
            var i = await QueueImage(num + 2, false);

            currentImage = num + 1;
            ((Image)SlideShowPanel.FindName("image" + currentImage)).Width = imageSize;
        });

    timer = new Windows.UI.Xaml.DispatcherTimer();
    timer.Interval = new TimeSpan(0, 0, timeLapse);
    timer.Tick += delegate(object sender, object e)
    {
        PlayNextImage(num + 1);
    };
    timer.Start();
}

// QueueImage
// Called to create an image object for the displayed images.

private async System.Threading.Tasks.Task<Image> QueueImage(int num, bool isFirstImage)
{
    // Create the image element for the specified image index and add to the
    // slide show div.

    Image image = new Image();
    image.Width = isFirstImage ? imageSize : thumbnailSize;
    image.Name = "image" + num;
    image.VerticalAlignment = VerticalAlignment.Bottom;
    var fileContents = await imageList[num % imageList.Count].OpenReadAsync();
    var imageBitmap = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
    imageBitmap.SetSource(fileContents);
    image.Source = imageBitmap;

    await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
        () =>
        {
            SlideShowPanel.Children.Add(image);
        });

    // If this is the first image of the slide show, queue the next image. Do
    // not queue if streaming as images are already queued before
    // streaming using Play To.

    if (isFirstImage && !streaming)
    {
        var i = await QueueImage(num + 1, false);

        timer = new Windows.UI.Xaml.DispatcherTimer();
        timer.Interval = new TimeSpan(0, 0, timeLapse);
        timer.Tick += delegate(object sender, object e)
        {
            PlayNextImage(num);
        };
        timer.Start();
    }

    // Use the transferred event of the Play To connection for the current image object
    // to "move" to the next image in the slide show. The transferred event occurs
    // when the PlayToSource.playNext() method is called, or when the Play To
    // Receiver selects the next image.

    image.PlayToSource.Connection.Transferred += 
        async delegate(Windows.Media.PlayTo.PlayToConnection sender, 
                 Windows.Media.PlayTo.PlayToConnectionTransferredEventArgs e)
           { 
               currentImage = num + 1;

               await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                   () =>
                   {
                       ((Image)SlideShowPanel.FindName("image" + currentImage)).Width = imageSize;
                   });
           };


// Use the statechanged event to determine which action to take or to respond
// if the Play To Receiver is disconnected.
image.PlayToSource.Connection.StateChanged += 
    async delegate(Windows.Media.PlayTo.PlayToConnection sender,
             Windows.Media.PlayTo.PlayToConnectionStateChangedEventArgs e)
    {
        switch (e.CurrentState) {
            case Windows.Media.PlayTo.PlayToConnectionState.Disconnected:

                // If the state is disconnected and the current image index equals the 
                // num value passed to queueImage, then the image element is not connected 
                // to the Play To Receiver any more. Restart the slide show.
                // Otherwise, the current image has been discarded and the slide show
                // has moved to the next image. Clear the current image object and
                // remove it from the slide show div.

                if (currentImage == num)
                {
                    await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, 
                        async () =>
                        {
                            MessageBlock.Text = "Slideshow disconnected";

                            // Cancel any existing timeout
                            if (timer != null) { timer.Stop(); }

                            // Clear all image objects from the slide show div
                            SlideShowPanel.Children.Clear();

                            // Reset the slide show objects and values to their beginning state
                            streaming = false;
                            DisconnectButton.Visibility = Visibility.Collapsed;
                            InstructionsBlock.Visibility = Visibility.Visible;
                            DisconnectButton.Click -= DisconnectButtonClick;

                            // Restart the slide show from the current image index
                            var i = await QueueImage(currentImage, true);
                        });
                } 
                else 
                { 
                    await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                            () =>
                            {
                                image.PlayToSource.Next = null;

                                if (streaming)
                                {
                                    SlideShowPanel.Children.Remove(image);
                                }   
                            });
                }

                break;
            
            case Windows.Media.PlayTo.PlayToConnectionState.Connected:

                // If the state is connected and the previous state is disconnected, 
                // then the image element is newly connected. Queue up the next image so 
                // that it is loaded while the current image is being displayed.
                // If the previous state is rendering, then the user has paused the slideshow 
                // on the Play To Receiver. Clear the current timeout until the user restarts
                // the slide show.
                await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                    async () =>
                    {
                        if (e.PreviousState ==  Windows.Media.PlayTo.PlayToConnectionState.Disconnected)
                        {
                            var imageNext = await QueueImage(num + 1, false);
                            image.PlayToSource.Next = imageNext.PlayToSource;
                        } 
                        else if (e.PreviousState == Windows.Media.PlayTo.PlayToConnectionState.Rendering) 
                        {
                            if (timer != null) { timer.Stop(); }
                        }

                        if (currentImage == num) 
                        {
                            MessageBlock.Text = "Slideshow connected";
                        }
                    });
                break;

            case  Windows.Media.PlayTo.PlayToConnectionState.Rendering:

                // If the state is rendering and the previous state is
                // connected, then the Play To Receiver has restarted
                // the slide show.
                    await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                        () =>
                        {
                            if (e.PreviousState == Windows.Media.PlayTo.PlayToConnectionState.Connected)
                            {
                                // Clear any existing timeout.
                                if (timer != null) { timer.Stop(); }

                                // Restart the slide show.
                                timer = new Windows.UI.Xaml.DispatcherTimer();
                                timer.Interval = new TimeSpan(0, 0, timeLapse);
                                timer.Tick += delegate(object s, object args)
                                {
                                    image.PlayToSource.PlayNext();
                                };
                                timer.Start();
                            }

                            if (currentImage == num)
                            {
                                MessageBlock.Text = "Slideshow rendering";
                            }
                       }); 
                break;
            }
        };

    return image;
}


5. Hinzufügen von Code für "Wiedergeben auf"

Der Code in diesem Schritt implementiert den Vertrag für "Wiedergeben auf". Er ruft einen Verweis auf den PlayToManager für die aktuelle App ab und weist den Ereignishandler für das SourceRequested-Ereignis und das SourceSelected-Ereignis zu.

Da die Bildobjekte für jedes einzelne Bild der Bildschirmpräsentation erstellt und eliminiert werden, verwenden wir ein temporäres Bildobjekt, das beim SourceRequested-Ereignis nie eliminiert wird. Das geschieht deshalb, weil wir nicht wissen, ob das Zeitlimit abläuft, bevor der Benutzer einen "Wiedergeben auf"-Empfänger auswählt. Sollte das passieren, wird das aktuelle Bild eliminiert, und wir würden einen Nullverweis an "Wiedergeben auf" weiterleiten. Stattdessen leiten wir einen Verweis zu einem Bildobjekt an "Wiedergeben auf" weiter, das nie eliminiert wird, und aktualisieren die Bildquelle auf das aktuell eingeblendete Bild, sobald der Benutzer einen "Wiedergeben auf"-Empfänger auswählt. Wir wissen, dass das passiert ist, wenn sich der Zustand des Bilds zu Connected ändert.

Fügen Sie in der Datei MainPage.xaml.cs oder MainPage.xaml.vb den folgenden Code hinter dem Code aus dem vorherigen Schritt ein.


// Set up the Play To contract.

// Used to pass an image to Play To that will not be removed/destroyed
// by the slide show logic. For example, if the user opens the Devices
// charm and the sourcerequested event fires, but the image display timeout
// completes before the user selects a target device, then the image that
// was being displayed is removed and destroyed. intialImage is never 
// destroyed so Play To will always have a valid source to stream.
Image initialImage = null;

private async void SourceRequested(Windows.Media.PlayTo.PlayToManager sender, 
                             Windows.Media.PlayTo.PlayToSourceRequestedEventArgs e)
{
    var deferral = e.SourceRequest.GetDeferral();

    await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
    () =>
    {
        initialImage = new Image();

        // Use the statechanged event of the image passed to Play To to determine when
        // the image is finally connected to the Play To Receiver.
        initialImage.PlayToSource.Connection.StateChanged += InitialImageConnectionStateChanged;

        // Provide Play To with the first image to stream.
        e.SourceRequest.SetSource(initialImage.PlayToSource);

        deferral.Complete();
    });
}

private async void InitialImageConnectionStateChanged(Windows.Media.PlayTo.PlayToConnection sender,
                                                      Windows.Media.PlayTo.PlayToConnectionStateChangedEventArgs e)
{
        if (e.CurrentState == Windows.Media.PlayTo.PlayToConnectionState.Connected) {

            await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, 
                async () =>
                {
                    // Clear any existing timeout.
                    if (timer != null) { timer.Stop(); }

                    // Clear the slide show panel.
                    SlideShowPanel.Children.Clear();

                    // Set the slide show objects and values to show that we are streaming.
                    streaming = true;
                    DisconnectButton.Visibility = Visibility.Visible;
                    InstructionsBlock.Visibility = Visibility.Collapsed;

                    // Queue and display the next image.
                    var image = await QueueImage(currentImage, true);
                    initialImage.PlayToSource.Next = image.PlayToSource;
                    initialImage.PlayToSource.PlayNext();
                });
        };
}

// Update the once the user has selected a device to stream to.

private async void SourceSelected(Windows.Media.PlayTo.PlayToManager sender, 
                            Windows.Media.PlayTo.PlayToSourceSelectedEventArgs e)
{
    await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
        () =>
        {
            DisconnectButton.Click += DisconnectButtonClick;
            MessageBlock.Text = "Streaming to " + e.FriendlyName + "...";
            DeviceBlock.Text = e.FriendlyName + ".\nClick here to disconnect.";
            var imageBitmap = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
            imageBitmap.SetSource(e.Icon);
            IconImage.Source = imageBitmap;
        });
}

private void DisconnectButtonClick(object sender, RoutedEventArgs e)
{
    Windows.Media.PlayTo.PlayToManager.ShowPlayToUI();
}


6. Erstellen eines "Wiedergeben auf"-Ziels (optional)

Zum Ausführen der Anwendung ist ein Zielgerät erforderlich, auf das mit "Wiedergeben auf" Medien gestreamt werden können. Falls Sie keinen zertifizierten Empfänger für "Wiedergeben auf" haben, nutzen Sie Windows Media Player als Zielgerät. Ihr Computer muss mit einem privaten Netzwerk verbunden sein, damit Sie Windows Media Player als Zielgerät verwenden können. Windows Media Player muss auf einem anderen Computer ausgeführt werden als Ihre "Wiedergeben auf"-Quell-App.

  1. Microsoft Windows Media Player
  2. Erweitern Sie das Menü Streamen, und aktivieren Sie die Option Remotesteuerung des Players zulassen.... Lassen Sie Windows Media Player geöffnet. Der Player muss ausgeführt werden, damit er als Ziel für "Wiedergeben auf" verfügbar ist.
  3. Öffnen Sie in der Systemsteuerung Geräte und Drucker. Klicken Sie auf Geräte und Drucker hinzufügen. Suchen Sie im Assistenten zum Hinzufügen von Geräten und Druckern im Fenster Gerät oder Drucker zum Hinzufügen zu diesem PC auswählen den Digital Media-Renderer für Ihren PC. Dies ist Windows Media Player für Ihren PC. Wählen Sie ihn aus, und klicken Sie auf Weiter. Beim Abschließen des Assistenten wird die Instanz von Windows Media Player in der Liste der Multimediageräte angezeigt.

7. Ausführen der App

  • Drücken Sie in Visual Studio F5 (Debuggen), um die App auszuführen. Sie können eine beliebige Medienschaltfläche auswählen, um das erste Medienelement in den verschiedenen Medienbibliotheken wiederzugeben oder anzuzeigen. Öffnen Sie während der Medienwiedergabe den Charm "Geräte", und wählen Sie das Ziel für "Wiedergeben auf" aus, um das Medium auf das Zielgerät zu streamen.

Zusammenfassung

In dieser Schnellstartanleitung haben Sie einer App, die Bilder als Bildschirmpräsentation auf einem Zielgerät anzeigt, die Funktion "Wiedergeben auf" hinzugefügt. Mit der Funktion "Wiedergeben auf" können Benutzer Inhalt aus der App auf einen Empfänger für "Wiedergeben auf" im Netzwerk streamen.

Verwandte Themen

Streamen von Medien auf Geräte mit "Wiedergeben auf"
Beispiele
Beispiel für "Wiedergeben auf"
Beispiel für "PlayToReceiver"
Beispiel für Medienserver

 

 

Anzeigen:
© 2016 Microsoft